A Kubernetes controller that manages databases within a cluster.
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.
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.
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.yamlTo install the controller, run the following command:
kubectl apply -f https://raw.githubusercontent.com/linka-cloud/k8s-db-manager/main/deploy/manifests.yamlYou can check that the controller is running with the following command:
kubectl get pods -n k8s-db-manager-systemThe 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 testYou 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
EOFWait for the database engine to be ready:
kubectl get pod -l app=postgres -n test --watchNAME 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
EOFVerify that the DatabaseProvider is ready:
kubectl get databaseprovidersNAME TYPE STATUS AGE
postgres postgres Ready 24s
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
EOFVerify that the Database is ready:
kubectl get databases -n test --watchNAME 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 testName: 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_CONNpostgres://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_CONNtest-database-sample-postgres=>
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-namespacesThen, you need to delete all DatabaseProvider resources:
kubectl delete databaseproviders --all --all-namespacesFinally, you can delete the remaining resources:
kubectl delete -f https://raw.githubusercontent.com/linka-cloud/k8s-db-manager/main/deploy/manifests.yamlCopyright 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.