Aller au contenu
Conteneurs & Orchestration medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Probes Kubernetes : liveness, readiness, startup sans faux positifs

17 min de lecture

logo kubernetes

Une probe mal configurée peut provoquer plus d’indisponibilité que l’absence de probe. Ce guide vous apprend à choisir la bonne probe, à dimensionner ses paramètres, et à éviter les pièges qui transforment un healthcheck en source de pannes.

  • La différence réelle entre liveness, readiness et startup
  • Quand utiliser (et quand éviter) chaque type de probe
  • Comment dimensionner les paramètres sans faux positifs
  • Les anti-patterns qui causent des redémarrages en boucle
  • Comment diagnostiquer une probe qui échoue

Les probes (sondes) permettent à Kubernetes de surveiller l’état de vos conteneurs et d’agir en conséquence. Par défaut, Kubernetes considère qu’un conteneur est “en marche” tant que son processus principal tourne, même si l’application est bloquée ou incapable de traiter des requêtes.

Les probes comblent ce manque de signal applicatif en donnant au kubelet des indicateurs concrets sur l’état réel de l’application.

Kubernetes propose trois types de probes, chacune avec un objectif distinct :

ProbeQuestion poséeAction si échec
startupProbe”Le conteneur a-t-il fini de démarrer ?”Redémarrage du conteneur
livenessProbe”Le conteneur est-il bloqué et irrécupérable ?”Redémarrage du conteneur
readinessProbe”Le conteneur peut-il recevoir du trafic maintenant ?”Retrait des endpoints du Service

La startupProbe est conçue pour les applications qui ont besoin d’un temps de démarrage important. Tant qu’elle n’a pas réussi, Kubernetes n’exécute pas les autres probes.

Cas d’usage :

  • Application Java chargeant de nombreuses dépendances
  • Base de données qui charge des données volumineuses en mémoire
  • Application legacy avec initialisation complexe
startupProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 30 # 30 × 5s = 150s max pour démarrer

La livenessProbe vérifie si le conteneur est irrémédiablement bloqué et doit être redémarré. Elle répond à la question : “faut-il tuer ce conteneur ?”

Cas d’usage :

  • Deadlock applicatif
  • Boucle infinie
  • Thread principal suspendu
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
timeoutSeconds: 5
failureThreshold: 3

La readinessProbe indique si le conteneur peut traiter des requêtes maintenant. Tant qu’elle échoue, le Pod est retiré des endpoints des Services et ne reçoit plus de trafic.

Cas d’usage :

  • API qui doit établir une connexion à une base de données
  • Application qui charge des fichiers de configuration
  • Service qui attend une dépendance externe
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3

L’ordre d’exécution n’est pas linéaire. Voici comment Kubernetes les orchestre :

Probes Kubernetes

  1. Au démarrage du conteneur

    Si une startupProbe est définie, elle prend le contrôle. Les autres probes sont désactivées jusqu’à sa réussite.

  2. Après réussite de la startup probe

    La livenessProbe et la readinessProbe s’exécutent en parallèle, chacune selon sa propre logique et ses propres paramètres.

  3. En fonctionnement normal

    • La readinessProbe contrôle l’inclusion dans les endpoints
    • La livenessProbe surveille les blocages irréversibles

Une liveness probe n’est pas toujours nécessaire. Kubernetes rappelle que si votre application sait déjà crasher proprement en cas d’erreur, le kubelet appliquera la politique de redémarrage (restartPolicy) sans avoir besoin d’une liveness probe.

Situations où la liveness est inutile ou dangereuse

Section intitulée « Situations où la liveness est inutile ou dangereuse »
SituationPourquoi éviter la liveness
L’application crashe d’elle-même en cas de panneLe restartPolicy suffit
Le check est coûteux ou instableRisque de faux positifs
Le check dépend d’un service externeUn problème externe provoquera des redémarrages
L’application est stateful et sensible aux redémarragesPerte de données ou d’état

C’est l’erreur la plus fréquente : utiliser le même endpoint pour les deux probes sans réflexion.

