KubernetesXVI · Deployment StrategiesDeployment strategies
Readiness, preStop, and Service traffic — gating rollout safety
What you'll learn
- Describe the readiness-to-endpoints-to-dataplane path that drains traffic from old Pods
- Configure preStop hooks and terminationGracePeriodSeconds to coordinate with load balancers
- Identify the failure modes that interrupt the rollout chain
- Apply readinessProbe and lifecycle discipline to a real production manifest
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
Every Kubernetes rollout strategy depends on the same chain of events: a Pod is created, it becomes Ready, the Endpoints controller includes it in the Service’s Endpoints, kube-proxy programs the dataplane to route traffic to it. When the rollout terminates an old Pod, the chain runs in reverse: preStop runs, SIGTERM is sent, the Pod is removed from Endpoints, kube-proxy drains it, and after the grace period SIGKILL arrives. This lesson is about every link in that chain and the production failures that come from breaking any one of them.
The full chain, end to end
sequenceDiagram
participant K as kubelet
participant EP as Endpoints Controller
participant KP as kube-proxy
participant UL as Upstream LB
participant P as Pod
K->>P: Create container
P->>K: readinessProbe passes
K->>EP: Pod Ready=True
EP->>KP: Endpoints updated
KP->>UL: dataplane programmed
UL->>P: traffic flows
Note over P: rollout begins
UL->>P: preStop runs
P->>K: shutdown
K->>EP: Pod Ready=False
EP->>KP: Endpoints updated
KP->>UL: dataplane drains
UL-->>P: no new traffic
K->>P: SIGTERM after grace period
K->>P: SIGKILL
If any link in the chain is broken — readiness is wrong, the Endpoints controller is not running, kube-proxy is out of sync, the upstream load balancer has a long drain interval — the rollout is unsafe.
The readiness probe is the gate
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
The probe runs against the Pod’s IP at the configured path.
Until it passes, the Pod’s Ready condition is False. The
Endpoints controller excludes not-Ready Pods from the
Service’s Endpoints. Traffic only flows to Ready Pods.
flowchart TB
A[New Pod starts] --> B["Container Running<br/>Ready=False"]
B --> C{readinessProbe}
C -->|pass| D["Ready=True<br/>Endpoints include IP"]
C -->|fail 3x| E["Ready=False<br/>stays out of Endpoints"]
D --> F[Traffic flows]
E --> G[Deployment rollout stalls]
preStop — coordinating with load balancers
When a Pod is terminated, the Endpoints controller marks it not-Ready, and after a small delay removes its IP from the Endpoints object. kube-proxy and the CNI dataplane pick up the change. But external load balancers and Ingress controllers have their own drain intervals, which can be slower than the kubelet’s default termination grace period.
The standard pattern:
spec:
terminationGracePeriodSeconds: 60
containers:
- name: web
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 15"]
The preStop runs before SIGTERM. A 15-second sleep gives the
upstream load balancer time to drain. Combined with a
terminationGracePeriodSeconds: 60, the Pod has 15s of preStop
- 45s for in-flight requests to drain after SIGTERM.
flowchart LR
A[Pod terminating] --> B["preStop<br/>e.g. sleep 15"]
B --> C["Endpoints controller<br/>removes IP"]
C --> D["kube-proxy<br/>dataplane drains"]
D --> E[SIGTERM sent]
E --> F{grace period<br/>elapsed?}
F -->|no| E
F -->|yes| G[SIGKILL]
Without preStop, the upstream LB may still send traffic to the Pod after SIGTERM but before the Endpoints change propagates — producing 502/504 errors during every rollout.
Readiness gates for external systems
A readiness gate is a Pod condition reported by an external controller. The Pod is not Ready until the gate is True.
spec:
readinessGates:
- conditionType: pods.web.example.com/ready
An external controller (e.g., a service mesh sidecar) sets the condition when the Pod is fully wired into the mesh. The Service does not route to the Pod until the mesh reports it ready.
This is how production rollouts safely handle external dependencies: cache priming, downstream service registration, external API warm-up. The Deployment waits for the gate; the gate is owned by the operator’s controller.
The chain breaks in stages
When a rollout is unsafe, the failure usually traces to one link:
| Symptom | Probable cause |
|---|---|
| Old Pod continues serving traffic after rollout | Endpoints controller is not running; readiness is wrong; kube-proxy is stale |
| New Pod sees 100% traffic immediately | readinessProbe is missing or returns 200 on / |
| New Pod receives no traffic after rollout | Service selector does not match Pod template labels |
| Rollout stalls, old Pod continues | New Pod never passes readiness; check kubectl describe pod |
| Errors during rollout only | Upstream LB has long drain; preStop sleep is too short |
| Errors after rollout only | New code is broken — rollback |
Each one requires its own evidence. A blind kubectl rollout undo is the operator’s last resort, not the first response.
Inspecting the rollout state
kubectl get pods -l app=web -n prod -o wide
# NAME READY STATUS AGE
# web-7c8d9b1f8-abcd 1/1 Running 5m
# web-7c8d9b1f8-efgh 1/1 Running 5m
# web-6b3d5a7e9-ijkl 1/1 Running 30s
kubectl describe pod web-6b3d5a7e9-ijkl -n prod | grep -A 2 Conditions
# Conditions:
# Type Status
# Ready True
# ContainersReady True
# PodReadyToStartContainers True
$ kubectl get endpoints web -n prod -o yaml | head -40apiVersion: v1
kind: Endpoints
metadata:
name: web
namespace: prod
subsets:
- addresses:
- ip: 10.244.1.12
nodeName: worker-01
- ip: 10.244.2.34
nodeName: worker-02
- ip: 10.244.1.55
nodeName: worker-01
ports:
- port: 8080If a new Pod’s IP is not in the Endpoints list, the rollout chain has broken before the Endpoints controller step.
Quiz
Knowledge check · 4 questions
Q1. What is the role of a Pod's readiness probe in a RollingUpdate rollout?
Q2. A tcpSocket port 8080 readiness probe is sufficient to verify a web application is ready to serve traffic.
Q3. Your team's deployment uses preStop sleep 15 and terminationGracePeriodSeconds 60. Users report 502 errors during every rollout. Diagnose.
Deployment web with preStop sleep 15 and terminationGracePeriodSeconds 60. The upstream NGINX Ingress has connection-draining but the preStop is not enough.
Q4. Why do env-var ConfigMap/Secret changes not take effect on running Pods, and what is the production workaround?
Passing score: 75%. Answers are checked in this browser.
Production discipline
- Readiness must be application-aware. A real probe verifies dependencies and warms state, not just port reachability.
preStopis mandatory for stateful traffic drains. A 10-15 second sleep costs nothing; an unsynced LB costs every user 1-2 errors.terminationGracePeriodSecondsmust exceed the longest expected in-flight request. A 60-second value is a safe default for HTTP; tune upward for long-lived connections.- Rollout metrics are first-class. The Deployment
controller’s
progressDeadlineSecondsshould match the alerting threshold; a stuck rollout is a page. - Test the chain in staging. Synthesise a rollout that
scales
replicas: 0mid-flight. If readiness and preStop are wrong, you will see it in the staging logs, not in production.
The strategy you choose — RollingUpdate, Recreate, blue/green, canary — is the visible half. The invisible half is the chain that drains and admits traffic. Operators who understand the chain own the rollout.