Production-grade guide to container orchestration patterns covering architecture patterns, implementation strategies, testing approaches, and operational best practices for enterprise engineering teams.
Container Orchestration Patterns
Container orchestration patterns capture the recurring ways platform teams arrange workloads, updates, and self-healing logic on top of a cluster manager. They matter whenever you’re running more than a handful of containers in production and need guarantees about availability, update safety, and resource fairness. This page collects the patterns you’ll actually invoke, the commands you’ll type, and the failure modes that catch teams off guard.
The most common day-to-day pattern is replacing pods one at a time so that the service remains available throughout. In a kubectl-driven workflow the canonical command sequence looks like this:
kubectl set image deployment/app container=registry/example/app:v2 --record
# Watch the rollout progress, failing after a reasonable deadline
kubectl rollout status deployment/app --timeout=300s
If the rollout stalls, the annotated revision lets you reverse course immediately:
kubectl rollout undo deployment/app
Exact error when a health check blocks progress
error: deployment "app" has timed out waiting for rollout to finish:
5 of 5 old replicas are available, 0 new replicas are available:
Ingress failed health check
Sharp edges
initialDelaySeconds: 0 or periodSeconds: 1) will kill pods during startup, causing a rapid oscillation between old and new replicas and ultimately a rollout failure with the error above. Conversely, a readiness probe that never passes will prevent traffic from ever reaching the new version, making it look like the deployment hung.When you need to validate a new version with a subset of traffic before full cutover, the pattern shifts from automatic replacement to deliberate traffic routing. The mechanics are the same across orchestrators: adjust the set of endpoints a Service selects, or use an ingress/controller weight.
Concrete command (adjusting Service selectors)
# Route 10% of traffic to the canary version by mutating the Service’s selector
kubectl patch service app -p '{"spec":{"selector":{"version":"canary","track":"stable"}}}'
In practice, most teams rely on a service mesh (e.g., Istio, Linkerd) or cloud provider ingress (AWS ALG, GCP Ingress) to split traffic via request.weight or percent annotations. The underlying idea is identical: the orchestrator continues to manage pod lifecycles, while an external routing layer directs requests.
Sharp edges
Orchestrators distinguish between “the process died” and “the process is up but not yet serving traffic” through two complementary probe types. The YAML fragment below is representative of what you’ll place inside a pod spec:
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
Use kubectl to inspect the current state of a pod’s probes:
kubectl describe pod <pod-name> | grep -A5 "Probes:"
Exact error when a liveness probe fails repeatedly
Back-off restarting failed container(example-app) 1m12s repeated message "Get "http://10.244.0.5:8080/healthz": dial tcp 10.244.0.5:8080: connect: connection refused"
Sharp edges
initialDelaySeconds, which means the first probe fires before the app has loaded its configuration, resulting in immediate failure.Preventing a single workload from starving others is achieved by expressing CPU and memory requests and limits. The orchestrator uses these values to place pods, decide QoS (Quality of Service) class, and make eviction decisions under pressure.
Representative pod spec fragment
resources:
requests:
cpu: "200m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"
Adjust these values on a running deployment:
kubectl edit deployment/app
# Modify the resources section, then save and exit
Sharp edges
0/3 nodes are available: 3 Insufficient cpu. Teams frequently mistake this for a cluster capacity issue when the real cause is a few pods with high requests and no limits.kubectl get pods output as OOMKilled in the STATUS column, accompanied by Container terminated with exit code 137. This silently kills the process without a graceful shutdown hook, potentially corrupting in-memory state or leaving database connections in an inconsistent state.When a node hardware failure or scheduled maintenance occurs, the orchestrator must drain the node and reschedule its pods elsewhere. The standard toolchain involves cordoning, draining, and relying on the cluster autoscaler or manual intervention.
Concrete commands
# Prevent new pods from scheduling on the node
kubectl cordon node1
# Drain the node, respecting DaemonSets and deleting empty-dir volumes
kubectl drain node1 --ignore-daemonsets --delete-emptydir-data
If the cluster autoscaler is active, it will add a new node when the scheduler cannot find a fit:
# Watch the autoscaler log (cloud-provider-specific)
# Typical flag set at deployment:
# --scale-down-utilization-threshold=0.5
Sharp edges
restartPolicy: Never (e.g., CI job pods) are not rescheduled after a node drain; they are simply lost. Teams often forget this and wonder why a job re-runs but never completes.--ignore-daemonsets by default, but if a DaemonSet pod fails to restart on the new node, the cluster’s observability pipeline may break silently.Getting configuration and secrets into pods without baking them into images is a first-class pattern. The orchestrator provides two primary mechanisms: ConfigMaps for plaintext key-value data and Secrets for base64-encoded sensitive data.
ConfigMap volume mount (representative YAML)
volumeMounts:
- name: app-config
mountPath: /etc/app-config
readOnly: true
volumes:
- name: app-config
configMap:
name: app-config-map
Secret volume mount (representative YAML)
volumeMounts:
- name: db-credentials
mountPath: /etc/db-credentials
readOnly: true
volumes:
- name: db-credentials
secret:
secretName: db-credentials-secret
Create these objects from the command line:
kubectl create configmap app-config-map --from-file=./config/
kubectl create secret generic db-credentials-secret --from-literal=username=admin --from-literal=password=$(openssl rand -base64 12)
Sharp edges
kubectl apply on the Secret object alone will not refresh the running pod.Adding or removing pods in response to traffic is the pattern that keeps latency reasonable under variable demand. The Horizontal Pod Autoscaler (HPA) is the canonical mechanism.
Concrete command to create an HPA
kubectl autoscale deployment app --min=2 --max=10 --cpu-percent=75
The resulting HPA resource stores a target average utilization percentage. The orchestrator’s controller loop queries the metrics server every 15 seconds and adjusts the replica count accordingly.
Sharp edges
cpu-percent metric. A pod that occasionally bursts to 200% CPU will be seen as “above target” even during normal operation, causing the HPA to scale up unnecessarily.0 or null for the metric, leading to either no scaling action or erratic scaling behavior that is difficult to diagnose without kubectl get hpa -o yaml and inspection of the currentMetrics field.| Pattern | Primary Command | Common Failure |
|---|---|---|
| Rolling update | kubectl set image … && kubectl rollout status | Probe misconfiguration stalls rollout |
| Canary/blue-green | kubectl patch service … or mesh weight config | Sticky sessions mask traffic split |
| Liveness/readiness | Pod spec httpGet probes | Readiness missing → 502s; liveness too aggressive → restart loop |
| Resource requests/limits | kubectl edit deployment | OOMKilled without graceful shutdown |
| Node drain/cordon/drain | kubectl cordon … && kubectl drain … | DaemonSets or taints block drainage |
| ConfigMap/Secret injection | kubectl create configmap/secret … | Updated ConfigMap/Secret not reflected until pod restart |
| HPA autoscaling | kubectl autoscale … --cpu-percent=75 | Metrics-server lag or external metric adapter misconfiguration |
These patterns form the operational vocabulary of any containerised workload running above a cluster manager. Memorise the commands, respect the probe boundaries, and verify that resource requests and limits match your actual workload profile—the most common production incidents in orchestrated environments trace back to one of the sharp edges listed above.
This page was rewritten on 17 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.
We use cookies for analytics (Google Analytics) and advertising (Google AdSense) to improve your experience and support free content. Privacy Policy