DEV Community

janak0ff
janak0ff

Posted on

Execute Rolling Updates in Kubernetes

An application currently running on the Kubernetes cluster employs the nginx web server. The Nautilus application development team has introduced some recent changes that need deployment. They've crafted an image nginx:1.19 with the latest updates.

Execute a rolling update for this application, integrating the nginx:1.19 image. The deployment is named nginx-deployment.

Ensure all pods are operational post-update.

Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.


Solution

Step 1: Check Current Deployment Status

First, let's verify the current state of the deployment:

kubectl get deployments
kubectl get pods
kubectl get rs
Enter fullscreen mode Exit fullscreen mode

Expected output:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           5m

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-7c5d8bf9f7-xxx    1/1     Running   0          5m
nginx-deployment-7c5d8bf9f7-yyy    1/1     Running   0          5m
nginx-deployment-7c5d8bf9f7-zzz    1/1     Running   0          5m
Enter fullscreen mode Exit fullscreen mode

Step 2: Check Current Image Version

Verify the current image version:

kubectl describe deployment nginx-deployment | grep Image
Enter fullscreen mode Exit fullscreen mode

Step 3: Perform the Rolling Update

Update the deployment to use the nginx:1.19 image:

kubectl set image deployment/nginx-deployment nginx=nginx:1.19
Enter fullscreen mode Exit fullscreen mode

Expected output:

deployment.apps/nginx-deployment image updated
Enter fullscreen mode Exit fullscreen mode

Step 4: Check Rollout Status

Monitor the rollout progress:

kubectl rollout status deployment/nginx-deployment
Enter fullscreen mode Exit fullscreen mode

Expected output:

Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 3 out of 3 new replicas have been updated...
deployment "nginx-deployment" successfully rolled out
Enter fullscreen mode Exit fullscreen mode

Step 5: Verify the Update

Check that all pods are updated and running:

# Check deployment status
kubectl get deployments

# Check pods
kubectl get pods

# Verify the new image
kubectl describe deployment nginx-deployment | grep Image

# Check pods with the new image
kubectl get pods -o jsonpath='{.items[*].spec.containers[0].image}'
Enter fullscreen mode Exit fullscreen mode

Expected output:

nginx:1.19
Enter fullscreen mode Exit fullscreen mode

Step 6: Check ReplicaSets

Verify the old and new ReplicaSets:

kubectl get rs
Enter fullscreen mode Exit fullscreen mode

Expected output:

NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-7c5d8bf9f7   0         0         0       5m    # Old ReplicaSet (scaled down)
nginx-deployment-8d9f4b5c6    3         3         3       1m    # New ReplicaSet (scaled up)
Enter fullscreen mode Exit fullscreen mode

Alternative Methods

Method 1: Using kubectl edit

Edit the deployment directly:

kubectl edit deployment nginx-deployment
Enter fullscreen mode Exit fullscreen mode

Then change:

spec:
  containers:
  - image: nginx:1.19
Enter fullscreen mode Exit fullscreen mode

Save and exit. The deployment will automatically roll out the update.

Method 2: Using kubectl patch

Patch the deployment with a strategic merge:

kubectl patch deployment nginx-deployment -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx","image":"nginx:1.19"}]}}}}'
Enter fullscreen mode Exit fullscreen mode

Method 3: Using kubectl apply with YAML

Update the YAML file and reapply:

# Edit the YAML file
nano nginx-deployment.yaml

# Change image to nginx:1.19
# Apply the updated YAML
kubectl apply -f nginx-deployment.yaml
Enter fullscreen mode Exit fullscreen mode

Method 4: Using kubectl replace

# Get current deployment YAML
kubectl get deployment nginx-deployment -o yaml > nginx-deployment.yaml

# Edit the file
nano nginx-deployment.yaml

# Replace with the updated YAML
kubectl replace -f nginx-deployment.yaml
Enter fullscreen mode Exit fullscreen mode

Verification Commands

1. Check Deployment Status

# Detailed status
kubectl rollout status deployment/nginx-deployment

# Deployment details
kubectl describe deployment nginx-deployment

# Show deployment with custom columns
kubectl get deployment nginx-deployment -o custom-columns=NAME:.metadata.name,REPLICAS:.spec.replicas,UPDATED:.status.updatedReplicas,READY:.status.readyReplicas
Enter fullscreen mode Exit fullscreen mode

2. Verify Pod Status

# List all pods
kubectl get pods

# Get detailed pod information
kubectl get pods -o wide

# Check pod status with labels
kubectl get pods --show-labels

# Verify all pods are running
kubectl get pods -l app=nginx-deployment
Enter fullscreen mode Exit fullscreen mode

3. Check Image Version

