Lab: Simulating Deployment Strategies with Kubernetes
Prerequisites
kubectlconfigured against a running Kubernetes cluster (local clusters likeminikube,kind, ork3dwork perfectly)minikubeversion 1.30 or later (if using minikube)- Basic familiarity with
kubectl getandkubectl apply
Setup: Create a Working Directory
mkdir -p ~/devops-labs/deployment-strategies
cd ~/devops-labs/deployment-strategies
Part 1: Rolling Update in Action
Step 1: Deploy Version 1
Create the initial deployment file:
cat > rolling-deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 6
selector:
matchLabels:
app: webapp
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: nginx:1.24
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 3
periodSeconds: 3
EOF
kubectl apply -f rolling-deployment.yaml
Expected output:
deployment.apps/webapp created
Step 2: Watch the pods come up
kubectl get pods -l app=webapp --watch
Expected output (after ~15 seconds):
NAME READY STATUS RESTARTS AGE
webapp-7d9f8b6c4-2xkpq 1/1 Running 0 12s
webapp-7d9f8b6c4-4mnvr 1/1 Running 0 12s
webapp-7d9f8b6c4-6bqwt 1/1 Running 0 12s
webapp-7d9f8b6c4-8hzpl 1/1 Running 0 12s
webapp-7d9f8b6c4-k9rts 1/1 Running 0 12s
webapp-7d9f8b6c4-p3vjx 1/1 Running 0 12s
Press Ctrl+C to stop watching.
Step 3: Trigger a rolling update to Version 2
Open a second terminal and run the watch command so you can observe the rollout live:
# Terminal 2: watch pods
kubectl get pods -l app=webapp --watch
In your first terminal, update the image:
kubectl set image deployment/webapp webapp=nginx:1.25
Expected output:
deployment.apps/webapp image updated
In Terminal 2, you will see pods being terminated and replaced one at a time:
webapp-7d9f8b6c4-2xkpq 1/1 Terminating 0 2m
webapp-8c6f9d7b5-nqwvz 0/1 Pending 0 0s
webapp-8c6f9d7b5-nqwvz 0/1 Running 0 3s
webapp-8c6f9d7b5-nqwvz 1/1 Running 0 6s
webapp-7d9f8b6c4-4mnvr 1/1 Terminating 0 2m
...
Step 4: Check rollout status
kubectl rollout status deployment/webapp
Expected output:
deployment "webapp" successfully rolled out
Step 5: Simulate a rollback
kubectl rollout undo deployment/webapp
Expected output:
deployment.apps/webapp rolled back
Verify the image reverted:
kubectl get deployment webapp -o jsonpath='{.spec.template.spec.containers[0].image}'
Expected output:
nginx:1.24
Part 2: Simulating Blue/Green with Two Deployments
Step 1: Create the Blue deployment (v1)
cat > blue-deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-blue
spec:
replicas: 3
selector:
matchLabels:
app: webapp
version: blue
template:
metadata:
labels:
app: webapp
version: blue
spec:
containers:
- name: webapp
image: nginx:1.24
ports:
- containerPort: 80
EOF
kubectl apply -f blue-deployment.yaml
Step 2: Create the Service pointing to Blue
cat > webapp-service.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
name: webapp-svc
spec:
selector:
app: webapp
version: blue
ports:
- port: 80
targetPort: 80
EOF
kubectl apply -f webapp-service.yaml
Expected output:
service/webapp-svc created
Step 3: Deploy Green (v2) — no traffic yet
cat > green-deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-green
spec:
replicas: 3
selector:
matchLabels:
app: webapp
version: green
template:
metadata:
labels:
app: webapp
version: green
spec:
containers:
- name: webapp
image: nginx:1.25
ports:
- containerPort: 80
EOF
kubectl apply -f green-deployment.yaml
Verify both deployments are running:
kubectl get deployments
Expected output:
NAME READY UP-TO-DATE AVAILABLE AGE
webapp-blue 3/3 3 3 2m
webapp-green 3/3 3 3 30s
Step 4: Switch traffic from Blue to Green (the "flip")
kubectl patch service webapp-svc -p '{"spec":{"selector":{"version":"green"}}}'
Expected output:
service/webapp-svc patched
Step 5: Verify the switch
kubectl get service webapp-svc -o jsonpath='{.spec.selector}'
Expected output:
{"app":"webapp","version":"green"}
Step 6: Instant rollback — switch back to Blue
kubectl patch service webapp-svc -p '{"spec":{"selector":{"version":"blue"}}}'
Expected output:
service/webapp-svc patched
Verify It Worked
kubectl get deployments
kubectl get service webapp-svc -o jsonpath='{.spec.selector}'
You should see both Blue and Green deployments running, and the service selector showing blue after the rollback — confirming that traffic is back on the original version.
What Just Happened?
In Part 1, you observed Kubernetes' rolling update controller replacing pods one at a time, respecting the maxUnavailable and maxSurge constraints, and you practiced an instant rollback using kubectl rollout undo. In Part 2, you simulated a Blue/Green deployment by running two separate Deployments simultaneously and switching traffic between them by patching a single Service selector — a change that takes effect in milliseconds. This is the core mechanism behind Blue/Green: the "switch" is just a label selector update on a Service, not a redeployment of any application code.
Cleanup
kubectl delete deployment webapp webapp-blue webapp-green
kubectl delete service webapp-svc
You're viewing a free demo lesson
Take the 4-min skill check to get your personalized roadmap, then sign up to save it.