In this post I am going to show a few steps to deploy and run PostgreSQL database in a K8S cluster on OKE.
The deployment is going to be based on postgres:11.1 Docker image which requires a few environment variables to be configured: POSTGRES_DB (database name), POSTGRES_USER and POSTGRES_PASSWORD. I am going to store values of these variables in K8S ConfigMap and Secret:
These configuration K8S resources are referenced by the StatefulSet which actually takes care of the lifespan of a pod with postgres-db container:
StatefulSet K8S resource has been specially designed for stateful applications like database that save their data to a persistent storage. In order to define a persistent storage for our database we use another K8s resource Persistent Volume and here in the manifest file we are defining a claim to create a 3Gi Persistent Volume with name db. The volume is called persistent because its lifespan is not maintained by a container and not even by a pod, it’s maintained by a K8s cluster. So it can outlive any containers and pods and save the data. Meaning that if we kill or recreate a container or a pod or even the entire StatefulSet, the data will be still there. We are referring to this persistence volume in the container definition mounting a volume on path /var/lib/postgresql/data. This is where PostgreSQL container stores its data.
In order to access the database we are going to create a service:
The deployment is going to be based on postgres:11.1 Docker image which requires a few environment variables to be configured: POSTGRES_DB (database name), POSTGRES_USER and POSTGRES_PASSWORD. I am going to store values of these variables in K8S ConfigMap and Secret:
apiVersion: v1 kind: ConfigMap metadata: name: postgre-db-config data: db-name: flexdeploy
apiVersion: v1 kind: Secret metadata: name: postgre-db-secret stringData: username: creator password: c67
These configuration K8S resources are referenced by the StatefulSet which actually takes care of the lifespan of a pod with postgres-db container:
apiVersion: apps/v1beta2 kind: StatefulSet metadata: name: postgre-db labels: run: postgre-db spec: selector: matchLabels: run: postgre-db serviceName: "postgre-db-svc" replicas: 1 template: metadata: labels: run: postgre-db spec: containers: - image: postgres:11.1 volumeMounts: - mountPath: /var/lib/postgresql/data name: db env: - name: POSTGRES_DB valueFrom: configMapKeyRef: name: postgre-db-config key: db-name - name: POSTGRES_USER valueFrom: secretKeyRef: name: postgre-db-secret key: username - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: postgre-db-secret key: password - name: PGDATA value: /var/lib/postgresql/data/pgdata name: postgre-db ports: - containerPort: 5432 volumeClaimTemplates: - metadata: name: db spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 3Gi
StatefulSet K8S resource has been specially designed for stateful applications like database that save their data to a persistent storage. In order to define a persistent storage for our database we use another K8s resource Persistent Volume and here in the manifest file we are defining a claim to create a 3Gi Persistent Volume with name db. The volume is called persistent because its lifespan is not maintained by a container and not even by a pod, it’s maintained by a K8s cluster. So it can outlive any containers and pods and save the data. Meaning that if we kill or recreate a container or a pod or even the entire StatefulSet, the data will be still there. We are referring to this persistence volume in the container definition mounting a volume on path /var/lib/postgresql/data. This is where PostgreSQL container stores its data.
In order to access the database we are going to create a service:
apiVersion: v1 kind: Service metadata: name: postgre-db-svc spec: selector: run: postgre-db ports: - port: 5432 targetPort: 5432 type: LoadBalancer
This is a LoadBalancer service which is accessible from outside of the K8S cluster:
$ kubectl get svc postgre-db-svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE postgre-db-svc LoadBalancer 10.96.177.34 129.146.211.77 5432:32498/TCP 39m
kubectl apply -f postgre-db-config.yaml kubectl apply -f postgre-db-secret.yaml kubectl apply -f postgre-db-pv.yaml kubectl apply -f postgre-db-service.yamlHaving done that, we can connect to the database from our favorite IDE on our laptop
The manifest files for this post are available on GitHub.
That's it!