4 min read
Deployment Strategies for Azure Kubernetes Service
Azure Kubernetes Service (AKS) has become the go-to platform for container orchestration on Azure. As organizations scale their container deployments, choosing the right deployment strategy becomes critical. Let me walk through the common patterns.
Prerequisites
# Create an AKS cluster
az aks create \
--resource-group rg-aks \
--name aks-cluster \
--node-count 3 \
--enable-addons monitoring \
--generate-ssh-keys
# Get credentials
az aks get-credentials --resource-group rg-aks --name aks-cluster
Rolling Update (Default)
The default strategy replaces pods gradually:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myregistry.azurecr.io/myapp:v1
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 15
periodSeconds: 20
Deploy and update:
# Initial deployment
kubectl apply -f deployment.yaml
# Update the image
kubectl set image deployment/myapp myapp=myregistry.azurecr.io/myapp:v2
# Watch the rollout
kubectl rollout status deployment/myapp
# Rollback if needed
kubectl rollout undo deployment/myapp
Blue-Green Deployment
Run two identical environments and switch traffic:
# blue-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-blue
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: blue
template:
metadata:
labels:
app: myapp
version: blue
spec:
containers:
- name: myapp
image: myregistry.azurecr.io/myapp:v1
ports:
- containerPort: 80
---
# green-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-green
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: green
template:
metadata:
labels:
app: myapp
version: green
spec:
containers:
- name: myapp
image: myregistry.azurecr.io/myapp:v2
ports:
- containerPort: 80
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
version: blue # Switch to green when ready
ports:
- port: 80
targetPort: 80
Switch traffic:
# Deploy green version
kubectl apply -f green-deployment.yaml
# Test green deployment (via port-forward or internal service)
kubectl port-forward deployment/myapp-green 8080:80
# Switch traffic to green
kubectl patch service myapp -p '{"spec":{"selector":{"version":"green"}}}'
# Clean up blue deployment
kubectl delete deployment myapp-blue
Canary Deployment
Route a percentage of traffic to the new version:
# stable-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-stable
spec:
replicas: 9
selector:
matchLabels:
app: myapp
track: stable
template:
metadata:
labels:
app: myapp
track: stable
spec:
containers:
- name: myapp
image: myregistry.azurecr.io/myapp:v1
---
# canary-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-canary
spec:
replicas: 1 # 10% of total (1 out of 10)
selector:
matchLabels:
app: myapp
track: canary
template:
metadata:
labels:
app: myapp
track: canary
spec:
containers:
- name: myapp
image: myregistry.azurecr.io/myapp:v2
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp # Matches both stable and canary
ports:
- port: 80
targetPort: 80
Gradually shift traffic:
# Scale canary up, stable down
kubectl scale deployment myapp-canary --replicas=3
kubectl scale deployment myapp-stable --replicas=7
# Continue until fully migrated
kubectl scale deployment myapp-canary --replicas=10
kubectl scale deployment myapp-stable --replicas=0
Using Helm for Deployments
# Create a Helm chart
helm create myapp
# Install
helm install myapp ./myapp --set image.tag=v1
# Upgrade
helm upgrade myapp ./myapp --set image.tag=v2
# Rollback
helm rollback myapp 1
Health Checks Are Critical
Always configure proper probes:
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
startupProbe:
httpGet:
path: /health
port: 80
failureThreshold: 30
periodSeconds: 10
Monitoring Deployments
# Watch deployment progress
kubectl get deployments -w
# Check events
kubectl get events --sort-by='.lastTimestamp'
# View pod logs
kubectl logs -f deployment/myapp
Choosing the right deployment strategy depends on your risk tolerance and application requirements. Start with rolling updates and evolve to more sophisticated strategies as needed.