Comment effectuer des mises à jour progressives sans interruption de service dans les déploiements Kubernetes
Configurez les mises à jour progressives de Kubernetes avec des sondes de disponibilité, maxSurge, maxUnavailable et un arrêt gracieux.
Comment effectuer des mises à jour progressives sans interruption de service dans les déploiements Kubernetes
Les mises à jour progressives de Kubernetes peuvent remplacer les Pods sans interruption visible, mais seulement si votre déploiement et votre application s'accordent sur le moment où un Pod est prêt et comment il doit s'arrêter. La stratégie par défaut aide, mais elle ne vous protège pas contre les mauvaises sondes de disponibilité, les versions incompatibles ou les requêtes en cours abandonnées.
Atteindre une véritable interruption zéro, cependant, nécessite plus que la configuration Kubernetes par défaut. Cela exige une coordination minutieuse entre le manifeste de déploiement, les points de terminaison de santé de l'application et le processus d'arrêt gracieux. Ce guide fournit une approche complète, étape par étape, pour configurer les déploiements Kubernetes afin de garantir que les mises à jour de l'application soient transparentes et invisibles pour l'utilisateur final.
Ce guide couvre les sondes de disponibilité, maxSurge, maxUnavailable et l'arrêt gracieux afin que votre service maintienne sa capacité pendant un déploiement.
Prérequis pour une interruption zéro
Avant de configurer le manifeste Kubernetes, l'application sous-jacente doit respecter certains principes pour prendre en charge les déploiements sans interruption :
- Compatibilité ascendante de l'application : Pendant la courte période où les anciennes et nouvelles versions de l'application fonctionnent simultanément, elles doivent être compatibles avec les ressources partagées (bases de données, files d'attente, caches).
- Idempotence : Les opérations qui pourraient être traitées par les deux versions doivent être répétables sans effets secondaires négatifs.
- Arrêt gracieux : L'application doit être programmée pour reconnaître le signal
SIGTERMenvoyé par Kubernetes et arrêter gracieusement d'accepter de nouvelles connexions tout en terminant les requêtes en cours avant de se fermer.
Comprendre la stratégie de mise à jour progressive de Kubernetes
Les déploiements Kubernetes utilisent par défaut la stratégie RollingUpdate. Cette méthode garantit que l'ancienne version de l'application n'est pas complètement supprimée avant que la nouvelle version ne soit opérationnelle, en gérant la transition à l'aide de deux paramètres principaux :
| Paramètre | Description | Impact sur l'interruption zéro |
|---|---|---|
maxSurge |
Définit le nombre maximum de Pods pouvant être créés au-dessus du nombre souhaité de réplicas. Peut être un nombre absolu ou un pourcentage (par défaut : 25%). | Contrôle la vitesse du déploiement et garantit une augmentation temporaire de la capacité. |
maxUnavailable |
Définit le nombre maximum de Pods pouvant être indisponibles pendant la mise à jour. Peut être un nombre absolu ou un pourcentage (par défaut : 25%). | Crucial pour une interruption zéro. Définir cette valeur à 0% signifie qu'aucun Pod en service n'est terminé tant que les nouveaux Pods ne sont pas complètement Prêts. |
Stratégie recommandée pour une interruption zéro
Pour la plus haute disponibilité, la meilleure configuration est souvent de garantir une perte de capacité nulle :
maxUnavailable: 0(Garantir que la capacité ne diminue jamais).maxSurge: 1ou25%(Permettre à la capacité de dépasser brièvement la cible, garantissant qu'un nouveau Pod est prêt avant qu'un ancien ne soit tué).
Étape 1 : Implémentation des sondes de disponibilité
La sonde de disponibilité est le mécanisme le plus important pour garantir des mises à jour sans interruption. Kubernetes s'appuie sur cette sonde pour déterminer si un nouveau Pod est prêt à recevoir du trafic utilisateur et si un ancien Pod sert encore activement du trafic.
Sonde de vivacité vs. Sonde de disponibilité
- Sonde de vivacité : Indique à Kubernetes si le conteneur est sain et fonctionnel. En cas d'échec, le conteneur est redémarré.
- Sonde de disponibilité : Indique à Kubernetes si le conteneur est prêt à servir des requêtes. En cas d'échec, le Pod est retiré des points de terminaison du Service associé, détournant le trafic jusqu'à ce qu'il soit prêt.
Pour les mises à jour progressives, la sonde de disponibilité est utilisée pour contrôler la transition. Kubernetes ne procédera pas à la terminaison d'un ancien Pod tant qu'un Pod nouvellement créé n'aura pas réussi son test de disponibilité.
# extrait de deployment.yaml
spec:
containers:
- name: my-app
image: myregistry/my-app:v2.0
ports:
- containerPort: 8080
# --- Configuration de la sonde de disponibilité ---
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 15 # Temps d'attente avant la première tentative de sonde
periodSeconds: 5 # Fréquence d'exécution du test
timeoutSeconds: 3
failureThreshold: 3 # Nombre d'échecs consécutifs pour marquer le Pod comme non prêt
# --- Configuration de la sonde de vivacité (test de santé standard) ---
livenessProbe:
httpGet:
path: /health/live
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
Astuce : Assurez-vous que le point de terminaison
/health/readyde votre application renvoie un code de succès (HTTP 200-299) uniquement lorsque l'initialisation, les connexions à la base de données et autres dépendances externes sont pleinement opérationnelles.
Étape 2 : Configuration de la stratégie de déploiement
Pour imposer une véritable interruption zéro, nous configurons explicitement la stratégie de mise à jour progressive afin d'empêcher toute baisse du nombre de réplicas disponibles.
Dans cette configuration, Kubernetes créera d'abord un nouveau Pod (maxSurge: 1). Une fois que le nouveau Pod aura passé sa sonde de disponibilité, seulement alors Kubernetes terminera un ancien Pod. Puisque maxUnavailable est 0, la capacité du service ne descend jamais en dessous du nombre cible de réplicas.
# extrait de deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-web-deployment
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
# Garantit que la capacité ne descend jamais en dessous du nombre souhaité de réplicas (4)
maxUnavailable: 0
# Permet la création d'un Pod supplémentaire pendant le déploiement
maxSurge: 1
template:
# ... spécification du conteneur ...
Étape 3 : Garantir un arrêt gracieux
Même avec des sondes de disponibilité robustes, si l'application s'arrête instantanément dès la réception du signal de terminaison, elle risque de perdre des requêtes en cours.
Kubernetes suit une séquence de terminaison spécifique :
- Le Pod est marqué comme Terminating.
- Le Pod est retiré des points de terminaison du Service (le trafic cesse d'être routé vers lui).
- Le hook pré-arrêt (s'il est défini) est exécuté.
- Le conteneur reçoit le signal
SIGTERM. - Kubernetes attend la durée définie par
terminationGracePeriodSeconds(par défaut : 30 secondes). - Si le conteneur est toujours en cours d'exécution, il reçoit un
SIGKILLnon négociable.
Pour garantir un arrêt gracieux, l'application doit gérer SIGTERM, et terminationGracePeriodSeconds doit être suffisamment long pour que l'application termine les requêtes existantes.
# extrait de deployment.yaml, à l'intérieur de la spécification du modèle de Pod
spec:
terminationGracePeriodSeconds: 45 # Paramètre au niveau du Pod
containers:
- name: my-app
image: myregistry/my-app:v2.0
lifecycle:
preStop:
exec:
# Donne le temps aux mises à jour des points de terminaison et aux équilibreurs de charge externes de se vider.
command: ["/bin/sh", "-c", "sleep 10"]
Meilleure pratique : Votre application doit cesser d'accepter de nouvelles tâches lorsqu'elle reçoit
SIGTERM, puis terminer les requêtes en cours avant de se fermer. UnterminationGracePeriodSecondslégèrement plus long, comme 45 ou 60 secondes, aide à prévenir les arrêts forcés pour les requêtes plus lentes.
Étape 4 : Effectuer et surveiller la mise à jour
Une fois que votre manifeste de déploiement inclut la stratégie optimisée et des sondes robustes, effectuer la mise à jour est simple.
Mettre à jour l'étiquette de l'image : Modifiez votre manifeste de déploiement pour refléter la nouvelle version de l'image (par exemple,
v2.0àv2.1).Appliquer la configuration :
kubectl apply -f deployment.yamlAlternativement, vous pouvez patcher l'image directement :
kubectl set image deployment/my-web-deployment my-app=myregistry/my-app:v2.1Surveiller l'état du déploiement : Observez Kubernetes progresser à travers les étapes, en vérifiant que le nombre de Pods prêts ne descend jamais en dessous du nombre souhaité.
kubectl rollout status deployment/my-web-deploymentVérifier la disponibilité des Pods : Observez l'état des Pods pour confirmer que les anciens Pods (v2.0) sont terminés gracieusement seulement après que les nouveaux Pods (v2.1) sont complètement prêts.
kubectl get pods -l app=my-web-deployment -w
Considérations avancées
Utilisation des budgets de perturbation de Pods (PDB)
Alors qu'une stratégie de déploiement gère les déploiements, un budget de perturbation de Pods (PDB) limite les perturbations volontaires telles que les drainages de nœuds et certaines opérations de maintenance du cluster. Il n'empêche pas toutes les pannes imprévues, mais il donne à Kubernetes et aux outils d'automatisation un objectif de disponibilité minimale à respecter.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: my-app-pdb
spec:
minAvailable: 75% # Garantir qu'au moins 75% des réplicas sont toujours disponibles
selector:
matchLabels:
app: my-web-deployment
L'importance du délai initial
Si votre application prend du temps à chauffer, ajustez initialDelaySeconds, periodSeconds et failureThreshold pour que la disponibilité reflète le comportement réel de démarrage. Une sonde de disponibilité qui échoue maintient le Pod hors des points de terminaison du Service ; une sonde de vivacité qui échoue est ce qui peut redémarrer le conteneur et créer une boucle de crash.
Déployer en toute sécurité
Atteindre de véritables mises à jour progressives sans interruption dans Kubernetes est une combinaison d'une configuration de plateforme robuste et d'un développement d'application discipliné. En utilisant correctement les sondes de disponibilité pour signaler l'état opérationnel, en ajustant la stratégie de déploiement (maxUnavailable: 0) pour maintenir la capacité, et en implémentant des gestionnaires d'arrêt gracieux, vous pouvez garantir que les mises à jour de l'application sont effectuées de manière fiable sans perturber le service pour vos utilisateurs. Testez toujours votre processus de mise à jour de manière approfondie dans un environnement de staging pour valider la période d'arrêt gracieux et la logique des sondes.