Deployments

Deployments are the most common way to manage stateless applications in Kubernetes. They provide declarative updates, rolling deployments, rollback capabilities, and automatic pod replacement. Think of a Deployment as a manager that ensures your application always has the right number of pods running with the correct configuration.

What Are Deployments?

A Deployment manages a ReplicaSet, which in turn manages a set of pods. When you update a Deployment—changing the container image, environment variables, or resource limits—the Deployment automatically performs a rolling update, gradually replacing old pods with new ones without downtime.

graph TB A[Deployment] --> B[Manages ReplicaSet] B --> C[ReplicaSet Manages Pods] C --> D[Pod 1] C --> E[Pod 2] C --> F[Pod 3] G[Update Deployment] --> H[New ReplicaSet Created] H --> I[Gradual Pod Replacement] I --> J[Rolling Update Complete] style A fill:#e1f5ff style B fill:#fff4e1 style C fill:#e8f5e9 style I fill:#f3e5f5

Why Use Deployments?

Deployments provide several key benefits:

Declarative updates - Describe desired state, Kubernetes makes it happen
Rolling updates - Update pods gradually without downtime
Automatic rollback - Revert to previous version if something goes wrong
Self-healing - Automatically replaces failed pods
Scaling - Easily scale up or down by changing replica count
Status tracking - Monitor rollout progress and health

How Deployments Work

Deployments use ReplicaSets to manage pod replicas. When you create a Deployment, it creates a ReplicaSet that ensures the desired number of pods are running. When you update the Deployment, it creates a new ReplicaSet and performs a rolling update.

graph TD A[Deployment Created] --> B[Creates ReplicaSet] B --> C[ReplicaSet Creates Pods] C --> D[Pods Running] E[Update Deployment] --> F{Update Strategy} F -->|RollingUpdate| G[New ReplicaSet Created] F -->|Recreate| H[Delete Old Pods First] G --> I[Scale Up New ReplicaSet] I --> J[Scale Down Old ReplicaSet] J --> K[Rolling Update Complete] H --> L[Create New Pods] L --> K style A fill:#e1f5ff style G fill:#fff4e1 style K fill:#e8f5e9

Basic Deployment Example

Here’s a simple Deployment that runs an nginx web server:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

Key fields:

  • replicas - Number of pod replicas to maintain
  • selector - Labels that identify which pods this Deployment manages
  • template - Pod template used to create new pods
  • template.metadata.labels - Must match the selector labels

Deployment Lifecycle

A Deployment goes through several states during its lifecycle:

graph LR A[Deployment Created] --> B[Progressing] B --> C{All Pods Ready?} C -->|Yes| D[Available] C -->|No| B D --> E[Updated] E --> F[Progressing] F --> C E --> G[Deployment Deleted] G --> H[Pods Terminated] style A fill:#e1f5ff style D fill:#e8f5e9 style H fill:#ffe1e1

You can check the status with:

kubectl get deployment nginx-deployment
kubectl describe deployment nginx-deployment
kubectl rollout status deployment nginx-deployment

Updating Deployments

Deployments support two update strategies:

RollingUpdate (Default)

Gradually replaces old pods with new ones. You can control the update process:

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1          # Can have 1 extra pod during update
      maxUnavailable: 0    # All pods must be available
  replicas: 3

During a rolling update:

  • New pods are created gradually
  • Old pods are terminated after new ones are ready
  • Service remains available throughout

Recreate

Terminates all old pods before creating new ones. Causes brief downtime:

spec:
  strategy:
    type: Recreate

Use Recreate when:

  • Your application doesn’t support running multiple versions
  • You need to ensure only one version runs at a time
  • Brief downtime is acceptable

Rolling Updates in Action