# Check image of all pods
kubectl get pods -o jsonpath='{.items[*].spec.containers[0].image}'

# Check image for specific pod
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[0].image}'

# Check image via describe
kubectl describe deployment nginx-deployment | grep -i image
Enter fullscreen mode Exit fullscreen mode

4. Monitor the Update Process

# Watch pods during update
kubectl get pods -w

# Watch deployments during update
kubectl get deployments -w

# Watch ReplicaSets during update
kubectl get rs -w
Enter fullscreen mode Exit fullscreen mode

5. Check Events

# Check events related to the deployment
kubectl get events --field-selector involvedObject.name=nginx-deployment

# Check all events sorted by time
kubectl get events --sort-by='.lastTimestamp'
Enter fullscreen mode Exit fullscreen mode

6. View Logs

# View logs from updated pods
kubectl logs deployment/nginx-deployment

# View logs from specific pod
kubectl logs -l app=nginx-deployment
Enter fullscreen mode Exit fullscreen mode

Understanding Rolling Updates

How Rolling Updates Work

┌─────────────────────────────────────────────────────────┐
│                     Deployment                          │
│                    Desired: 3 pods                      │
└────────────────────┬────────────────────────────────────┘
                     │
        ┌────────────┴────────────┐
        │                         │
        ▼                         ▼
┌───────────────────┐   ┌───────────────────┐
│   Old ReplicaSet  │   │   New ReplicaSet  │
│   (nginx:latest)  │   │   (nginx:1.19)    │
│   ┌───┐ ┌───┐     │   │   ┌───┐           │
│   │ 1 │ │ 2 │     │ → │   │ 3 │           │
│   └───┘ └───┘     │   │   └───┘           │
│   ┌───┐           │   │   ┌───┐           │
│   │ 3 │           │ → │   │ 2 │           │
│   └───┘           │   │   └───┘           │
│   ┌───┐           │   │   ┌───┐           │
│   │ 4 │           │ → │   │ 1 │           │
│   └───┘           │   │   └───┘           │
└───────────────────┘   └───────────────────┘
Enter fullscreen mode Exit fullscreen mode

Update Strategy Options

1. RollingUpdate (Default)

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1        # Maximum extra pods during update
    maxUnavailable: 0  # Maximum unavailable pods during update
Enter fullscreen mode Exit fullscreen mode

2. Recreate

strategy:
  type: Recreate
Enter fullscreen mode Exit fullscreen mode

RollingUpdate Parameters

Parameter Description Default Example
maxSurge Max extra pods during update 25% 1 or 25%
maxUnavailable Max unavailable pods during update 25% 0 or 25%

Advanced Operations

1. Pause a Rollout

# Pause the rollout
kubectl rollout pause deployment/nginx-deployment

# Check status (will show paused)
kubectl rollout status deployment/nginx-deployment
Enter fullscreen mode Exit fullscreen mode

2. Resume a Rollout

# Resume the rollout
kubectl rollout resume deployment/nginx-deployment
Enter fullscreen mode Exit fullscreen mode

3. Check Rollout History

# View all revisions
kubectl rollout history deployment/nginx-deployment

# View specific revision details
kubectl rollout history deployment/nginx-deployment --revision=1
kubectl rollout history deployment/nginx-deployment --revision=2
Enter fullscreen mode Exit fullscreen mode

4. Rollback to Previous Version

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

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

# Check status after rollback
kubectl rollout status deployment/nginx-deployment
Enter fullscreen mode Exit fullscreen mode

5. Change Update Strategy

# Change to Recreate strategy
kubectl patch deployment nginx-deployment -p '{"spec":{"strategy":{"type":"Recreate"}}}'

# Change RollingUpdate parameters
kubectl patch deployment nginx-deployment -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":2,"maxUnavailable":1}}}}'
Enter fullscreen mode Exit fullscreen mode

6. Set Update Parameters

# Set maxSurge and maxUnavailable
kubectl patch deployment nginx-deployment -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":"50%","maxUnavailable":"25%"}}}}'
Enter fullscreen mode Exit fullscreen mode

Common Issues and Troubleshooting

Issue 1: Rollout Stuck

Symptoms:

  • Rollout status shows waiting indefinitely
  • Pods remain in "Pending" or "CrashLoopBackOff"

Solutions:

# Check rollout status
kubectl rollout status deployment/nginx-deployment

# Check pod status
kubectl get pods

# Check pod events
kubectl describe pod -l app=nginx-deployment

# Check deployment events
kubectl describe deployment nginx-deployment

# If stuck, try resuming
kubectl rollout resume deployment/nginx-deployment

# If still stuck, undo the rollout
kubectl rollout undo deployment/nginx-deployment
Enter fullscreen mode Exit fullscreen mode

