Target Audience: Backend developers who want to deploy applications in Kubernetes Prerequisites: Pod concepts After reading this: You will understand how to deploy and update applications with Deployments

TL;DR
  • Deployment manages declarative updates of Pods
  • Rolling updates enable zero-downtime deployment
  • Can rollback to previous version when problems occur

What is Deployment?#

Deployment is a resource that manages Pod deployment and updates. Using Deployment instead of directly managing Pods offers several benefits.

FeatureDescription
Declarative updatesJust define desired state, Kubernetes handles the rest
Rolling updatesDeploy new version without downtime
RollbackRevert to previous version when problems occur
ScalingChange Pod count by adjusting replicas
Auto-recoveryAutomatically recreate Pods on failure

Deployment Structure#

Deployment creates ReplicaSets, and ReplicaSets manage Pods.

flowchart TB
    D[Deployment] --> RS[ReplicaSet]
    RS --> P1[Pod 1]
    RS --> P2[Pod 2]
    RS --> P3[Pod 3]

Comparing each resource’s role:

ResourceRole
DeploymentManage deployment strategy, ReplicaSet version management
ReplicaSetMaintain specified number of Pod replicas
PodExecute actual application containers
Why Not Use ReplicaSet Directly
You can create ReplicaSets directly, but they lack rolling update and rollback features. Always use Deployment as it provides these capabilities.

Deployment YAML#

A basic Deployment definition.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: app
        image: my-app:1.0
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"

Key fields explained:

FieldDescription
replicasNumber of Pods to maintain
selector.matchLabelsCriteria to select Pods to manage
templatePod template to create
template.metadata.labelsLabels to attach to Pods (must match selector)

Relationship Between Selector and Labels#

Deployment’s selector and Pod’s labels must match.

spec:
  selector:
    matchLabels:
      app: my-app      # Manage Pods with this label
  template:
    metadata:
      labels:
        app: my-app    # Assign this label to Pods (matches above)

Rolling Updates#

Understanding rolling updates, a core Deployment feature.

Rolling Update Process#

Changing the image version triggers a rolling update.

sequenceDiagram
    participant D as Deployment
    participant RS1 as ReplicaSet v1
    participant RS2 as ReplicaSet v2

    Note over RS1: Pod v1 x 3

    D->>RS2: Create new ReplicaSet
    RS2->>RS2: Start 1 Pod v2
    RS1->>RS1: Terminate 1 Pod v1

    RS2->>RS2: Start 2 Pods v2
    RS1->>RS1: Terminate 2 Pods v1

    RS2->>RS2: Start 3 Pods v2
    RS1->>RS1: Terminate 3 Pods v1

    Note over RS2: Pod v2 x 3

Rolling Update State by Stage#

With replicas=3, maxSurge=1, maxUnavailable=0:

Stagev1 Podsv2 PodsTotal PodsAvailable PodsDescription
0 (before)3033Initial state
13143Create 1 v2 Pod
22133After v2 Ready, terminate 1 v1
32243Create 1 more v2 Pod
41233After v2 Ready, terminate 1 v1
51343Create 1 more v2 Pod
6 (complete)0333Terminate last v1
Key Point
With maxUnavailable=0, available Pods always remain at 3 or more. Previous Pods are only terminated after new Pods become Ready.

Advantages of rolling updates:

AdvantageDescription
Zero-downtimeAlways maintains certain number of running Pods
GradualCan stop if problems detected
AutomatedNo separate scripts needed

Update Strategy Configuration#

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # Additional Pods allowed beyond desired count
      maxUnavailable: 0  # Pods that can be unavailable simultaneously
SettingMeaningExample (replicas=3)
maxSurge: 1Allow up to 4 running3+1=4
maxUnavailable: 0Always keep minimum 3 runningNever go below 2
maxSurge: 25%Allow up to 43*1.25=3.75→4

Comparing common strategies:

StrategymaxSurgemaxUnavailableCharacteristics
Safety first10Slow but safe
Fast deployment25%25%Fast but temporary capacity reduction
Resource saving01No additional resources needed

Recreate Strategy#

Strategy to terminate all Pods then create new ones.

spec:
  strategy:
    type: Recreate

Use cases:

  • When old and new versions cannot run simultaneously
  • Applications that only allow single instance
  • When database migration is needed
Warning
Recreate strategy causes downtime. Use carefully in production.

Rollback#

Revert to previous version when problems occur.

Check Rollout History#

# Check deployment history
kubectl rollout history deployment/my-app

Expected output:

REVISION  CHANGE-CAUSE
1         <none>
2         <none>
3         <none>

To record CHANGE-CAUSE, add annotation during deployment:

kubectl annotate deployment/my-app kubernetes.io/change-cause="Update to image version 2.0"

Execute Rollback#

# Rollback to immediately previous version
kubectl rollout undo deployment/my-app

# Rollback to specific version
kubectl rollout undo deployment/my-app --to-revision=2

Check Rollout Status#

# Rollout progress status
kubectl rollout status deployment/my-app

# Pause rollout
kubectl rollout pause deployment/my-app

# Resume rollout
kubectl rollout resume deployment/my-app

Scaling#

Adjust Pod count to respond to traffic changes.

Manual Scaling#

# Change replicas to 5
kubectl scale deployment/my-app --replicas=5

# Or edit YAML
kubectl edit deployment/my-app

Scaling Considerations#

ConsiderationDescription
Resource checkWhether nodes have sufficient resources
ConnectionsDB connection pool, external API limits
Session managementWhether sticky session is needed
StorageRWO volumes cannot be shared by multiple Pods

Practice: Deploying and Updating Deployment#

Create Deployment#

# Create Deployment
kubectl apply -f deployment.yaml

# Check status
kubectl get deployment my-app
kubectl get replicaset
kubectl get pods -l app=my-app

Update Image#

# Trigger rolling update by changing image
kubectl set image deployment/my-app app=my-app:2.0

# Monitor rollout status
kubectl rollout status deployment/my-app

# Watch Pods being replaced
kubectl get pods -w

Check ReplicaSets#

# List ReplicaSets - previous versions are retained
kubectl get rs

# Expected output:
# NAME                  DESIRED   CURRENT   READY   AGE
# my-app-7d8f9b7c5f     3         3         3       10m
# my-app-5b9f8c6d4e     0         0         0       30m

Previous ReplicaSets are retained for rollback. You can configure retention count with revisionHistoryLimit.

spec:
  revisionHistoryLimit: 3  # Keep only recent 3 versions

Rollback Practice#

# Intentionally deploy invalid image
kubectl set image deployment/my-app app=my-app:invalid

# Check rollout status (fails)
kubectl rollout status deployment/my-app

# Check Pod status
kubectl get pods
# Check Pods in ImagePullBackOff state

# Rollback
kubectl rollout undo deployment/my-app

# Verify recovery
kubectl get pods

Frequently Used kubectl Commands#

CommandDescription
kubectl get deploymentList Deployments
kubectl describe deployment <name>Detailed information
kubectl rollout status deployment/<name>Rollout status
kubectl rollout history deployment/<name>Version history
kubectl rollout undo deployment/<name>Rollback
kubectl scale deployment/<name> --replicas=NScaling
kubectl set image deployment/<name> <container>=<image>Change image

Deployment example for actual operations.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  revisionHistoryLimit: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: app
        image: my-app:1.0
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10

Recommended settings checklist:

ItemReason
resources settingsPrevent resource contention, scheduling accuracy
readinessProbePrevent traffic to unready Pods
livenessProbeAuto-restart stuck Pods
maxUnavailable: 0Guarantee zero-downtime deployment
revisionHistoryLimitManage rollback-able versions

Next Steps#

Once you understand Deployments, proceed to the next steps:

GoalRecommended Doc
Access PodsService
Auto-scalingScaling
Configure health checksHealth Checks