Advanced Deployments in Kubernetes: Strategies and Best Practices
Explore advanced deployment strategies in Kubernetes, rolling updates and rollbacks, as well as best practices for robust deployments.
InSkillCoach
Deployment Strategies in Kubernetes
Kubernetes Deployments offer several strategies for updating your applications. Choosing the right strategy is crucial to minimize service interruptions and ensure a smooth transition.
Recreate Strategy
The Recreate strategy stops all instances of the old version before starting the new ones. It is the default strategy.
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3
strategy:
type: Recreate
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:1.0
Advantages:
- Simple to understand and debug
- Guarantees that only one version is running at a time
Disadvantages:
- Downtime during the deployment
- No automatic rollback on failure
Use cases:
- Applications that don’t support multiple versions running simultaneously
- Development or test environments
- Applications with critical database dependencies
Rolling Update Strategy (RollingUpdate)
The rolling update strategy gradually replaces old instances with new ones, while maintaining a minimum number of available instances.
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # Maximum number of extra pods allowed
maxUnavailable: 0 # Maximum number of pods unavailable during the update
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:1.0
Advantages:
- No downtime
- Automatic rollback on failure
- Fine-grained control over the update process
Disadvantages:
- More complex to configure
- May require more resources during the update
Use cases:
- Production applications
- Services that require high availability
- Applications that support multiple versions running simultaneously
Blue/Green Deployment Strategy
Although Kubernetes does not natively provide blue/green deployments, you can implement them using Services and Deployments.
# "Blue" Deployment (current version)
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-blue
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: blue
template:
metadata:
labels:
app: myapp
version: blue
spec:
containers:
- name: myapp
image: myapp:1.0
---
# "Green" Deployment (new version)
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-green
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: green
template:
metadata:
labels:
app: myapp
version: green
spec:
containers:
- name: myapp
image: myapp:1.1
---
# Service that points to the active version
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: myapp
version: blue # Change to "green" to switch to the new version
ports:
- port: 80
targetPort: 8080
Advantages:
- Instant switchover between versions
- No service degradation during the update
- Simple rollback by changing the Service selector
Disadvantages:
- Requires twice the resources during the deployment
- More complex configuration
- Requires manual intervention or a script for the switchover
Use cases:
- Critical applications with strict maintenance windows
- Services that require a fast switchover if a problem occurs
- Applications with complex dependencies between versions
Canary Deployment Strategy
A canary deployment exposes a small portion of traffic to the new version before rolling it out completely.
# Main Deployment (current version)
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-main
spec:
replicas: 9
selector:
matchLabels:
app: myapp
version: main
template:
metadata:
labels:
app: myapp
version: main
spec:
containers:
- name: myapp
image: myapp:1.0
---
# Canary Deployment (new version)
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-canary
spec:
replicas: 1
selector:
matchLabels:
app: myapp
version: canary
template:
metadata:
labels:
app: myapp
version: canary
spec:
containers:
- name: myapp
image: myapp:1.1
---
# Service that distributes traffic
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
Advantages:
- Testing in production with minimal risk
- Early detection of problems
- Ability to collect metrics before the full rollout
Disadvantages:
- More complex configuration
- Requires careful monitoring during the canary phase
- May require additional tools for traffic routing
Use cases:
- Applications with a large number of users
- Services that require validation in production
- High-risk deployments
Managing Rollbacks
Rollbacks are essential for maintaining your application’s availability when a new version causes problems.
Automatic Rollback with Health Checks
Configure health probes (liveness and readiness) so that Kubernetes can automatically detect problems and perform a rollback.
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:1.0
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
Manual Rollback with kubectl
You can perform a manual rollback to a previous version using the kubectl rollout undo command:
# Rollback vers la version précédente
kubectl rollout undo deployment/app-deployment
# Rollback vers une version spécifique
kubectl rollout undo deployment/app-deployment --to-revision=2
Best Practices for Deployments
1. Use Specific Image Tags
Avoid using latest as an image tag, because it makes it hard to track versions and can lead to non-reproducible deployments.
# À éviter
image: myapp:latest
# Recommandé
image: myapp:1.0.2
2. Set Resource Limits
Specify resource limits to prevent a pod from consuming too many resources and affecting other pods.
spec:
containers:
- name: myapp
image: myapp:1.0
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
3. Use Anti-Affinity Rules
Deploy pods across different nodes to improve availability.
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp
topologyKey: kubernetes.io/hostname
4. Implement Scaling Strategies
Configure the Horizontal Pod Autoscaler (HPA) to automatically adjust the number of replicas based on load.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: app-deployment
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
5. Use ConfigMaps and Secrets
Separate application configuration from code so you can make changes without rebuilding the image.
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: production
LOG_LEVEL: info
---
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
DB_PASSWORD: base64encodedpassword
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
template:
spec:
containers:
- name: myapp
image: myapp:1.0
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secrets
Complete Deployment Example
Here is a complete example of a Kubernetes Deployment that follows best practices:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
labels:
app: myapp
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:1.0.2
ports:
- containerPort: 8080
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secrets
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp
topologyKey: kubernetes.io/hostname
---
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
type: LoadBalancer
Conclusion
Advanced deployments in Kubernetes offer great flexibility for managing your application updates. By choosing the right deployment strategy and following best practices, you can ensure a smooth transition between versions while keeping your service available.
In the next article, we will explore secrets and configuration management in Kubernetes, a crucial aspect of securing your applications.
About InSkillCoach
Training and technology expert
Coach specializing in advanced technologies and AI, backed by GNeurone Inc.
Certifications:
- AWS Certified Solutions Architect – Professional
- Google Cloud certifications
- Microsoft Certified: DevOps Engineer Expert
- Certified Kubernetes Administrator (CKA)
- CompTIA Security+
Comments
Comments are powered by GitHub Discussions
Sign in with GitHub to join the discussion