Skip to content

linka-cloud/k8s-db-manager

Repository files navigation

k8s-db-manager

A Kubernetes controller that manages databases within a cluster.

Description

The controller exposes two Custom Resources: DatabaseProvider and Database.

The DatabaseProvider is a cluster-wide resource that defines a database engine and its access credentials. The Database is a namespace-scoped resource that defines a database inside a DatabaseProvider engine.

Getting Started

You’ll need a Kubernetes cluster to run against. You can use KIND to get a local cluster for testing, or run against a remote cluster.

Prerequisites

cert-manager is required to run this controller. You can install it with the following command:

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.2/cert-manager.yaml

Installing

To install the controller, run the following command:

kubectl apply -f https://raw.githubusercontent.com/linka-cloud/k8s-db-manager/main/deploy/manifests.yaml

You can check that the controller is running with the following command:

kubectl get pods -n k8s-db-manager-system

Usage

The examples below assumes that you have a Namespace resource called test.

If it does not exist, you can create it with the following command:

kubectl create namespace test

Create a DatabaseProvider

You first need to create a DatabaseProvider resource:

If you don't have an existing database engine, you can deploy one in the cluster:

kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: postgres
  namespace: test
stringData:
  username: k8s-db-manager
  password: Søm3RiD1cUl0uSc0mpL3xP4ssw0rdTh4tYouC4nNev3rRem3mber
---
apiVersion: v1
kind: Service
metadata:
  name: postgres
  namespace: test
spec:
  selector:
    app: postgres
  ports:
  - port: 5432
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
  namespace: test
  labels:
    app: postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      name: postgres
      labels:
        app: postgres
    spec:
      restartPolicy: Always
      containers:
      - name: postgres
        image: postgres
        imagePullPolicy: IfNotPresent
        env:
        - name: POSTGRES_USER
          valueFrom:
            secretKeyRef:
              name: postgres
              key: username
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: postgres
              key: password
        ports:
        - containerPort: 5432
EOF

Wait for the database engine to be ready:

kubectl get pod -l app=postgres -n test --watch
NAME                       READY   STATUS    RESTARTS   AGE
postgres-99dff4b8b-km5kw   1/1     Running   0          5s

You can then create a DatabaseProvider that will use the deployed database engine:

kubectl apply -f - <<EOF
apiVersion: db.linka.cloud/v1alpha1
kind: DatabaseProvider
metadata:
  labels:
    app.kubernetes.io/name: postgres
    app.kubernetes.io/instance: postgres
    app.kubernetes.io/part-of: k8s-db-manager
    app.kubernetes.io/created-by: k8s-db-manager
  name: postgres
spec:
  type: postgres
  host: postgres.test.svc.cluster.local
  username:
    key: username
    name: postgres
    namespace: test
  password:
    key: password
    name: postgres
    namespace: test
EOF

Verify that the DatabaseProvider is ready:

kubectl get databaseproviders
NAME       TYPE       STATUS   AGE
postgres   postgres   Ready    24s

Create a Database

You can now create a Database resource:

kubectl apply -f - <<EOF
apiVersion: db.linka.cloud/v1alpha1
kind: Database
metadata:
  labels:
    app.kubernetes.io/name: test
    app.kubernetes.io/instance: database-sample
    app.kubernetes.io/part-of: k8s-db-manager
    app.kubernetes.io/managed-by: kustomize
    app.kubernetes.io/created-by: k8s-db-manager
  name: database-sample-postgres
spec:
  provider: postgres
  secretName: database-sample-postgres
  secretTemplate:
    connection: "postgres://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}?sslmode=disable"
  reclaimPolicy: Delete
EOF

Verify that the Database is ready:

kubectl get databases -n test --watch
NAME                       DATABASE                        PROVIDER   RECLAIM POLICY   STATUS   SECRET                     AGE
database-sample-postgres   test-database-sample-postgres   postgres   Delete           Ready    database-sample-postgres   5s

The secret database-sample-postgres has been created in the test namespace:

kubectl describe secret database-sample-postgres -n test
Name:         database-sample-postgres
Namespace:    test
Labels:       app.kubernetes.io/component=database
              app.kubernetes.io/instance=database-sample-postgres
              app.kubernetes.io/managed-by=k8s-db-manager
Annotations:  <none>

Type:  Opaque

Data
====
connection:  188 bytes
database:    29 bytes
host:        31 bytes
password:    64 bytes
port:        4 bytes
username:    29 bytes

You can now retrieve the connection string that has been created by using the secretTemplate field:

PSQL_CONN=$(kubectl get secret database-sample-postgres -n test -o jsonpath='{.data.connection}' | base64 -d)
echo $PSQL_CONN
postgres://test-database-sample-postgres:000088f04241e023e4e79fc1c2ea822eb8bf8e703e8d242c52ed72f44cbe2a75@postgres.test.svc.cluster.local:5432/test-database-sample-postgres?sslmode=disable

You can now connect to the database:

kubectl run --rm -it --image postgres psql -- psql $PSQL_CONN
test-database-sample-postgres=> 

Uninstall

First, you need to delete all Database resources:

Warning: This will delete all the created databases with reclaimPolicy set to Delete.

kubectl delete databases --all --all-namespaces

Then, you need to delete all DatabaseProvider resources:

kubectl delete databaseproviders --all --all-namespaces

Finally, you can delete the remaining resources:

kubectl delete -f https://raw.githubusercontent.com/linka-cloud/k8s-db-manager/main/deploy/manifests.yaml

License

Copyright 2023.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published