Step 1 : Create K8s Cluster

eksctl create cluster --name helm-cluster --region ap-south-1 --nodes 3 --node-type t2.medium

Step 2 : Create resources required to start postgres internally

deployment.yml

apiVersion: v1 # Namespace
kind: Namespace
metadata:
  name: postgres-manual

---

apiVersion: v1  # ConfigMap
kind: ConfigMap 
metadata:
  name: postgres-config 
  namespace: postgres-manual
data:
  postgres_db: postgres 
  postgres_user: postgres

--- 

apiVersion: v1 # Secret
kind: Secret
metadata:
  name: postgres-secret 
  namespace: postgres-manual
data:
  postgres_password: cGFzc3dvcmQ=

---

apiVersion: v1 # PVC ( Should be available before pod starts )
kind: PersistentVolumeClaim 
metadata:
  name: postgres-pvc 
  namespace: postgres-manual
spec:
  accessModes:
    - ReadWriteOnce 
  resources:
    requests:
      storage: 10Gi
  storageClassName: gp2

---

apiVersion: apps/v1  # Deployment 
kind: Deployment 
metadata:
  name: postgres-deployment 
  namespace: postgres-manual
spec:
  replicas: 1
  selector:
    matchLabels: 
      app: postgres
  template:
    metadata:
      labels:
        app: postgres 
    spec:
      containers: 
        - name: postgres
          image: postgres:14
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_DB 
              valueFrom: 
                configMapKeyRef:
                  name: postgres-config
                  key: postgres_db 
            - name: POSTGRES_USER 
              valueFrom:
                configMapKeyRef:
                  name: postgres-config 
                  key: postgres_user 
            - name: POSTGRES_PASSWORD 
              valueFrom:
                secretKeyRef:
                  name: postgres-secret 
                  key: postgres_password
            - name: PGDATA # This tells postgres not to use root of volume, instead initialise and store all db files in subdir
              value: /var/lib/postgresql/data
          volumeMounts:
            - name: postgres-volume 
              mountPath: /var/lib/postgresql/data # since original postgres db directory is not empty u should create a subdirectory to mount files
              subPath: pgdata
      volumes:
        - name: postgres-volume 
          persistentVolumeClaim:
            claimName: postgres-pvc 

---

apiVersion: v1 # Service
kind: Service 
metadata:
  name: postgres-service 
  namespace: postgres-manual
spec:
  selector:
    app: postgres 
  ports:
    - protocol: TCP 
      port: 5432
      targetPort: 5432
  type: ClusterIP

kubectl apply -f deployment.yml

Step 3 : ssh into postgres pod and check if it got mounted correctly

kubectl get pods -n postgres-manual

image.png

To debug errors , u can check pod logs

kubectl describe pod <POD_NAME> -n postgres-manual

kubectl logs -f <POD_NAME> -n postgres_manual
kubectl exec -it <POD_NAME> -n postgres_manual -- sh

su -- postgres # ( switch from root user to postgres )
psql -U postgres  # ( Enter postgres shell )

CREATE DATABASE mydb # ( Create database in postgres ) 

CREATE TABLE users ( id SERIAL PRIMARY KEY, name TEXT, email TEXT );

INSERT INTO users (name, email) VALUES ('Alice', '[email protected]');

select * from users;

 \dt

image.png

image.png

Step 4: Delete old pod & restart a new pod to see if data persists

# Step 1 : Show current pod running
kubectl get pods -n postgres-manual

# Step 2 : Delete currently running pod
kubectl delete pod postgres-deployment-869d45f5b4-6tzpg -n postgres-manual

# Step 3 : new pod gets automatically started by deployment
kubectl get pods -n postgres-manual

# Step 4 : ssh into newly created pod 
kubectl exec -it postgres-deployment-869d45f5b4-8mpkv -n postgres-manual -- sh
 
# Switch from root user to postgres user
su -- postgres
 
# Start postgres shell 
psql -U postgres
 
# Show all db 
\l
 
# Switch to mydb  
\c mydb

#Shows all relations ( tables ) inside mydb database   
\dt

# Shows all columns in this table 
SELECT * FROM users;

You can see that columns inserted in old pod, automatically gets added to new pod that means data persisted via PVC

image.png