Un service enregistré dans Consul et un service réellement capable de répondre à une requête sont deux choses différentes, et confondre les deux est la cause la plus fréquente d’un routage vers une instance morte. Consul ne se contente pas de savoir qui existe : il vérifie en continu qui répond, et c’est cette vérification, pas le simple enregistrement, qui fait la valeur du système.

Le catalogue : qui existe, pas qui va bien

Quand un service démarre, un agent Consul (qui tourne sur chaque nœud) l’enregistre dans le catalogue avec son adresse, son port, et des métadonnées optionnelles. Ce catalogue seul ne dit rien sur l’état de santé du service : une instance qui a planté sans se désenregistrer proprement y reste visible indéfiniment.

service {
  name = "payment-api"
  port = 8080
  check {
    http     = "http://localhost:8080/health"
    interval = "10s"
    timeout  = "2s"
  }
}

Les health checks : ce qui rend le catalogue fiable

C’est le bloc check qui transforme un simple annuaire en système de découverte fiable. Consul interroge périodiquement chaque service enregistré et retire des résultats de requête toute instance qui échoue à son check, sans jamais la supprimer du catalogue lui-même : la distinction entre « enregistré » et « en bonne santé » reste visible, ce qui aide au diagnostic (une instance critical n’est pas une instance absente).

Trois types de check existent, avec des garanties différentes. Un check http interroge un endpoint et vérifie le code de statut, ce qui confirme que le processus répond mais rien de plus. Un check script exécute une commande locale, utile pour des vérifications spécifiques (espace disque, connexion à une dépendance) mais qui s’exécute sur le nœud, pas depuis l’extérieur. Un check ttl inverse la logique : c’est le service lui-même qui doit activement confirmer sa santé à intervalle régulier, et l’absence de confirmation vaut échec, ce qui est utile pour détecter un processus qui existe encore mais ne progresse plus (un deadlock, par exemple), ce qu’un simple ping HTTP ne verrait jamais.

Le piège du health check superficiel

Un check http qui vérifie seulement GET /health retournant 200 OK codé en dur ne teste rien de réel : le processus peut répondre alors que sa dépendance critique (base de données, cache) est injoignable, et le check reste vert pendant que le service échoue silencieusement sur chaque vraie requête. Un health check qui a de la valeur vérifie ce dont le service a réellement besoin pour fonctionner, pas seulement qu’un port écoute.

# Faux health check : ne teste rien
GET /health -> toujours 200

# Health check utile : vérifie la dépendance réelle
GET /health -> 200 seulement si la connexion DB répond

L’inverse existe aussi et coûte tout autant : un check trop strict (qui échoue sur la moindre latence de dépendance non critique) retire des instances parfaitement fonctionnelles du routage, créant une pénurie artificielle de capacité pile au moment où la charge est déjà élevée.

Pourquoi Consul a besoin d’un consensus (Raft)

Les serveurs Consul (distincts des agents qui tournent sur chaque nœud applicatif) doivent s’accorder entre eux sur l’état du catalogue, y compris en cas de panne partielle du cluster. Consul utilise Raft, un algorithme de consensus qui exige qu’une majorité stricte des serveurs (un quorum) soit disponible et d’accord pour que le cluster accepte des écritures. Avec 3 serveurs Consul, le cluster tolère la perte d’un seul sans interruption ; avec 5, il en tolère deux. Un nombre pair de serveurs n’apporte aucune tolérance supplémentaire par rapport à l’impair immédiatement inférieur, tout en doublant le risque de partition en deux groupes égaux sans majorité claire : c’est pourquoi la documentation Consul recommande systématiquement un nombre impair de serveurs.

Où ça se range

Consul répond au même besoin que le service discovery au sens large, avec un mécanisme de santé actif que les Services Kubernetes natifs n’offrent pas nativement (ils routent vers ce qui est Ready, mais la définition de Ready reste à la charge de vos propres probes). Choisir entre les deux, ou les deux ensemble sur une infrastructure hybride, fait partie des décisions posées lors d’une migration Kubernetes.

À retenir

Le catalogue Consul dit qui existe, les health checks disent qui répond réellement, et confondre les deux fait router du trafic vers des instances mortes. Un check superficiel (qui teste juste qu’un port écoute) ne protège de rien ; un check trop strict retire des instances saines. Le consensus Raft impose un nombre impair de serveurs pour garantir un quorum clair en cas de panne partielle.