"Deploy sem downtime" is not a flag. It is the set of decisions that prevents traffic from reaching a pod that is not yet ready — and prevents the cluster from killing a pod that is just slow.
Getting readiness wrong is the number one cause of 502 errors during deployment.
Course seal: tested on Kubernetes 1.35 with a Java application and Nginx.
The three probes
| Probe | Question | If it fails |
|---|---|---|
| startup | already started? | restarts (in the meantime, liveness does not run) |
| readiness | can receive traffic? | leaves the Service (without restarting) |
| liveness | is it alive? | restarts the container |
startupProbe:
httpGet: { path: /actuator/health/liveness, port: 8080 }
failureThreshold: 30
periodSeconds: 5
readinessProbe:
httpGet: { path: /actuator/health/readiness, port: 8080 }
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
livenessProbe:
httpGet: { path: /actuator/health/liveness, port: 8080 }
periodSeconds: 10
failureThreshold: 3
Practical rules:
- Readiness should check dependencies that prevent serving (database, critical cache). Do not put non-critical dependency: if Redis goes down, the pod goes offline unnecessarily.
- Liveness should check only the process. Liveness checking database = cascading restart when the database fluctuates.
- Startup exists for slow applications; without it, liveness kills the app before it comes up.
initialDelaySecondshigh is a symptom of misconfigured liveness, not a solution.
Rolling update
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
maxUnavailable: 0ensures that capacity does not drop during the rollout.maxSurge: 1creates a new pod before tearing down an old one.minReadySecondsprevents considering it ready too early:
minReadySeconds: 10
progressDeadlineSecondsprevents a rollout stuck forever:
progressDeadlineSeconds: 600
Monitor:
kubectl -n portal rollout status deploy/portal-backend --timeout=5m
kubectl -n portal rollout history deploy/portal-backend
kubectl -n portal rollout undo deploy/portal-backend
terminationGracePeriodSeconds and the classic 502
When a pod is removed:
- It is marked as
Terminatingand leaves the Endpoints. - The kubelet sends SIGTERM.
- The process has
terminationGracePeriodSecondsto shut down.
If the application stops accepting connections immediately on SIGTERM, in-flight connections drop. The correct pattern:
- Receive SIGTERM.
- Continue serving for a few seconds (the Endpoints have already propagated).
- Close the server and database connections.
- Exit with 0.
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 5"]
terminationGracePeriodSeconds: 30
The sleep 5 is not elegance: it is the time for the Service to stop sending traffic.
PDB in deployment
PDB protects during drain, not during rollout. Still, without PDB a drain can take down all replicas at once.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: portal-backend
spec:
minAvailable: 1
selector:
matchLabels:
app: portal-backend
minAvailable: 50% also works and scales better.
HPA without bringing down the service
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: portal-backend
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: portal-backend
minReplicas: 2
maxReplicas: 6
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60
Lessons:
minReplicas: 2to not run out of capacity on a single node.scaleDownwith a stabilization window avoids flapping.- CPU metric only works with defined
requests. Without requests, HPA does not calculate. - HPA does not solve database bottleneck. Scaling an app that holds too many connections brings down Postgres — it happened in our environment with 10 pods.
Deploy with tight quota
If the cluster has no slack for maxSurge: 1, the new pod stays Pending and the rollout gets stuck. Two solutions:
maxSurge: 0+maxUnavailable: 1(accepts momentary capacity drop).- Ensure resource slack (chapter 26).
Rollout stuck with Pending is lack of capacity, not a Kubernetes bug.
Lab
- Create a Deployment with 3 replicas, readiness, and
maxUnavailable: 0. - Make a request loop and deploy with a new image:
while true; do curl -s -o /dev/null -w "%{http_code}\n" http://portal.local/api/health; sleep 0.2; done
- Observe the rollout: no 5xx should appear.
- Remove the readinessProbe and repeat: errors appear.
- Test
kubectl drainwith and without PDB. - Generate load and see HPA scale:
kubectl -n portal get hpa -w
- Force a pod into
CrashLoopBackOffand observe liveness/startup.
Common errors
| Symptom | Cause |
|---|---|
| 502 during deployment | missing readiness or missing preStop |
| Cascading restart | liveness checking external dependency |
Rollout stuck Pending |
lack of CPU/memory for the surge |
| HPA does not scale | without requests or metrics-server out |
| HPA scales and brings down the database | too many connections / poorly sized pool |
| Pod never Ready | readiness with wrong path/timeout |
| Drain blocked | PDB with minAvailable equal to the total |
Checklist
- [ ] Startup, readiness, and liveness with distinct purposes.
- [ ] Readiness only with critical dependencies.
- [ ]
maxUnavailable: 0andmaxSurgecompatible with capacity. - [ ]
minReadySecondsandprogressDeadlineSecondsdefined. - [ ]
preStop+terminationGracePeriodSeconds. - [ ] SIGTERM handled in the application.
- [ ] PDB for each critical service.
- [ ] HPA with
requestsandbehaviorof scaleDown. - [ ] Deploy test with request loop.
Glossary
- readiness: ready for traffic.
- liveness: healthy process.
- startup: long initialization.
- maxSurge: extra pods during rollout.
- maxUnavailable: pods that can be missing.
- PDB: disruption budget.
- HPA: horizontal autoscaling.
Next
Zero-downtime deploy solved. Now how the image gets here: pipeline, immutable image, tag by digest, and SBOM in the next chapter.
Next: Kubernetes Course 24 — CI/CD: immutable images and SBOM
Keep reading
Read also

StorCLI - Complete Cheat Sheet
StorCLI is the official and modern tool for managing Broadcom/LSI RAID controllers. This guide covers essential commands, syntax and use cases.
12 min de leitura
TutoriaisBusiness Services in Nyverra Portal: Translating IT into Business
The business doesn't feel a server go down — it feels email stop. The Business Services (Service Mapping) module of Nyverra ITSM Portal connects services like Email, ERP or PACS to CMDB assets, revealing the real impact of each failure.
5 min de leitura
SegurançaRPO vs RTO: How to Define Before Buying Backup (and Why Most Companies Get It Wrong)
Most companies buy backup asking the wrong question: "how much does it cost?". The right question is: how much data can I lose (RPO) and how long can I be down (RTO). Discover how to define these numbers per system and avoid purchasing protection based on price, not on real need.
9 min de leitura
Comments
No comments yet
Be the first to share your thoughts on this article.

Leave a comment