Skip to main content
Insyrge - Zoho CRM & Business Automation Consulting
← Back to All ArticlesAI & Business Automation

Kubernetes Zero Downtime Deployment Guide

How rolling updates, readiness probes, graceful shutdown and disruption budgets work together for invisible releases.

•Manav Sharma
Kubernetes Zero Downtime Deployment Guide

Achieve Kubernetes zero downtime deployment with rolling update settings, readiness probes, graceful shutdown, disruption budgets and safe DB changes.

Releasing a new version of an application should not mean a maintenance page, dropped requests or a nervous evening. Kubernetes can replace running containers gradually while traffic keeps flowing, but only if the application and its configuration cooperate: new pods must signal when they are ready, old pods must finish their work before stopping, and enough capacity must remain throughout. Kubernetes zero downtime deployment is the combination of rolling update settings, readiness probes, graceful shutdown and disruption budgets that makes releases invisible to users. This guide explains each piece, shows a working configuration pattern, covers database changes and rollbacks, and lists what to check before trusting the process in production.

How a rolling update works

A Kubernetes Deployment manages a set of identical pods. When you change its pod template, such as the container image, the Deployment creates new pods and removes old ones in steps rather than all at once. Two settings control the pace, according to the Kubernetes Deployment documentation:

  • maxUnavailable: how many pods can be unavailable during the update, as a number or percentage; the default is 25%
  • maxSurge: how many extra pods can be created above the desired count; the default is also 25%, and it cannot be 0 if maxUnavailable is 0

Setting maxUnavailable to 0 and maxSurge to 1 means a new pod must become available before an old one is removed, which keeps full capacity throughout, at the cost of needing room for one extra pod.

Readiness: only send traffic to pods that can handle it

A new pod may take seconds to start, load configuration and warm caches. If traffic arrives before then, requests fail. Readiness probes solve this. The Kubernetes documentation on pod lifecycle explains that, based on probe results, Kubernetes can stop sending traffic to containers that are not ready. The probes guide covers configuration.

A good readiness endpoint checks that the application can serve requests, such as having loaded configuration and connected to essential services, without being so strict that a brief hiccup in a dependency takes every pod out of service at once.

Keep readiness separate from liveness. A liveness probe tells Kubernetes to restart a container that has stopped working; pointing it at the same strict checks as readiness can cause restarts when a dependency is briefly slow, turning a minor delay into an outage. For applications that start slowly, the probes guide also describes startup probes, which hold off the other probes until the application has started.

Graceful shutdown: let old pods finish

When Kubernetes removes a pod, it sends the main process a termination signal and allows a grace period before forcing it to stop. The pod lifecycle documentation says the grace period defaults to 30 seconds. Applications should handle the signal by stopping new work, finishing requests in progress and closing connections cleanly.

There is a subtlety: removing the pod from service endpoints and sending the termination signal happen around the same time, so a few requests may still arrive just after shutdown begins. A common approach is a short pause in a preStop hook before the application starts shutting down, giving load balancers time to stop routing to the pod. Make sure the pause plus shutdown time fits within the grace period.

Disruption budgets: protect capacity during maintenance

Rolling updates are not the only thing that removes pods. Node maintenance and cluster upgrades evict pods too. A PodDisruptionBudget, described in the Kubernetes guide to configuring a disruption budget, limits how many pods of an application can be down at once during voluntary disruptions, such as draining a node. It does not affect rolling updates directly, but it prevents maintenance from taking too many replicas offline at the same time.

Worked example: Kubernetes zero downtime deployment settings for a web API

Suppose a team runs a customer-facing API with four replicas. This simplified, untested configuration shows the pattern; the image name, paths and timings are placeholders to adapt and test.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: orders-api
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1
  selector:
    matchLabels:
      app: orders-api
  template:
    metadata:
      labels:
        app: orders-api
    spec:
      terminationGracePeriodSeconds: 45
      containers:
        - name: api
          image: registry.example.com/orders-api:1.8.2
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /ready
              port: 8080
            periodSeconds: 5
            failureThreshold: 3
          lifecycle:
            preStop:
              exec:
                command: ["sleep", "10"]
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: orders-api
spec:
  minAvailable: 3
  selector:
    matchLabels:
      app: orders-api

With these settings, each new pod must pass its readiness probe before an old pod is removed, old pods pause for ten seconds before shutting down, and maintenance cannot take the API below three running pods. The sleep command assumes the container image includes it. The application itself must still handle the termination signal gracefully within the 45-second grace period.

Database changes without downtime

Code and database changes must be compatible during a rolling update, because old and new versions run side by side for a while. Use the expand and contract pattern:

  1. Expand: add new columns or tables in a backwards-compatible way, deployed before the code that uses them
  2. Deploy code that works with both old and new structures
  3. Migrate data in the background if needed
  4. Contract: remove old columns only after no running version uses them

Never rename or drop a column in the same release as the code change that stops using it. Our guide to monolith to microservices migration covers similar compatibility thinking at a larger scale.

Rollbacks

Even well-tested releases fail sometimes. Kubernetes keeps a rollout history for Deployments, and the kubectl rollout commands include undo, which returns to the previous revision. Rollbacks are only safe if the previous code still works with the current database, which is another reason for expand and contract. Practise rolling back in a test environment, so it is routine rather than improvised.

Checking before you trust it

Prove that releases are invisible to users before relying on them:

  • Run a load test during a deployment and confirm no failed requests
  • Watch error rates and latency during real releases
  • Test what happens when a new version fails its readiness probe: the rollout should stall, not take down healthy pods
  • Drain a node during load and confirm the disruption budget holds
  • Review graceful shutdown logs to confirm requests complete

Our guide to client portal performance covers monitoring that also shows whether releases affect users.

Common mistakes

  • No readiness probe, so traffic reaches pods before they are ready
  • Applications that ignore the termination signal and drop requests
  • A grace period shorter than the shutdown time
  • Database changes that break the old version during the rollout
  • No disruption budget, so node maintenance removes too many pods
  • Never testing a rollback

Frequently Asked Questions

What is a Kubernetes zero downtime deployment?

It is a release that replaces running pods gradually, using rolling updates, readiness probes and graceful shutdown, so users see no errors or interruption.

What are the default rolling update settings?

According to the Kubernetes documentation, maxUnavailable and maxSurge both default to 25% of the desired number of pods.

Why is a readiness probe needed?

It tells Kubernetes when a pod can handle traffic, so new pods receive requests only once ready and unhealthy pods stop receiving them.

How long does Kubernetes wait before stopping a pod?

The termination grace period defaults to 30 seconds, according to the Kubernetes documentation, and can be adjusted per pod.

Release without interruptions

We design deployment pipelines and Kubernetes configurations that keep applications available during every release. See our custom app development services, or talk to us about your deployments.

About the Author

Manav Sharma is the founder of Insyrge and a CRM solutions architect. He works across Zoho, Salesforce, HubSpot, Odoo and more, designing the CRM setups, integrations and automations that keep sales and operations teams working from the same data.

Need Help Implementing This in Your Business?

Our certified Zoho consultants and automation experts can help you design and deploy custom workflows tailored to your operations.

Book Free Consultation