Issue 2: Image Pull Error

Error:

ImagePullBackOff or ErrImagePull
Enter fullscreen mode Exit fullscreen mode

Solutions:

# Check if image exists
docker pull nginx:1.19

# Check pod details
kubectl describe pod <pod-name>

# If image doesn't exist, update to correct image
kubectl set image deployment/nginx-deployment nginx=nginx:1.19.10

# Or rollback to working version
kubectl rollout undo deployment/nginx-deployment
Enter fullscreen mode Exit fullscreen mode

Issue 3: CrashLoopBackOff

Error:

Pod crashes continuously
Enter fullscreen mode Exit fullscreen mode

Solutions:

# Check pod logs
kubectl logs <pod-name> --previous

# Check pod events
kubectl describe pod <pod-name>

# Try rolling back
kubectl rollout undo deployment/nginx-deployment

# Or investigate the image
kubectl run test --image=nginx:1.19 --rm -it -- /bin/bash
Enter fullscreen mode Exit fullscreen mode

Issue 4: Insufficient Resources

Error:

0/1 nodes are available: 1 Insufficient cpu
Enter fullscreen mode Exit fullscreen mode

Solutions:

# Check node resources
kubectl describe nodes

# Scale down temporarily
kubectl scale deployment nginx-deployment --replicas=2

# After update, scale back up
kubectl scale deployment nginx-deployment --replicas=3

# Or use maxUnavailable to reduce load
kubectl patch deployment nginx-deployment -p '{"spec":{"strategy":{"rollingUpdate":{"maxUnavailable":"50%"}}}}'
Enter fullscreen mode Exit fullscreen mode

Issue 5: Pods Not Ready

Error:

Pods running but not ready (0/1)
Enter fullscreen mode Exit fullscreen mode

Solutions:

# Check readiness probe
kubectl describe pod <pod-name> | grep -A 5 Readiness

# Check application logs
kubectl logs <pod-name>

# If probes are failing, consider:
# 1. Increasing initialDelaySeconds
# 2. Adjusting failureThreshold
# 3. Rolling back if application issues
kubectl rollout undo deployment/nginx-deployment
Enter fullscreen mode Exit fullscreen mode

Monitoring During Rolling Update

1. Real-time Monitoring Script

#!/bin/bash
echo "=== Monitoring Rolling Update ==="
while true; do
    clear
    echo "=== Deployment Status ==="
    kubectl get deployment nginx-deployment
    echo ""
    echo "=== Pod Status ==="
    kubectl get pods -l app=nginx-deployment
    echo ""
    echo "=== ReplicaSets ==="
    kubectl get rs -l app=nginx-deployment
    sleep 2
done
Enter fullscreen mode Exit fullscreen mode

2. Watch Commands

# Watch deployment status
watch -n 2 'kubectl get deployment nginx-deployment'

# Watch pod status
watch -n 2 'kubectl get pods -l app=nginx-deployment'

# Watch ReplicaSets
watch -n 2 'kubectl get rs -l app=nginx-deployment'
Enter fullscreen mode Exit fullscreen mode

3. Metrics Monitoring

# Monitor pod metrics during update
kubectl top pods -l app=nginx-deployment

# Monitor node metrics
kubectl top nodes
Enter fullscreen mode Exit fullscreen mode

Testing the Update

1. Test Nginx Version

# Get a shell in one of the pods
kubectl exec -it $(kubectl get pods -l app=nginx-deployment -o jsonpath='{.items[0].metadata.name}') -- /bin/bash

# Check nginx version
nginx -v
# Should show: nginx version: nginx/1.19.0
Enter fullscreen mode Exit fullscreen mode

2. Test Application Functionality

# Port forward to test
kubectl port-forward deployment/nginx-deployment 8080:80

# Test the application
curl http://localhost:8080
# Should show the default nginx welcome page

# Check response headers
curl -I http://localhost:8080
Enter fullscreen mode Exit fullscreen mode

3. Load Testing

# Run a simple load test
kubectl run load-test --image=busybox --rm -it -- /bin/sh -c "while true; do wget -q -O- http://nginx-deployment:80; sleep 1; done"
Enter fullscreen mode Exit fullscreen mode

Complete Example with Deployment

Here's a complete deployment YAML with rolling update configuration:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: default
  labels:
    app: nginx
    environment: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  minReadySeconds: 10
  revisionHistoryLimit: 5
  template:
    metadata:
      labels:
        app: nginx
        environment: production
    spec:
      containers:
      - name: nginx
        image: nginx:1.19
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
        resources:
          requests:
            cpu: "100m"
            memory: "64Mi"
          limits:
            cpu: "200m"
            memory: "128Mi"
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 5
          timeoutSeconds: 3
          successThreshold: 1
          failureThreshold: 3
