CKA — Deployments

4 minute read

CKA Exam Domain

Workloads & Scheduling — 15%

Understand Deployments and how to perform rolling updates.

Deployments are one of the most heavily tested topics in the CKA exam. You’ll need to create them quickly (both imperative and declarative), understand their relationship with ReplicaSets, and know the available strategies.

What Is a Deployment?

A Deployment provides a declarative way to manage Pods. You describe a desired state — which container image, how many replicas, what update strategy — and the Deployment controller makes it happen.

Under the hood, a Deployment manages one or more ReplicaSets, which in turn manage the actual Pods.

Deployment → ReplicaSet → Pod(s)

Why use Deployments instead of bare Pods?

Feature Bare Pod Deployment
Self-healing No Yes — Pods are recreated if they fail
Scaling Manual kubectl scale or HPA
Rolling updates Not possible Built-in
Rollback Not possible Built-in revision history
Declarative management Limited Full support

Creating Deployments

Imperative (fast — great for the exam)

kubectl create deployment nginx --image=nginx:1.27 --replicas=3

Generate YAML without creating (use --dry-run=client):

kubectl create deployment nginx --image=nginx:1.27 --replicas=3 \
  --dry-run=client -o yaml > nginx-deploy.yaml

Declarative (YAML manifest)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.27
        ports:
        - containerPort: 80

Apply with:

kubectl apply -f nginx-deploy.yaml

Deployment Spec Breakdown

Here’s the annotated breakdown of every key field:

apiVersion: apps/v1          # API group for Deployments
kind: Deployment
metadata:
  name: web                  # Deployment name
  namespace: default         # Target namespace
  labels:
    app: web                 # Labels on the Deployment itself
spec:
  replicas: 3                # Desired number of Pods
  revisionHistoryLimit: 10   # How many old ReplicaSets to keep (default: 10)
  selector:
    matchLabels:
      app: web               # MUST match .spec.template.metadata.labels
  strategy:
    type: RollingUpdate      # RollingUpdate (default) or Recreate
    rollingUpdate:
      maxSurge: 25%          # Max Pods above desired count during update
      maxUnavailable: 25%    # Max Pods unavailable during update
  template:                  # Pod template
    metadata:
      labels:
        app: web             # Pod labels — must match selector
    spec:
      containers:
      - name: web
        image: nginx:1.27
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 250m
            memory: 256Mi

Exam tip: The selector.matchLabels and template.metadata.labels must match. If they don’t, the Deployment will be rejected.

ReplicaSets Under the Hood

A Deployment doesn’t manage Pods directly — it creates a ReplicaSet, which then creates the Pods.

kubectl get rs

Output:

NAME               DESIRED   CURRENT   READY   AGE
nginx-6d4cf56db6   3         3         3       2m

The random suffix (6d4cf56db6) is a hash of the Pod template. When you update the Deployment (e.g., change the image), a new ReplicaSet is created and the old one is scaled down.

# After an update, you'll see two ReplicaSets:
kubectl get rs
NAME               DESIRED   CURRENT   READY   AGE
nginx-6d4cf56db6   0         0         0       10m    # old
nginx-7f89b4c7d2   3         3         3       1m     # new

Important: Never manage ReplicaSets directly. Always manage the Deployment and let it handle ReplicaSets for you.

Deployment Strategies

Strategy Behavior Downtime Use Case
RollingUpdate (default) Gradually replaces old Pods with new ones No Production workloads
Recreate Kills all old Pods first, then creates new ones Yes When old & new versions can’t coexist

RollingUpdate Strategy (default)

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1           # At most 1 extra Pod during update
      maxUnavailable: 0     # All Pods must stay available

Recreate Strategy

spec:
  strategy:
    type: Recreate

With Recreate, Kubernetes terminates all existing Pods before creating new ones. This causes downtime but guarantees only one version runs at a time.

maxSurge and maxUnavailable Combinations

maxSurge maxUnavailable Behavior
25% 25% Default — balanced speed and availability
1 0 Safest — no downtime, one extra Pod at a time
0 1 No extra Pods — one Pod removed before new one added
50% 0 Fast rollout — up to 50% extra Pods temporarily

kubectl Commands

# Create a Deployment
kubectl create deployment web --image=nginx:1.27 --replicas=3

# List Deployments
kubectl get deployments

# Detailed info
kubectl describe deployment web

# View ReplicaSets managed by the Deployment
kubectl get rs

# Scale the Deployment
kubectl scale deployment web --replicas=5

# Delete the Deployment (also deletes ReplicaSets and Pods)
kubectl delete deployment web

# Generate YAML (exam trick)
kubectl create deployment web --image=nginx:1.27 --replicas=3 \
  --dry-run=client -o yaml

# Edit a Deployment live
kubectl edit deployment web

Practice Questions

Q1. Create a Deployment named api-server with image httpd:2.4 and 4 replicas using an imperative command.

Show Answer
kubectl create deployment api-server --image=httpd:2.4 --replicas=4

Verify:

kubectl get deployment api-server
kubectl get pods -l app=api-server

Q2. What is the default Deployment strategy, and what are the default values for maxSurge and maxUnavailable?

Show Answer

The default strategy is RollingUpdate with:

  • maxSurge: 25%
  • maxUnavailable: 25%

You can verify with:

kubectl describe deployment <name> | grep -A5 "Strategy"

Q3. A Deployment named backend exists. Generate its YAML without modifying it.

Show Answer
kubectl get deployment backend -o yaml > backend.yaml

Q4. What happens if selector.matchLabels doesn’t match template.metadata.labels in a Deployment?

Show Answer

The API server will reject the Deployment with a validation error. The selector and Pod template labels must match — this is enforced at creation time.


Q5. Create a Deployment named cache with image redis:7 and the Recreate strategy. Use --dry-run=client to generate the YAML, then modify it and apply.

Show Answer
kubectl create deployment cache --image=redis:7 --dry-run=client -o yaml > cache.yaml

Edit cache.yaml and add the strategy:

spec:
  strategy:
    type: Recreate

Apply:

kubectl apply -f cache.yaml

Verify:

kubectl describe deployment cache | grep Strategy

Next up — learn how to update and rollback Deployments safely.

Next: Rolling Updates & Rollbacks →

Updated: