Introduction
Running signifie qu’un processus de conteneur existe ; cela ne prouve pas que l’application est prête à recevoir du trafic ni qu’elle est capable de récupérer après une défaillance. Les sondes Kubernetes transforment les vérifications de santé propres à l’application en comportements pour les contrôleurs et les Services.
Vous allez ajouter les trois types de sondes, observer comment la disponibilité retire un Pod des points de terminaison d’un Service, le réparer, puis ajouter un mécanisme d’arrêt progressif.
Gardez bien les responsabilités distinctes : une sonde de démarrage protège les initialisations lentes, une sonde de disponibilité détermine si un Pod reçoit le trafic d’un Service, et une sonde de vivacité indique quand kubelet doit redémarrer un conteneur bloqué. Utiliser une seule sonde pour tous les objectifs entraîne souvent des redémarrages évitables ou l’envoi prématuré de trafic.
Déployer une application avec des sondes
Dans cette étape, déployez NGINX avec des vérifications de démarrage, de disponibilité et de vivacité sur /, via son port nommé http.
Le manifeste est plus long, car les trois sondes se trouvent dans la spécification du conteneur. Avant de l’appliquer, lisez-le dans cet ordre : Deployment et labels, conteneur et port nommé, puis sondes de démarrage, de disponibilité et de vivacité. Dans cette démonstration, les trois vérifications utilisent le même point de terminaison HTTP, mais leurs conséquences en cas d’échec sont différentes.
Certaines associations et listes sur une seule ligne utilisent le style YAML compact appelé « flow style », comme {app: healthy-web}. Les accolades représentent une association et les crochets une liste ; ils ont la même signification que leurs équivalents YAML sur plusieurs lignes. Utilisez-les ici uniquement lorsque la valeur complète reste facile à lire.
Le seuil de démarrage autorise jusqu’à 24 secondes (12 × 2) avant que Kubernetes ne considère le démarrage comme échoué. Une fois le démarrage réussi, la disponibilité est vérifiée toutes les trois secondes et la vivacité toutes les cinq secondes.
cd /home/labex/project/application-health
cat <<'EOF' > healthy-web.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: healthy-web
namespace: practice-health
spec:
replicas: 2
selector:
matchLabels: {app: healthy-web}
template:
metadata:
labels: {app: healthy-web}
spec:
containers:
- name: web
image: nginx:1.27-alpine
imagePullPolicy: IfNotPresent
ports:
- {name: http, containerPort: 80, protocol: TCP}
startupProbe:
httpGet: {path: /, port: http}
failureThreshold: 12
periodSeconds: 2
readinessProbe:
httpGet: {path: /, port: http}
periodSeconds: 3
livenessProbe:
httpGet: {path: /, port: http}
periodSeconds: 5
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: healthy-web
namespace: practice-health
spec:
selector: {app: healthy-web}
ports:
- {name: http, port: 80, targetPort: http, protocol: TCP}
EOF
Créez l’espace de noms et appliquez le manifeste. rollout status attend que les deux réplicas satisfassent la condition de disponibilité, et pas simplement que leurs processus aient démarré :
kubectl create namespace practice-health
kubectl apply -f healthy-web.yaml
kubectl rollout status deployment/healthy-web -n practice-health --timeout=60s
La sonde de démarrage protège les initialisations lentes ; la disponibilité contrôle l’accès au trafic ; la vivacité permet un redémarrage après une défaillance irrécupérable.
Si le déploiement s’achève correctement, vous savez déjà davantage que « les conteneurs sont en cours d’exécution » : les deux Pods ont répondu avec succès à la requête de disponibilité.
La dernière ligne du déploiement constitue la première preuve de bon fonctionnement :
Waiting for deployment "healthy-web" rollout to finish: 0 of 2 updated replicas are available...
Waiting for deployment "healthy-web" rollout to finish: 1 of 2 updated replicas are available...
deployment "healthy-web" successfully rolled out
Les lignes intermédiaires sont normales. Kubernetes indique la progression à mesure que chaque Pod réussit les sondes de démarrage et de disponibilité ; seule la dernière ligne signifie que les deux réplicas sont disponibles.
Relier la disponibilité aux points de terminaison du Service
Dans cette étape, examinez la condition de disponibilité et les EndpointSlices.
Commencez par le tableau habituel des Pods, puis limitez l’affichage à la condition de disponibilité et au nombre de redémarrages. Le tableau personnalisé permet de distinguer facilement « non disponible » de « en cours de redémarrage » :
kubectl get pods -n practice-health -l app=healthy-web
kubectl get pods -n practice-health -l app=healthy-web -o custom-columns='POD:.metadata.name,READY_CONDITION:.status.conditions[?(@.type=="Ready")].status,RESTARTS:.status.containerStatuses[0].restartCount'
kubectl get endpointslices -n practice-health -l kubernetes.io/service-name=healthy-web -o jsonpath='{range .items[].endpoints[*]}{.addresses[0]} ready={.conditions.ready}{"\n"}{end}'
Les deux adresses devraient afficher ready=true. Un échec de la sonde de disponibilité laisse le conteneur en fonctionnement, mais retire son adresse du routage normal du Service.
Les EndpointSlices font le lien entre le sélecteur d’un Service et les adresses réelles des Pods. Le Service existe toujours lorsqu’un Pod n’est pas disponible ; c’est la condition de son point de terminaison qui empêche l’envoi du trafic normal vers ce Pod.
Voici un exemple typique lorsque tout fonctionne correctement :
POD READY_CONDITION RESTARTS
healthy-web-... True 0
healthy-web-... True 0
10.244.104.11 ready=true
10.244.104.12 ready=true
Les noms des Pods et les adresses IP seront différents. C’est la relation qui compte : deux Pods Ready=True correspondent à deux points de terminaison ready=true, et aucun conteneur n’a redémarré.
Observer un échec de disponibilité
Dans cette étape, modifiez volontairement uniquement le chemin de disponibilité pour utiliser une URL inexistante.
Il s’agit d’un échec contrôlé. Le correctif JSON remplace un seul champ imbriqué et laisse donc les sondes de démarrage et de vivacité inchangées. NGINX renvoie le code HTTP 404 pour /not-ready, ce que la sonde de disponibilité interprète comme un échec.
kubectl patch deployment healthy-web -n practice-health --type='json' -p='[{"op":"replace","path":"/spec/template/spec/containers/0/readinessProbe/httpGet/path","value":"/not-ready"}]'
kubectl rollout status deployment/healthy-web -n practice-health --timeout=20s || true
kubectl get pods -n practice-health -l app=healthy-web
kubectl get endpointslices -n practice-health -l kubernetes.io/service-name=healthy-web -o jsonpath='{range .items[].endpoints[*]}{.addresses[0]} ready={.conditions.ready}{"\n"}{end}'
|| true indique que l’expiration du délai de déploiement est attendue et permet au shell de poursuivre. Les nouveaux conteneurs s’exécutent, mais la disponibilité échoue et le Deployment ne peut pas devenir entièrement disponible.
Le déploiement testé a produit un état similaire à celui-ci :
error: timed out waiting for the condition
NAME READY STATUS RESTARTS
healthy-web-old-... 1/1 Running 0
healthy-web-old-... 1/1 Running 0
healthy-web-new-... 0/1 Running 0
...
10.244.104.17 ready=false
Le nouveau Pod est Running, mais il n’est pas disponible et n’a pas redémarré. Les deux anciens Pods disponibles restent en place, car les mises à jour progressives des Deployments protègent la disponibilité : Kubernetes ne remplace pas davantage de réplicas sains tant que la nouvelle révision ne peut pas devenir disponible. L’expiration du délai du déploiement démontre donc à la fois le comportement de la sonde de disponibilité et le mécanisme de sécurité du contrôleur. Dans la sortie des EndpointSlices, la nouvelle adresse affiche ready=false, et le routage normal du Service continue donc d’utiliser uniquement les points de terminaison sains.
Réparer la disponibilité et vérifier le trafic
Dans cette étape, rétablissez le chemin de disponibilité et attendez le retour des points de terminaison du Service.
Utilisez l’opération inverse du correctif précédent afin que l’expérience ne modifie qu’une seule variable. L’attente de l’état du déploiement réussit maintenant, car les Pods de remplacement répondent à / avec le code HTTP 200.
kubectl run health-client crée un Pod autonome temporaire pour effectuer la requête. --image sélectionne BusyBox, --image-pull-policy=IfNotPresent réutilise l’image mise en cache et --restart=Never demande la création d’un Pod plutôt que d’un contrôleur. --rm -i maintient la commande attachée et supprime le Pod à sa sortie ; le second -- sépare les options de kubectl de la commande wget exécutée à l’intérieur du conteneur.
Dans wget -qO-, -q masque les messages de progression et -O- écrit le corps de la réponse sur la sortie standard ; le tube transmet ensuite ce corps à head, qui n’en affiche que les premières lignes. L’URL utilise le nom du Service healthy-web, que le DNS du cluster résout à l’intérieur de l’espace de noms.
kubectl patch deployment healthy-web -n practice-health --type='json' -p='[{"op":"replace","path":"/spec/template/spec/containers/0/readinessProbe/httpGet/path","value":"/"}]'
kubectl rollout status deployment/healthy-web -n practice-health --timeout=60s
kubectl run health-client -n practice-health --image=busybox:1.36 --image-pull-policy=IfNotPresent --restart=Never --rm -i -- wget -qO- http://healthy-web | head
Le client temporaire utilise le DNS du cluster. Limiter l’affichage du code HTML rend les résultats plus lisibles, tandis qu’une réponse réussie confirme que la disponibilité et le routage du Service sont cohérents.
La réponse commence par du code HTML NGINX reconnaissable :
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
L’apparition du code HTML après un déploiement réussi prouve l’ensemble du chemin : le DNS a résolu le Service, le Service a sélectionné un point de terminaison disponible et NGINX a traité la requête.
Supprimez ensuite le Pod temporaire afin de ne pas laisser de clients de diagnostic dans l’espace de noms.
Ajouter une terminaison progressive
Dans cette étape, ajoutez un hook preStop et une période de grâce avant terminaison. Le hook retarde brièvement l’arrêt afin de laisser le temps à la propagation du retrait du point de terminaison avant l’arrêt du processus.
Lisez séparément les deux opérations du correctif JSON. La première ajoute un délai de 20 secondes pour la terminaison du Pod. La seconde ajoute un hook de mise en veille de cinq secondes au conteneur d’index 0. Kubernetes démarre le hook au début de la terminaison, tandis que le délai de grâce continue de s’écouler.
kubectl patch deployment healthy-web -n practice-health --type=json -p='[
{"op":"add","path":"/spec/template/spec/terminationGracePeriodSeconds","value":20},
{"op":"add","path":"/spec/template/spec/containers/0/lifecycle","value":{"preStop":{"sleep":{"seconds":5}}}}
]'
kubectl rollout status deployment/healthy-web -n practice-health --timeout=60s
kubectl get deployment healthy-web -n practice-health -o jsonpath='grace={.spec.template.spec.terminationGracePeriodSeconds}s preStop={.spec.template.spec.containers[0].lifecycle.preStop.sleep.seconds}s{"\n"}'
Le correctif JSON ne modifie que les deux champs indiqués ; les sondes et les autres paramètres du conteneur restent donc inchangés. La terminaison progressive complète la disponibilité : l’une contrôle l’accès au trafic, tandis que l’autre laisse à Kubernetes le temps de retirer le Pod du trafic avant la fin de l’arrêt.
La sortie JSONPath finale doit être grace=20s preStop=5s. Le hook de cinq secondes tient dans le délai de 20 secondes, ce qui laisse à NGINX le temps de s’arrêter normalement.
Le déploiement peut rester momentanément bloqué sur des messages tels que 1 old replicas are pending termination, car le hook preStop ajoute volontairement cinq secondes à l’arrêt. La sortie finale reste :
deployment "healthy-web" successfully rolled out
grace=20s preStop=5s
Résumé
Vous avez relié les sondes de démarrage, de disponibilité et de vivacité aux comportements de Kubernetes, observé qu’un échec de disponibilité retire les points de terminaison sans arrêter les conteneurs, rétabli le trafic et ajouté une terminaison progressive. Ces mécanismes rendent l’état de santé exploitable, plutôt que simplement visible.


