Kubernetes Deployments: Rolling Updates and Best Practices
Deployment Configuration
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: api-server
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # Max pods above desired (during update)
maxUnavailable: 0 # Never take pods offline (zero-downtime)
template:
metadata:
labels:
app: api-server
version: "1.2.3"
spec:
containers:
- name: api
image: myrepo/api:1.2.3
ports:
- containerPort: 3000
# Resource limits are critical
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
# Health probes
livenessProbe:
httpGet:
path: /health/live
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /health/ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
# Graceful shutdown
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 5"]
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: app-secrets
key: database-url
terminationGracePeriodSeconds: 30
Health Check Endpoints
// Express health endpoints
app.get('/health/live', (req, res) => {
// Liveness: is the process running?
res.json({ status: 'ok', uptime: process.uptime() });
});
app.get('/health/ready', async (req, res) => {
// Readiness: can it handle requests?
try {
await db.query('SELECT 1'); // DB check
await redis.ping(); // Cache check
res.json({ status: 'ready' });
} catch (err) {
res.status(503).json({ status: 'not ready', error: err.message });
}
});
Horizontal Pod Autoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 2
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # Wait 5min before scaling down
policies:
- type: Percent
value: 50 # Scale down by max 50%
periodSeconds: 60
Pod Disruption Budget
# Ensure minimum availability during node drain/upgrades
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-server-pdb
spec:
minAvailable: 2 # Always keep at least 2 pods running
selector:
matchLabels:
app: api-server
Blue-Green Deployment
# Blue (current)
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-blue
spec:
replicas: 3
template:
metadata:
labels:
app: api
version: blue
spec:
containers:
- name: api
image: myrepo/api:1.2.3
---
# Service switches between blue and green
apiVersion: v1
kind: Service
metadata:
name: api-service
spec:
selector:
app: api
version: blue # Change to 'green' for cutover
ports:
- port: 80
targetPort: 3000
Rolling updates with proper health checks and PDBs enable zero-downtime deployments.