Enter fullscreen mode Exit fullscreen mode

Best Practices for Rolling Updates

✅ DO's

  1. Use version tags, not latest
   # GOOD
   image: nginx:1.19

   # BAD
   image: nginx:latest
Enter fullscreen mode Exit fullscreen mode
  1. Test in staging first
   # Deploy to staging
   kubectl set image deployment/nginx-staging nginx=nginx:1.19
   kubectl rollout status deployment/nginx-staging

   # Test
   curl http://nginx-staging:80

   # Then deploy to production
   kubectl set image deployment/nginx-production nginx=nginx:1.19
Enter fullscreen mode Exit fullscreen mode
  1. Set appropriate update strategy
   strategy:
     type: RollingUpdate
     rollingUpdate:
       maxSurge: 1
       maxUnavailable: 0
Enter fullscreen mode Exit fullscreen mode
  1. Add health checks
   readinessProbe:
     httpGet:
       path: /health
       port: 80
     initialDelaySeconds: 10
     periodSeconds: 5
Enter fullscreen mode Exit fullscreen mode
  1. Use minReadySeconds
   minReadySeconds: 10
Enter fullscreen mode Exit fullscreen mode
  1. Monitor during rollout
   # Watch the update
   kubectl rollout status deployment/nginx-deployment
   kubectl get pods -w
Enter fullscreen mode Exit fullscreen mode
  1. Prepare rollback plan
   # Know how to rollback quickly
   kubectl rollout undo deployment/nginx-deployment
Enter fullscreen mode Exit fullscreen mode

❌ DON'Ts

  1. Don't update without testing

    • Always test images before deployment
    • Use staging environment
  2. Don't use too aggressive parameters

   # BAD - Too aggressive
   maxSurge: 100%
   maxUnavailable: 100%

   # GOOD - Conservative
   maxSurge: 25%
   maxUnavailable: 25%
Enter fullscreen mode Exit fullscreen mode
  1. Don't ignore readiness probes

    • Without probes, traffic may be sent to unready pods
    • Implement proper readiness checks
  2. Don't forget to monitor

    • Monitor application metrics during and after update
    • Set up alerts for errors
  3. Don't delete old ReplicaSets

    • Keep at least 2-3 revisions for rollback
   revisionHistoryLimit: 5
Enter fullscreen mode Exit fullscreen mode

Clean Up

# Delete the deployment
kubectl delete deployment nginx-deployment

# Or delete using YAML
kubectl delete -f nginx-deployment.yaml

# Verify deletion
kubectl get deployments
kubectl get pods
Enter fullscreen mode Exit fullscreen mode

Lab Completion Summary

✅ Task Requirements Checklist

  • [x] Deployment identified: nginx-deployment
  • [x] Image updated: nginx:1.19
  • [x] Rolling update performed: Using kubectl set image
  • [x] Update verified: All pods operational
  • [x] Image version confirmed: nginx:1.19

Final Verification Commands

echo "=== Deployment Status ==="
kubectl get deployment nginx-deployment
echo ""
echo "=== Pod Status ==="
kubectl get pods -l app=nginx-deployment
echo ""
echo "=== Image Version ==="
kubectl get pods -o jsonpath='{.items[*].spec.containers[0].image}' -l app=nginx-deployment
echo ""
echo "=== Rollout History ==="
kubectl rollout history deployment nginx-deployment
echo ""
echo "=== Current ReplicaSets ==="
kubectl get rs -l app=nginx-deployment
Enter fullscreen mode Exit fullscreen mode

Expected output:

=== Deployment Status ===
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           10m

=== Pod Status ===
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-8d9f4b5c6-abc     1/1     Running   0          1m
nginx-deployment-8d9f4b5c6-def     1/1     Running   0          1m
nginx-deployment-8d9f4b5c6-ghi     1/1     Running   0          1m

=== Image Version ===
nginx:1.19 nginx:1.19 nginx:1.19

=== Rollout History ===
REVISION  STATUS
1         Superseded
2         Current

=== Current ReplicaSets ===
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-8d9f4b5c6   3         3         3       1m
Enter fullscreen mode Exit fullscreen mode

Success! 🎉

You have successfully:

  1. Performed a rolling update from nginx:latest to nginx:1.19
  2. Verified the update completed successfully
  3. Ensured all pods are operational
  4. Checked rollout history and ReplicaSets
  5. Verified the new image is running

The Nautilus application development team's changes have been successfully deployed using a rolling update strategy! The application is now running the nginx:1.19 image with zero downtime.

Top comments (0)