Ten Kubernetes Design Patterns: Probes, Sidecars, Init Containers and Operators
Foundational, structural, behavioural and higher-level Kubernetes patterns, each with the problem it solves and a manifest snippet you can adapt.
On this page
Kubernetes gives you a lot of verbs and very little advice. The patterns below are the advice: ten recurring shapes that the platform was built to support, and what each protects you from.
Foundational: let the platform manage you
- 1. Health probes
Expose endpoints the platform can ask. Liveness decides when to restart a stuck container. Readiness decides whether to send traffic. Startup protects slow-starting apps from being killed too soon.
- 2. Predictable demands
Declare CPU and memory requests and limits, and dependencies like config and volumes. The scheduler cannot place what it cannot size.
- 3. Automated placement
Describe where Pods may or must run (node selectors, affinity, taints and tolerations, topology spread) and let the scheduler do the rest. Spread replicas across zones so one failure does not take them all.
containers:
- name: api
image: example/api:1.4.2
resources:
requests: { cpu: "250m", memory: "256Mi" }
limits: { memory: "512Mi" }
readinessProbe:
httpGet: { path: /ready, port: 8080 }
periodSeconds: 5
livenessProbe:
httpGet: { path: /healthz, port: 8080 }
periodSeconds: 10
failureThreshold: 3
Pointing liveness at a check that depends on the database. When the database blips, every Pod fails liveness, Kubernetes restarts them all at once, and a small problem becomes a full outage. Keep liveness about the process itself, put dependency checks in readiness.
Structural: organising containers in a Pod
The rule of thumb: if the helper must share localhost or a volume with the app and share its lifecycle, it is a sidecar. If it is a separate service with its own scaling, it is a separate Deployment.
Behavioural: matching the workload
Higher-level: encoding operations
- 9. Controller
Kubernetes is a set of control loops. You declare the desired state, a controller watches actual state and acts until they match. This reconcile loop is why a crashed Pod simply comes back. Understanding it explains most “why did it do that” moments.
- 10. Operator
A custom controller plus a custom resource that captures a human operator’s knowledge: how to deploy a database cluster, take a backup, promote a replica, upgrade without data loss. You declare “a three-node Postgres, version 16” and the operator makes and keeps it so.
Operators are powerful and costly to write. Adopt an existing, well-maintained one for stateful software before building your own, and do not build one for a stateless service that a Deployment already handles.
Which pattern for which problem
| Problem | Pattern |
|---|---|
| Traffic hits a container that is still starting | Readiness probe |
| A hung process never recovers | Liveness probe |
| One Pod starves its neighbours | Requests and limits |
| All replicas land on one node | Spread constraints, anti-affinity |
| App must wait for a database before starting | Init container |
| Need log shipping or a proxy without changing the app | Sidecar |
| Nightly report | CronJob |
| Database needing stable identity | StatefulSet, possibly an operator |
Do
Give every workload requests, a readiness probe and at least two replicas spread across zones before you reach for anything advanced. Those three cover most production incidents.
Don't
Reach for operators, custom controllers or service meshes before the foundational patterns are in place. Advanced tooling on top of missing probes is complexity without resilience.
Takeaway
The ten patterns are really one idea at four levels: tell the platform enough about your workload (probes, demands, placement), organise containers by lifecycle (init, sidecar), match the controller to the workload type (job, stateful, service), and encode repeated operations as controllers. Start at the first level and move up only when a real problem demands it.
Frequently asked questions
What is the sidecar pattern in Kubernetes?
Running a helper container in the same Pod as your application container so they share network and storage. The helper adds capability, such as log shipping, proxying or certificate refresh, without changing the application image. Recent Kubernetes versions support sidecars that start before and outlive the main container.
What is the difference between a liveness and a readiness probe?
A liveness probe tells Kubernetes whether to restart a container that is stuck. A readiness probe tells it whether the container should receive traffic right now. A container can be alive but not ready, for example while warming a cache, and should be taken out of rotation without being killed.
When should I write an operator?
When running an application needs ongoing operational knowledge that you would otherwise do by hand, such as backups, failover, upgrades or scaling for a database. An operator encodes that knowledge in a controller. For stateless apps, plain Deployments are almost always enough.
Why declare resource requests and limits?
Requests tell the scheduler how much CPU and memory a Pod needs so it can place it well. Limits cap what it may use. Without them, one noisy Pod can starve neighbours, and the cluster cannot make good placement or eviction decisions.
/* Comments */
Comments are offline right now — we reconnect automatically, nothing is lost.