A database container can be replaced, but its data needs a storage volume. A StatefulSet manages Pods for this kind of workload. Unlike a Deployment of stateless Pods, it gives each replica a predictable, ordered name and its own volume claim. section 8.1.3 section 8.4.2
As replicas are added or removed, a StatefulSet manages:
- Storage: a volume claim template requests a separate volume for each new Pod. section 8.4.2
- Identity and order: Pods receive predictable names, are created in order, and are deleted in reverse order. section 8.4.2
- Replica count: if a Pod is missing or failing, a replacement is provisioned to meet the declared count. section 8.6
A Deployment can mount a PersistentVolumeClaim, but a single shared claim is not the same as giving each replica its own storage. A StatefulSet's volumeClaimTemplates field handles the per-replica request. Running several database Pods this way does not, by itself, create a database cluster. section 8.4.1 section 8.4.2
Listing 8.18 StatefulSet for Postgres, part 2
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
...
spec:
...
volumeClaimTemplates:
- metadata:
name: db-vol
spec:
storageClassName: linode-block-storage-retain
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 20Gi
The PostgreSQL manifest requests a 20Gi volume for each replica through volumeClaimTemplates. The claim uses ReadWriteOnce access and the linode-block-storage-retain storage class. section 8.4.2
Putting the PostgreSQL Pod together
The Pod mounts its claimed volume at /var/lib/postgresql and reads database settings from a Secret. An init container removes the new volume's lost+found directory so PostgreSQL can use it. A ClusterIP Service provides internal access on port 5432. section 8.4.2
Listing 8.20 StatefulSet for Postgres, part 4
...
spec:
...
template:
metadata:
containers:
- name: postgres-container
image: postgres:12.16
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5432
env:
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: postgres-db-secret
key: DB_NAME
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: postgres-db-secret
key: DB_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-db-secret
key: DB_PASSWORD
volumeMounts:
- name: db-vol
mountPath: /var/lib/postgresql
volumeClaimTemplates:
- metadata:
name: db-vol
spec:
...
The container configuration shows how the PostgreSQL image receives Secret-backed environment variables and mounts the volume named db-vol. section 8.4.2