sequenceDiagram participant User participant Deployment participant OldReplicaSet participant NewReplicaSet participant Pods User->>Deployment: Update image Deployment->>NewReplicaSet: Create new ReplicaSet NewReplicaSet->>Pods: Create Pod 4 (new) NewReplicaSet->>Pods: Create Pod 5 (new) OldReplicaSet->>Pods: Terminate Pod 1 (old) NewReplicaSet->>Pods: Create Pod 6 (new) OldReplicaSet->>Pods: Terminate Pod 2 (old) OldReplicaSet->>Pods: Terminate Pod 3 (old) Deployment->>User: Update complete

Rollback

If an update causes problems, you can rollback to a previous version:

# View rollout history
kubectl rollout history deployment nginx-deployment

# Rollback to previous version
kubectl rollout undo deployment nginx-deployment

# Rollback to specific revision
kubectl rollout undo deployment nginx-deployment --to-revision=2

# View rollback status
kubectl rollout status deployment nginx-deployment

Scaling Deployments

Scale a Deployment by changing the replica count:

# Scale to 5 replicas
kubectl scale deployment nginx-deployment --replicas=5

# Or edit the Deployment
kubectl edit deployment nginx-deployment

You can also enable autoscaling:

kubectl autoscale deployment nginx-deployment --min=3 --max=10 --cpu-percent=80

Deployment vs ReplicaSet

While ReplicaSets manage pod replicas, Deployments add:

  • Rolling updates - Gradual pod replacement
  • Rollback - Revert to previous versions
  • History - Track changes and revisions
  • Pause/Resume - Control rollout process

You typically use Deployments rather than ReplicaSets directly, as Deployments provide a higher-level abstraction that includes update management.

When to Use Deployments

Use Deployments for:

Stateless applications - Web servers, APIs, microservices
Applications needing updates - Rolling updates without downtime
Standard workloads - Most containerized applications
Applications that scale horizontally - Multiple identical pods
Applications without stable identity - Pods are interchangeable

Don’t use Deployments for:

Stateful applications - Use StatefulSets instead
One-time tasks - Use Jobs
Scheduled tasks - Use CronJobs
One pod per node - Use DaemonSets

Best Practices

  1. Always specify resource requests and limits - Helps scheduler make better placement decisions

  2. Use health probes - Liveness and readiness probes ensure pods are healthy

containers:
- name: nginx
  image: nginx:1.21
  livenessProbe:
    httpGet:
      path: /
      port: 80
    initialDelaySeconds: 30
    periodSeconds: 10
  readinessProbe:
    httpGet:
      path: /
      port: 80
    initialDelaySeconds: 5
    periodSeconds: 5
  1. Match labels correctly - Ensure selector.matchLabels matches template.metadata.labels

  2. Use appropriate update strategy - RollingUpdate for zero-downtime, Recreate when necessary

  3. Set maxUnavailable carefully - Ensure service availability during updates

  4. Version your images - Use specific tags, not latest, for predictable deployments

  5. Monitor rollouts - Use kubectl rollout status to monitor update progress

  6. Test rollbacks - Verify you can rollback before deploying to production

  7. Use namespaces - Organize Deployments with namespaces

  8. Document changes - Use annotations to document why changes were made

metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
    description: "Initial deployment"

Common Operations

View Deployment Status

kubectl get deployments
kubectl describe deployment nginx-deployment
kubectl get rs -l app=nginx  # View ReplicaSets
kubectl get pods -l app=nginx  # View Pods

Pause and Resume

# Pause a rollout
kubectl rollout pause deployment nginx-deployment

# Make multiple changes while paused
kubectl set image deployment nginx-deployment nginx=nginx:1.22
kubectl set resources deployment nginx-deployment -c nginx --limits=cpu=1000m

# Resume the rollout
kubectl rollout resume deployment nginx-deployment

Delete Deployment

# Delete Deployment (pods are also deleted)
kubectl delete deployment nginx-deployment

# Or delete with cascading
kubectl delete deployment nginx-deployment --cascade=foreground

Topics

See Also