DEV Community

丁久
丁久

Posted on • Originally published at dingjiu1989-hue.github.io

Databases in Containers: StatefulSets, Persistent Volumes, and Backup

This article was originally published on AI Study Room. For the full version with working code examples and related articles, visit the original post.

Databases in Containers: StatefulSets, Persistent Volumes, and Backup

Databases in Containers: StatefulSets, Persistent Volumes, and Backup

Databases in Containers: StatefulSets, Persistent Volumes, and Backup

Databases in Containers: StatefulSets, Persistent Volumes, and Backup

Databases in Containers: StatefulSets, Persistent Volumes, and Backup

Databases in Containers: StatefulSets, Persistent Volumes, and Backup

Databases in Containers: StatefulSets, Persistent Volumes, and Backup

Databases in Containers: StatefulSets, Persistent Volumes, and Backup

Databases in Containers: StatefulSets, Persistent Volumes, and Backup

Databases in Containers: StatefulSets, Persistent Volumes, and Backup

Databases in Containers: StatefulSets, Persistent Volumes, and Backup

Databases in Containers: StatefulSets, Persistent Volumes, and Backup

Databases in Containers: StatefulSets, Persistent Volumes, and Backup

Databases in Containers: StatefulSets, Persistent Volumes, and Backup

Running databases in containers was once considered an anti-pattern, but modern orchestration and storage primitives have made it viable for many production workloads. This article covers Kubernetes patterns for stateful databases, storage management, and operational considerations.

StatefulSets vs Deployments

Kubernetes Deployments are designed for stateless applications. StatefulSets are the correct primitive for databases:

apiVersion: apps/v1

kind: StatefulSet

metadata:

name: postgres

spec:

serviceName: postgres

replicas: 3

selector:

matchLabels:

app: postgres

template:

metadata:

labels:

app: postgres

spec:

containers:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- name: postgres

image: postgres:16

ports:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- containerPort: 5432

env:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- name: POSTGRES_PASSWORD

valueFrom:

secretKeyRef:

name: pg-secret

key: password

volumeMounts:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- name: data

mountPath: /var/lib/postgresql/data

volumeClaimTemplates:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- metadata:

name: data

spec:

accessModes: [ "ReadWriteOnce" ]

storageClassName: "fast-ssd"

resources:

requests:

storage: 100Gi

StatefulSets provide:

  • Stable, unique network identities (pod-name-0, pod-name-1).

  • Ordered, graceful deployment and scaling.

  • Stable storage with PersistentVolumeClaim templates.

PersistentVolumes and Storage Classes

Database storage requires careful configuration of PersistentVolumes:

apiVersion: storage.k8s.io/v1

kind: StorageClass

metadata:

name: fast-ssd

provisioner: ebs.csi.aws.com

parameters:

type: gp3

iops: "3000"

throughput: "125"

reclaimPolicy: Retain

Access Modes

| Mode | Description | Database Use Case | |------|-------------|-------------------| | ReadWriteOnce | Single node read-write | Primary database | | ReadOnlyMany | Many nodes read-only | Read replicas | | ReadWriteMany | Many nodes read-write | Shared storage (avoid for PostgreSQL) |

CloudNativePG Operator

The CloudNativePG operator is the most mature Kubernetes operator for PostgreSQL:

apiVersion: postgresql.cnpg.io/v1

kind: Cluster

metadata:

name: myapp-db

spec:

instances: 3

imageName: ghcr.io/cloudnative-pg/postgresql:16

storage:

size: 100Gi

storageClass: fast-ssd

backup:

barmanObjectStore:

destinationPath: s3://myapp-backups/

s3Credentials:

accessKeyId:

name: aws-creds

key: access-key

secretAccessKey:

name: aws-creds

key: secret-key

wal:

compression: gzip

retentionPolicy: "30d"

monitoring:

enablePodMonitor: true

resources:

requests:

memory: "4Gi"

cpu: "2"

limits:

memory: "8Gi"

cpu: "4"

Automated Failover

Simulate pod failure to test failover

kubectl delete pod myapp-db-0

Operator automatically:

1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\


Read the full article on AI Study Room for complete code examples, comparison tables, and related resources.

Found this useful? Check out more developer guides and tool comparisons on AI Study Room.

Top comments (0)