Pourquoi le zero-downtime ?
Les utilisateurs attendent une disponibilite permanente. Un deploiement ne doit jamais interrompre le service. Les strategies principales sont : rolling update, blue-green et canary.
Rolling Update dans Kubernetes
La strategie par defaut de Kubernetes remplace progressivement les anciens Pods par les nouveaux :
apiVersion: apps/v1
kind: Deployment
metadata:
name: mon-app
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
spec:
containers:
- name: app
image: mon-app:v2
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
Blue-Green avec Terraform et un Load Balancer
Le blue-green maintient deux environnements identiques. Le bascule se fait au niveau du load balancer.
# Terraform : basculer le target group
resource "aws_lb_listener_rule" "app" {
listener_arn = aws_lb_listener.front.arn
priority = 100
action {
type = "forward"
target_group_arn = var.active_color == "blue" ?
aws_lb_target_group.blue.arn :
aws_lb_target_group.green.arn
}
condition {
path_pattern {
values = ["/*"]
}
}
}
# Basculer : changer la variable et appliquer
# terraform apply -var="active_color=green"
Canary avec Kubernetes et Istio
Le canary envoie un pourcentage du trafic vers la nouvelle version :
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: mon-app
spec:
hosts:
- mon-app
http:
- route:
- destination:
host: mon-app
subset: stable
weight: 90
- destination:
host: mon-app
subset: canary
weight: 10
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: mon-app
spec:
host: mon-app
subsets:
- name: stable
labels:
version: v1
- name: canary
labels:
version: v2
Rolling update avec Ansible
# Deployer serveur par serveur
- hosts: webservers
serial: 1
pre_tasks:
- name: Retirer du load balancer
uri:
url: "http://lb.example.com/api/backends/{{ inventory_hostname }}"
method: DELETE
roles:
- deploy-app
post_tasks:
- name: Verifier la sante
uri:
url: "http://{{ inventory_hostname }}:8080/healthz"
status_code: 200
register: health
retries: 10
delay: 5
until: health.status == 200
- name: Remettre dans le load balancer
uri:
url: "http://lb.example.com/api/backends"
method: POST
body_format: json
body:
host: "{{ inventory_hostname }}"
Important : La cle du zero-downtime est la readiness probe. Ne marquez jamais un Pod comme pret avant qu'il puisse reellement servir du trafic.