ProbeQuestionCe qu’elle doit tester
readinessProbe”Puis-je traiter une requête maintenant ?”État fonctionnel complet (base de données connectée, cache chargé, dépendances OK)
livenessProbe”Suis-je irrémédiablement bloqué ?”État interne minimal (processus vivant, pas de deadlock)
# Readiness : vérifie que l'API peut vraiment répondre
readinessProbe:
httpGet:
path: /ready # Teste la connexion DB, le cache, etc.
port: 8080
periodSeconds: 10
failureThreshold: 3
# Liveness : vérifie seulement que le processus n'est pas bloqué
livenessProbe:
httpGet:
path: /healthz # Check léger, local, rapide
port: 8080
periodSeconds: 20
failureThreshold: 5 # Plus tolérant que readiness

Kubernetes propose quatre méthodes pour vérifier l’état d’un conteneur :

Effectue une requête HTTP sur un chemin spécifié. Réussit si le code de réponse est entre 200 et 399.

livenessProbe:
httpGet:
path: /healthz
port: http # Utilise un port nommé
periodSeconds: 10

Cas d’usage : Applications web, API REST.

Tente d’établir une connexion TCP sur le port spécifié. Réussit si le port est ouvert.

readinessProbe:
tcpSocket:
port: 3306
periodSeconds: 10

Cas d’usage : Bases de données, services TCP (MySQL, Redis, PostgreSQL).

Exécute une commande dans le conteneur. Réussit si le code de retour est 0.

startupProbe:
exec:
command:
- cat
- /app/ready
periodSeconds: 5

Cas d’usage : Vérifications personnalisées, présence d’un fichier.

Teste directement un service gRPC via le protocole standard de health checking. Disponible nativement depuis Kubernetes v1.23.

readinessProbe:
grpc:
port: 50051
service: myapp.v1.Health
periodSeconds: 10

Cas d’usage : Services exposant une interface gRPC.

Pour les probes HTTP, vous pouvez ajouter des en-têtes personnalisés :

readinessProbe:
httpGet:
path: /ready
port: 8080
httpHeaders:
- name: X-Probe-Type
value: readiness

Cas d’usage :

  • Distinguer les types de checks côté application
  • Satisfaire un reverse proxy interne
  • Ajouter des métadonnées pour l’observabilité
MéthodeProtocoleCas d’usageCoût
HTTPGetHTTP(S)Applications web, APIFaible
TCPSocketTCPBases de données, services TCPTrès faible
ExecCommandeVérifications personnaliséesÉlevé
gRPCgRPCServices gRPCFaible
ParamètreDéfautDescription
initialDelaySeconds0Délai avant la première exécution
periodSeconds10Intervalle entre chaque check
timeoutSeconds1Durée maximale d’un check
failureThreshold3Nombre d’échecs avant action
successThreshold1Nombre de succès pour revenir OK (readiness uniquement)
terminationGracePeriodSecondsDélai de grâce spécifique à la probe

Pour une meilleure lisibilité, référencez les ports par leur nom :

spec:
containers:
- name: app
image: myapp:1.0
ports:
- name: http
containerPort: 8080
- name: metrics
containerPort: 9090
livenessProbe:
httpGet:
path: /healthz
port: http # Référence le port nommé
readinessProbe:
httpGet:
path: /ready
port: http
  1. Mesurer le temps de démarrage réel

    Lancez votre application et mesurez le temps jusqu’à ce qu’elle soit prête. Ajoutez une marge de 20-30%.

  2. Définir la startup probe

    failureThreshold × periodSeconds doit être supérieur au temps de démarrage maximal.

  3. Configurer la readiness probe

    Plus réactive que la liveness. periodSeconds court (5-10s), failureThreshold modéré (3).

  4. Configurer la liveness probe

    Plus tolérante que la readiness. periodSeconds plus long (15-30s), failureThreshold plus élevé (5+).

