Skip to main content
RunBook Academy

PostgreSQLXVIII · Platforms, Corruption and Production ArchitecturePlatforms

PostgreSQL on Kubernetes: operators, StatefulSets, storage, fencing

Advanced⏱ ~30 min

What you'll learn

  • Map Kubernetes primitives onto the HA responsibilities from Part XV
  • Identify where Kubernetes conflicts with database requirements
  • Evaluate an operator against the six responsibilities
  • Decide whether Kubernetes is the right place for this database

Prerequisites

Verified against PostgreSQL 18.x · PostgreSQL (comparison targets) 17.11, 16.15 · PostgreSQL (support calendar) 18, 17, 16, 15, 14 supported · pgBackRest 2.59.1 · PgBouncer 1.25.2 · Patroni 4.1.5 · Ubuntu (host baseline) 26.04 LTS · 2026-08-27

Not yet marked complete on this device.

What Kubernetes supplies

StatefulSets give stable network identity and stable per-pod storage, which is the minimum a database needs and is why Deployment is wrong for one.

PersistentVolumeClaims bind storage to a pod identity rather than to a node.

Services give a stable name in front of changing pods, which is lesson XV-06’s routing problem with an implementation.

Scheduling places pods on nodes and moves them when nodes fail.

Where it conflicts

Kubernetes was built for stateless workloads, and its instincts are wrong for a database in specific ways.

It restarts things. A pod that exits is restarted. Lesson XVII-02 measured a cluster whose pg_wal filled: it PANICs, recovery fails for the same reason, and it shuts down. Kubernetes restarts it into the same condition, in a loop, and the log line that explains it scrolls past between attempts.

It reschedules things. Moving a database pod to another node means detaching and attaching storage, which takes time and can fail — and if it partially succeeds you have the fencing problem from lesson XV-03.

It treats pods as fungible. They are not. One of them is the primary, and which one matters more than anything else about the system.

Liveness probes assume a shallow question. pg_isready returns success for a cluster in recovery, a cluster refusing writes, and a cluster serving from the corrupted page in lesson XVIII-06. A failing liveness probe restarts the pod, which for a database is rarely the right response and is sometimes the worst one.

What an operator must do

Exactly lesson XV-04’s six responsibilities, plus the Kubernetes-specific ones:

ResponsibilityOn Kubernetes
DetectDeep health checks, not pg_isready
DecideConsensus — often the Kubernetes API itself
FenceEnsure a demoted pod cannot come back as primary
Promotepg_promote()
RerouteUpdate the Service’s endpoints
Rejoinpg_rewind or rebuild
StorageCorrect PVC handling across rescheduling
BackupsPart XIII, which Kubernetes supplies nothing for

Evaluating an operator means asking the lesson XV-04 questions, plus:

  • What happens when the Kubernetes API is unavailable? If it is the consensus store, the operator cannot decide — and the right behaviour is to keep serving and stop deciding.
  • What happens when a node is partitioned rather than dead? The pod may still be running and serving.
  • How is the primary’s identity expressed, and does the Service follow a promotion atomically?
  • What does it do about the kubelet’s restart policy during a deliberate demotion?

Storage

The database’s durability rests entirely on the storage layer, and this is where lesson VI-01’s measurement matters most: an 854 µs fdatasync predicted a ~1,170 tps commit ceiling, and pgbench measured 842.

Questions worth answering before running a production database on a storage class:

  • Does it honour fsync? If not, nothing above it is durable, and lesson VI-01’s whole chain is broken.
  • What is its fsync latency? That is your commit ceiling.
  • Is it node-local or network-attached? Local is faster and does not move with the pod.
  • What happens during a node failure? Detach and reattach takes time, and that time is part of your RTO.
  • Can it be resized? Lesson XVII-02’s remedy for a full filesystem is “extend it”.

What to take from this

  • StatefulSets, PVCs and Services supply identity, storage binding and routing. That is the useful part.
  • Kubernetes restarts, reschedules and treats pods as fungible — all wrong for a database.
  • pg_isready is not a health check. A failing liveness probe restarts the pod, which is rarely right.
  • The kubelet is a service manager, and a restart during a deliberate demotion produces two primaries.
  • An operator must supply all six Part XV responsibilities plus storage handling; backups are still yours.
  • Storage decides durability and your commit ceiling. Ask whether it honours fsync.
  • Kubernetes adds a distributed system between you and the database. Worth it for many clusters, poor for one important one.

Cross-course references

  • Kubernetes for Production Sysadmins — Part XVII (StatefulSets), Part L (PersistentVolumes and claims) and Part LIV (Stateful workloads) cover the primitives an operator builds on; Part LIII (Storage failure modes) covers what happens when the volume does not detach; and Part XXXIV (PodDisruptionBudgets) covers keeping a drain from taking the primary.
  • Ceph & Distributed Storage — Part LXXXV (Kubernetes integration) and Part LXXXVIII (Kubernetes storage failure scenarios) cover the storage layer underneath.

Quiz

Knowledge check · 6 questions

  1. Q1. An operator deliberately demotes a PostgreSQL pod as part of fencing. The container exits. What does Kubernetes do, and why does it matter?

  2. Q2. Why is pg_isready inadequate as a Kubernetes liveness probe for PostgreSQL?

  3. Q3. During a network partition, the Kubernetes control plane marks a node NotReady and evicts its pods. What is the state of the PostgreSQL pod on that node?

  4. Q4. Which questions should be asked of a storage class before running a production database on it? Select all that apply.

  5. Q5. Running PostgreSQL on Kubernetes removes the split-brain problem, because the control plane guarantees only one pod is the primary.

  6. Q6. Trace how a network partition on Kubernetes leads to two primaries, and name the defence.

Passing score: 75%. Answers are checked in this browser.