/simple-database-provisioner

The simple database provisioner allows to create and remove databases and user credentials (secretes) via kubernetes ressources on an existing DBMS server.

Primary LanguageGoApache License 2.0Apache-2.0

Kubernetes Simple Database Provisioner

License: Apache License 2.0
Simple Database Provisioner

The simple database provisioner allows to create and remove databases and user credentials (secretes) via kubernetes ressources on an existing DBMS server.

It was created as a simpler and more resilient alternative to setting up databases with OSBA.

Status

CURRENT STATUS: ALPHA

Not intended for production use yet. Tests, refactoring and updating the documentation are missing.

Concept

  • DBMS servers have to be created by some other tool (e.g. manually, or terraform)

  • DBMS servers are identified in the config via a unique name and a secret with the connection information

  • DBMS management is (currently) static and requires a pod restart

  • Database Instance and Binding management is dynamic via two Custom Resource Definitions

Installation

There is a helm chart provided so you can easily install it in your cluster.

  1. Set up a postgres database server manually somehow and have the credentials ready. The user must be able to create databases and roles.

  2. Create a secret with these credentials. (all values are base64 encoded, as usual). See examples/dev-postgres-secret.yaml for an example kubernetes resource definition. The metadata → name will be the identifier with which you can later assign some databases onto that dbms server.

  3. Enter the directory helm/simple-database-provisioner and execute

    helm -n sdp sync --name "simple-database-provisioner" .

Now watch the logs and create/delete some resources (e.g. from the examples folder, to verify functionality and to get used to it.

Configuration

Application Config File

config.yaml

dbmsServers:
  dev-postgres:
    secret: dev-postgres-secret

persistence:
  type: file
  location: ./sdp.db.yaml

Database Format (DRAFT)

The database format currently is only a rough draft and might change during development according to the needs (e.g. list instead of map, etc.).

namespaces:
  master:
    instances:
      mynamespace-myservice-database:
        dbmsServer: dev-postgres
        databaseName: mynamespace-myservice
    bindings:
      mynamespace-myservice-binding:
        instanceName: mynamespace-myservice-database
        secretName: mynamespace-myservice-database-secret

DBMS Secret

apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: dbms-dev-postgres-secret
data:
  database: cG9zdGdyZXM=
  host: cG9zdGdyZXMtcG9zdGdyZXNxbA==
  password: WkthNWE4Y0w0Yg==
  port: NTQzMg==
  ssl: ZmFsc2U=
  user: cG9zdGdyZXM=

Custom Resource Definitions

CDR: SimpleDatabaseInstance

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: simpledatabaseinstances.simpledatabaseprovisioner.k8s.ecodia.de
spec:
  group: simpledatabaseprovisioner.k8s.ecodia.de
  version: v1alpha1
  scope: Namespaced
  conditions:
  stored_versions: []
  names:
    plural: simpledatabaseinstances
    singular: simpledatabaseinstance
    kind: SimpleDatabaseInstance
    shortNames:
     - sdi

Example

apiVersion: simpledatabaseprovisioner.k8s.ecodia.de/v1alpha1
kind: SimpleDatabaseInstance
metadata:
  name: sample-application-database
spec:
  dbmsServer: dbms-dev-postgres
  databaseName: sample-application-database

CDR: SimpleDatabaseBinding

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: simpledatabasebindings.simpledatabaseprovisioner.k8s.ecodia.de
spec:
  group: simpledatabaseprovisioner.k8s.ecodia.de
  version: v1alpha1
  scope: Namespaced
  names:
    plural: simpledatabasebindings
    singular: simpledatabasebinding
    kind: SimpleDatabaseBinding
    shortNames:
     - sdb

Example

apiVersion: simpledatabaseprovisioner.k8s.ecodia.de/v1alpha1
kind: SimpleDatabaseBinding
metadata:
  name: sample-application-binding
spec:
  instanceName: sample-application-database
  secretName: sample-application-database-secret

Development

This controller is based on the kubernetes samplecontroller:

Hands on

Let’s jump right into some hands on commands

Run the controller

  • The controller automatically detects if it is run inside a cluster or can connect to a cluster via the kubernetes api

  • start minikube

  • run controller.py , then load the example resources and watch how events are read

    kubectl apply -f examples/sdi-example.yaml
    kubectl apply -f examples/sdb-example.yaml

Delete databases and bindings

For testing purposes it might be necessary to remove the instances and bindings:

kubectl delete sdi/sample-application-database
kubectl delete sdb/sample-application-binding

Delete Custom Resource Definitions

For testing purposes it might be necessary to remove the custom resource definitions:

kubectl delete crd/simpledatabasebindings.simpledatabaseprovisioner.k8s.ecodia.de
kubectl delete crd/simpledatabaseinstances.simpledatabaseprovisioner.k8s.ecodia.de

Run tests

To run the tests you need minikube and a postgres database with the correct user credentials:

minikube start
docker run --rm --name sdp-postgres-testdb -p 5432:5432 -e POSTGRES_PASSWORD=postgres -e POSTGRES_USER=postgres postgres

Then start the tests with: go test simple-database-provisioner…​

Generate custom resource types

The simple-database-provisioner controller is based on https://github.com/kubernetes/sample-controller .

It makes use of the generators in k8s.io/code-generator to generate a typed client, informers, listers and deep-copy functions. You can do this yourself using the ./hack/update-codegen.sh script.