SituationProbe recommandéeConfiguration suggérée
Démarrage en 45sstartupProbeperiodSeconds: 5, failureThreshold: 12
API rapide, dépendante d’une DBreadinessProbeperiodSeconds: 10, failureThreshold: 3
Process susceptible de deadlocklivenessProbeperiodSeconds: 20, failureThreshold: 5
Service sensible aux pics de chargeToutestimeoutSeconds: 5, failureThreshold: 5
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 3
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: myapi:1.0
ports:
- name: http
containerPort: 8080
# Startup : pour les démarrages lents
startupProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 30 # 150s max pour démarrer
# Liveness : détection des blocages
livenessProbe:
httpGet:
path: /healthz
port: http
periodSeconds: 20
timeoutSeconds: 5
failureThreshold: 5
# Readiness : contrôle du trafic
readinessProbe:
httpGet:
path: /ready
port: http
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
successThreshold: 1
Anti-patternConséquenceSolution
Liveness qui teste une DB externeCascade de redémarrages si la DB est lenteTester uniquement l’état interne
periodSeconds trop courtCharge CPU, faux positifsMinimum 10s pour liveness
timeoutSeconds de 1s par défautFaux positifs sous chargeAugmenter à 3-5s
Probe exec avec script lourdConsommation excessive de ressourcesPréférer HTTPGet
Même endpoint pour liveness et readinessPas de distinction entre “bloqué” et “pas prêt”Endpoints différents
Oublier startupProbe sur une appli lenteRedémarrages pendant le démarrageAjouter une startup probe
Headers HTTP avec secretsExposition de credentialsEndpoint non authentifié

Une probe ne doit pas devenir elle-même la cause de l’instabilité qu’elle cherche à détecter.

Quand une readinessProbe échoue, Kubernetes retire le Pod des endpoints du Service. Le Pod existe toujours, mais ne reçoit plus de trafic.

Fenêtre de terminal
# Voir les endpoints d'un Service
kubectl get endpoints mon-service
# Résultat quand un Pod n'est pas ready
NAME ENDPOINTS AGE
mon-service 10.244.0.5:8080,10.244.0.6:8080 1h
# Le Pod avec IP 10.244.0.7 n'apparaît plus car il n'est pas Ready
Fenêtre de terminal
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP
api-1 1/1 Running 0 1h 10.244.0.5
api-2 1/1 Running 0 1h 10.244.0.6
api-3 0/1 Running 0 1h 10.244.0.7 # Pas ready

La colonne READY montre 0/1 quand la readiness probe échoue.

  1. Vérifier l’état du Pod

    Fenêtre de terminal
    kubectl get pod mon-pod -o wide
    kubectl describe pod mon-pod

    Cherchez les événements Unhealthy avec le type de probe concerné.

  2. Lire les logs du conteneur

    Fenêtre de terminal
    kubectl logs mon-pod
    kubectl logs mon-pod --previous # Si le conteneur a redémarré
  3. Tester la probe manuellement

    Fenêtre de terminal
    kubectl exec mon-pod -- curl -v http://localhost:8080/healthz
    kubectl exec mon-pod -- cat /app/ready
  4. Vérifier les événements du cluster

    Fenêtre de terminal
    kubectl get events --sort-by=.lastTimestamp | grep mon-pod
MessageCause probableSolution
Liveness probe failed: connection refusedApplication pas encore démarréeAjouter startupProbe ou augmenter initialDelaySeconds
Readiness probe failed: HTTP 503Dépendance non disponibleVérifier les connexions externes
Liveness probe failed: context deadline exceededTimeout trop courtAugmenter timeoutSeconds
Back-off restarting failed containerProbe en échec répétéVérifier les logs avec --previous
Fenêtre de terminal
kubectl describe pod api-broken
Events:
Type Reason Age Message
---- ------ ---- -------
Warning Unhealthy 30s Liveness probe failed: HTTP probe failed with statuscode: 503
Warning Unhealthy 20s Liveness probe failed: HTTP probe failed with statuscode: 503
Warning Unhealthy 10s Liveness probe failed: HTTP probe failed with statuscode: 503
Normal Killing 10s Container api failed liveness probe, will be restarted

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

7 questions
5 min.
80% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  1. startupProbe désactive les autres probes jusqu’à sa réussite
  2. livenessProbe teste l’état interne, jamais les dépendances externes
  3. readinessProbe contrôle l’inclusion dans les endpoints du Service
  4. Une liveness trop agressive provoque des CrashLoopBackOff
  5. timeoutSeconds à 1s par défaut est souvent trop court
  6. Utilisez des endpoints différents pour liveness et readiness
  7. Les probes sont configurées sur les conteneurs, pas les Pods
  8. Sans startup probe, une appli lente redémarre pendant son init
  9. Les probes exec sont plus coûteuses que HTTPGet
  10. kubectl describe pod montre les événements Unhealthy

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn