Deployments and ReplicaSets
1 - Introduction
Deployments are the recommended way to deploy applications on Kubernetes. They automatically manage the ReplicaSets, which in turn maintain the desired number of Pods.
2 - ReplicaSets
2.1 Role of the ReplicaSet
A ReplicaSet ensures that a specified number of replicas of a Pod are running at all times.
# replicaset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-replicaset
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
2.2 How the ReplicaSet works
In practice, you do not create ReplicaSets directly. Instead, use Deployments, which manage ReplicaSets for you.
3 - Deployments
3.1 Create a Deployment
Imperative method:
# Créer un deployment
kubectl create deployment nginx --image=nginx:1.25 --replicas=3
# Vérifier
kubectl get deployments
kubectl get rs
kubectl get pods
Declarative method:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
kubectl apply -f deployment.yaml
3.2 Structure of a Deployment
4 - Scaling
4.1 Manual scaling
# Scale un deployment
kubectl scale deployment nginx-deployment --replicas=5
# Vérifier
kubectl get pods -w # Watch en temps réel
# Scale à zéro (arrêter tous les pods)
kubectl scale deployment nginx-deployment --replicas=0
4.2 Horizontal Pod Autoscaler (HPA)
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
# Créer via commande
kubectl autoscale deployment nginx-deployment --min=2 --max=10 --cpu-percent=70
# Vérifier
kubectl get hpa
kubectl describe hpa nginx-hpa
5 - Update strategies
5.1 RollingUpdate (default)
Gradually updates the Pods without service interruption.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # Pods supplémentaires pendant update
maxUnavailable: 1 # Pods pouvant être indisponibles
template:
spec:
containers:
- name: nginx
image: nginx:1.25
5.2 Recreate
Deletes all old Pods before creating new ones. Involves a service interruption.
spec:
strategy:
type: Recreate
5.3 Comparison of strategies
| Strategy | Interruption | Resources | Use case |
|---|---|---|---|
| RollingUpdate | No | More (temporarily) | Production |
| Recreate | Yes | Less | Dev, incompatibilities |
6 - Updates and rollbacks
6.1 Update a Deployment
# Mettre à jour l'image
kubectl set image deployment/nginx-deployment nginx=nginx:1.26
# Ou via edit
kubectl edit deployment nginx-deployment
# Ou via apply avec un fichier modifié
kubectl apply -f deployment.yaml
# Avec annotation de changement
kubectl set image deployment/nginx-deployment nginx=nginx:1.26 --record
6.2 Track an update
# Status du rollout
kubectl rollout status deployment/nginx-deployment
# Historique des révisions
kubectl rollout history deployment/nginx-deployment
# Détails d'une révision
kubectl rollout history deployment/nginx-deployment --revision=2
6.3 Rollback
# Rollback à la révision précédente
kubectl rollout undo deployment/nginx-deployment
# Rollback à une révision spécifique
kubectl rollout undo deployment/nginx-deployment --to-revision=2
# Vérifier
kubectl rollout status deployment/nginx-deployment
6.4 Pause and resume
# Mettre en pause (pour faire plusieurs changements)
kubectl rollout pause deployment/nginx-deployment
# Faire des modifications
kubectl set image deployment/nginx-deployment nginx=nginx:1.26
kubectl set resources deployment/nginx-deployment -c nginx --limits=cpu=200m,memory=512Mi
# Reprendre le rollout
kubectl rollout resume deployment/nginx-deployment
7 - Revision and history limits
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
revisionHistoryLimit: 10 # Nombre de ReplicaSets à conserver
progressDeadlineSeconds: 600 # Timeout du rollout
template:
# ...
8 - Labels and Selectors
8.1 Importance of selectors
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
selector:
matchLabels:
app: frontend
tier: web
matchExpressions:
- key: version
operator: In
values: ["v1", "v2"]
template:
metadata:
labels:
app: frontend
tier: web
version: v1
8.2 Filter with kubectl
# Pods avec label spécifique
kubectl get pods -l app=frontend
# Pods avec plusieurs labels
kubectl get pods -l app=frontend,tier=web
# Pods avec expression
kubectl get pods -l 'app in (frontend, backend)'
# Pods sans un label
kubectl get pods -l '!version'
9 - Complete production Deployment
# deployment-production.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mon-app
labels:
app: mon-app
version: v1.0.0
annotations:
description: "Application de production"
spec:
replicas: 3
revisionHistoryLimit: 5
progressDeadlineSeconds: 600
selector:
matchLabels:
app: mon-app
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0 # Zero downtime
template:
metadata:
labels:
app: mon-app
version: v1.0.0
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
spec:
# Éviter le même node pour les réplicas
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: mon-app
topologyKey: kubernetes.io/hostname
containers:
- name: app
image: mon-app:v1.0.0
imagePullPolicy: Always
ports:
- name: http
containerPort: 8080
- name: metrics
containerPort: 9090
env:
- name: ENVIRONMENT
value: "production"
- name: LOG_LEVEL
value: "info"
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: http
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
terminationGracePeriodSeconds: 30
10 - Other Workload types
10.1 StatefulSet
For stateful applications (databases).
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
10.2 DaemonSet
One Pod on each node.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
spec:
selector:
matchLabels:
name: fluentd
template:
metadata:
labels:
name: fluentd
spec:
containers:
- name: fluentd
image: fluentd:v1.14
10.3 Job and CronJob
# Job unique
apiVersion: batch/v1
kind: Job
metadata:
name: backup
spec:
template:
spec:
containers:
- name: backup
image: backup-tool:v1
restartPolicy: OnFailure
---
# CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-backup
spec:
schedule: "0 2 * * *" # Tous les jours à 2h
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: backup-tool:v1
restartPolicy: OnFailure
Summary
In this chapter, we learned:
- The role of ReplicaSets in maintaining replicas
- Creating and managing Deployments
- Manual and automatic scaling (HPA)
- The update strategies (RollingUpdate, Recreate)
- Rollbacks and revision history
- Other workloads: StatefulSet, DaemonSet, Job
Next step
In the next chapter, we will explore Services and Networking to expose your applications.
→ Next chapter: Services and Networking