k8s-postgresql-persistent-volume

Create Secret

$ kubectl create secret generic postgres-secret \
--from-literal=POSTGRES_USER=postgresadmin \
--from-literal=POSTGRES_PASSWORD=admin123 \
--dry-run -o yaml > secrets.yaml

Create the secret:

$ kubectl apply -f secrets.yaml
secret/postgres-secret created

Describe the secret:

$ kubectl describe secret postgres-secret
Name:         postgres-secret
Namespace:    default
Labels:       <none>
Annotations:
Type:         Opaque

Data
====
POSTGRES_PASSWORD:  8 bytes
POSTGRES_USER:      13 bytes

Create Persistent Volume

As you all know that Docker containers are ephemeral in nature. All the data which is generated by or in the container will be lost after termination of the container instance.

To save the data, we will be using Persistent volumes and persistent volume claim resource within Kubernetes to store the data on persistent storages.

Here, we are using local directory/path as Persistent storage resource (/opt/postgres-data)

File: postgres-storage.yaml

kind: PersistentVolume
apiVersion: v1
metadata:
  name: postgres-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  hostPath:
    path: "/opt/postgres-data"
$ k apply -f postgres-storage.yaml

Create Persistent Volume Claim

File: postgres-pvc.yaml

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: postgres-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
$ k apply -f postgres-pvc.yaml

PostgreSQL Deployment

PostgreSQL manifest for deployment of PostgreSQL container uses PostgreSQL 10.4 image. It is using PostgreSQL configuration like username, password, database name from the configmap that we created earlier. It also mounts the volume created from the persistent volumes and claims to make PostgreSQL container’s data persists.

$ k apply -f postgres-deployment.yaml

PostgreSQL Service

To access the deployment or container, we need to expose PostgreSQL service. Kubernetes provides different type of services like ClusterIP, NodePort and LoadBalancer.

With ClusterIP we can access PostgreSQL service within Kubernetes. NodePort gives the ability to expose service endpoint on the Kubernetes nodes. For accessing PostgreSQL externally, we need to use a Load Balancer service type which exposes the service externally.

$ k expose deployment postgres \
--type=NodePort \
--target-port=5432 \
--dry-run -o yaml > postgres-service.yaml

Install psql CLI

$ sudo apt-get install -y postgresql-client

Connect to PostgreSQL

For connecting PostgreSQL, we need to get the Node port from the service deployment.

$ k get svc postgres
NAME       TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
postgres   NodePort   10.100.34.227   <none>        5432:30223/TCP   6m24s

We need to use port 30223 to connect to PostgreSQL from machine/node present in kubernetes cluster with credentials given in the configmap earlier.

$ psql -h localhost -U postgresadmin --password -p 30223

Delete resources

Individually:

$ kubectl delete service postgres 
$ kubectl delete deployment postgres
$ kubectl delete secret postgres-secret
$ kubectl delete pvc postgres-pv-claim
$ kubectl delete pv postgres-pv-volume