PostgreSQL with Persistent Storage¶
This example deploys PostgreSQL from the UBI-based registry.redhat.io/rhel9/postgresql-16 image with a PersistentVolumeClaim (PVC). It validates that the CSI driver and StorageClass work end-to-end: stateful workloads, persistent storage, and data that survives pod restarts.
Note
Distroless hardened images do not include a shell or psql client, so oc rsh into those images fails. This POC uses the UBI image so you can run the interactive checks below.
Prerequisites¶
- Storage configured with a default StorageClass
Deploy PostgreSQL¶
-
Create a namespace:
-
Create the PersistentVolumeClaim:
-
Create the Deployment:
apiVersion: apps/v1 kind: Deployment metadata: name: postgresql namespace: postgresql-demo labels: app: postgresql spec: replicas: 1 selector: matchLabels: app: postgresql strategy: type: Recreate template: metadata: labels: app: postgresql spec: containers: - name: postgresql image: registry.redhat.io/rhel9/postgresql-16 ports: - containerPort: 5432 env: - name: POSTGRESQL_USER value: demo - name: POSTGRESQL_PASSWORD value: demo123 - name: POSTGRESQL_DATABASE value: sampledb resources: requests: memory: "256Mi" cpu: "250m" limits: memory: "512Mi" cpu: "500m" volumeMounts: - name: postgresql-data mountPath: /var/lib/pgsql/data readinessProbe: tcpSocket: port: 5432 initialDelaySeconds: 5 periodSeconds: 10 livenessProbe: tcpSocket: port: 5432 initialDelaySeconds: 30 periodSeconds: 10 volumes: - name: postgresql-data persistentVolumeClaim: claimName: postgresql-data -
Create the Service:
-
Verify the PVC is bound and the pod is running:
Write Test Data¶
-
Connect to PostgreSQL and insert some data:
Inside the pod:
Test Persistence¶
-
Delete the pod (the Deployment will recreate it):
-
Wait for the new pod to start:
-
Verify the data survived the pod restart:
The rows inserted earlier should still be there, proving the PVC retained the data across pod recreation.
What to Show in a Demo¶
- PVC binding —
oc get pvcshows the claim bound to a PV provisioned by the CSI driver - Data persistence — data survives pod deletion and recreation
- Storage class in action — the default StorageClass dynamically provisions the volume
- Pod scheduling — the pod is scheduled to a node where the volume is accessible
- Stateful workloads — OpenShift handles the same database workloads as traditional VMs