
Le domaine Troubleshooting pèse 30% de la CKA et inclut souvent des pannes d'infrastructure à diagnostiquer puis corriger rapidement. Ce guide cible principalement les clusters déployés avec kubeadm : control plane en static Pods, certificats gérés par kubeadm, et diagnostic local via kubelet et le runtime CRI. Il couvre le dépannage du control plane (kube-apiserver, scheduler, controller-manager), d'etcd, des nœuds workers, des certificats et des composants réseau du cluster.
Ce guide traite les pannes d'infrastructure : composants système, nœuds, certificats, etcd. Deux autres pages couvrent ce qu'il laisse de côté. Le debug d'applications prend le relais dès que le cluster est sain et que c'est un Pod ou un Service qui dysfonctionne. La méthode de diagnostic d'incident donne la démarche générale, celle qui vous dit dans lequel des deux cas vous vous trouvez avant d'ouvrir l'un ou l'autre.
Prérequis
Section intitulée « Prérequis »- Un cluster Kubernetes fonctionnel (kubeadm, lab ou playground)
- Un accès aux nœuds eux-mêmes, control plane et workers
- Connaissances de base sur l'architecture d'un cluster Kubernetes
- Familiarité avec le control plane et les worker nodes
Si vous n'avez pas de cluster accessible en SSH, un cluster kind fait
l'affaire pour presque tout ce guide : ses nœuds sont de vrais nœuds kubeadm,
avec /etc/kubernetes/manifests/, crictl, le journal du kubelet et
kubeadm certs check-expiration. Remplacez simplement ssh <nœud> par
docker exec <nom-du-nœud>.
Méthodologie de diagnostic cluster
Section intitulée « Méthodologie de diagnostic cluster »Face à une panne d'infrastructure, la tentation est de sauter directement à l'hypothèse la plus probable. C'est le meilleur moyen de perdre dix minutes sur un composant sain. La séquence ci-dessous part du plus général, le cluster répond-il, pour descendre vers le plus précis, quel fichier est mal configuré, et s'arrête dès qu'une étape renvoie une anomalie.
- État global : le cluster répond-il ? (
kubectl cluster-info,kubectl get nodes) - Composants système : les Pods kube-system tournent-ils ? (
kubectl get pods -n kube-system) - Nœuds : tous les nœuds sont-ils Ready ? (
kubectl get nodes -o wide) - Logs : que disent kubelet et les composants ? (
journalctl,kubectl logs) - Certificats : sont-ils valides ? (
kubeadm certs check-expiration) - Réseau : les composants communiquent-ils ? (
ss,curl,crictl)
Un raccourci est permis, et il fait gagner du temps. Si le symptôme désigne
clairement un worker isolé, entrez directement à l'étape 3 sur ce nœud. En
revanche, dès que kubectl ne répond plus, aucune des étapes suivantes n'est
jouable depuis votre poste : basculez immédiatement en diagnostic local sur le
control plane, où le kubelet et le runtime restent interrogeables même quand
l'API server est à terre.
Outils de diagnostic essentiels
Section intitulée « Outils de diagnostic essentiels »Avant de plonger dans les scénarios, voici les commandes clés à maîtriser pour le diagnostic d'infrastructure :
# === Depuis votre poste (si kubectl fonctionne) ===kubectl cluster-info # API server accessible ?kubectl get nodes -o wide # État de tous les nœudskubectl get pods -n kube-system -o wide # Composants du clusterkubectl get events -n kube-system --sort-by='.lastTimestamp' | tail -20
# === Depuis un nœud (en SSH) ===systemctl status kubelet # État du service kubeletjournalctl -u kubelet --no-pager --since "10 min ago" | tail -50crictl ps -a # Conteneurs (via CRI)crictl pods # Pods vus par le runtimess -tlnp | grep -E '6443|2379|10250|10256|10259|10257' # Ports critiquescrictl est l'outil le plus pratique pour inspecter les conteneurs du runtime CRI, mais il n'est pas installé partout. À défaut, appuyez-vous sur les journaux du kubelet, journalctl -u kubelet, et sur les outils natifs du runtime, ctr pour containerd.
Les ports critiques d'un cluster Kubernetes. La colonne d'écoute est celle
qu'on oublie, et elle explique la moitié des diagnostics ratés : trois de ces
ports ne sont joignables que depuis le nœud lui-même. Sonder 10257 depuis
votre poste ne prouve donc rien, pas plus qu'un curl vers 10259.
| Port | Composant | Écoute sur | Rôle |
|---|---|---|---|
| 6443 | kube-apiserver | toutes les interfaces | Entrée principale de l'API |
| 2379 | etcd (client) | boucle locale et IP du nœud | Requêtes lecture/écriture |
| 2380 | etcd (peer) | IP du nœud | Réplication entre membres |
| 10250 | kubelet | toutes les interfaces | API kubelet (métriques, exec) |
| 10256 | kube-proxy | toutes les interfaces | Health check |
| 10257 | kube-controller-manager | boucle locale seulement | Health check |
| 10259 | kube-scheduler | boucle locale seulement | Health check |
Relevé sur un nœud control plane en 1.37. Les deux ports de santé du contrôleur et du scheduler ne sont pas exposés, et c'est volontaire : c'est le kubelet, local lui aussi, qui interroge leurs sondes.
Section 1, Pannes du control plane
Section intitulée « Section 1, Pannes du control plane »Sur un cluster kubeadm, les composants du control plane tournent en static Pods : leurs manifests YAML sont dans /etc/kubernetes/manifests/. Le kubelet les surveille et les redémarre automatiquement en cas de crash. Une erreur dans un manifest = le composant ne démarre pas.
kube-apiserver ne répond pas
Section intitulée « kube-apiserver ne répond pas »C'est la panne la plus critique, sans API Server, kubectl est inutilisable.
Symptômes :
kubectlretourneThe connection to the server was refusedou timeout- Les autres composants écrivent des erreurs de connexion dans leurs logs
Diagnostic :
# 1. Vérifier si le processus tournessh <control-plane> "crictl ps | grep kube-apiserver"
# 2. Si pas de processus, vérifier le manifestssh <control-plane> "cat /etc/kubernetes/manifests/kube-apiserver.yaml | head -30"
# 3. Logs kubelet (c'est lui qui lance les static Pods)ssh <control-plane> "journalctl -u kubelet --since '5 min ago' | grep -i apiserver"
# 4. Si le conteneur existe mais crashssh <control-plane> "crictl logs \$(crictl ps -a --name kube-apiserver -q | head -1)"Causes fréquentes (CKA) :
| Cause | Symptôme dans les logs | Correction |
|---|---|---|
| Erreur dans le manifest YAML | failed to create pod dans kubelet | Corriger la syntaxe YAML dans /etc/kubernetes/manifests/kube-apiserver.yaml |
| Mauvais chemin de certificat | open /etc/kubernetes/pki/xxx: no such file | Vérifier les chemins --tls-cert-file, --tls-private-key-file |
| Port déjà utilisé | bind: address already in use | Identifier le processus sur le port 6443 (ss -tlnp | grep 6443) |
| etcd inaccessible | connection refused vers :2379 | Réparer etcd d'abord (voir section suivante) |
| Certificats expirés | certificate has expired | Renouveler avec kubeadm certs renew apiserver |
kube-scheduler ne fonctionne pas
Section intitulée « kube-scheduler ne fonctionne pas »Sans scheduler, les nouveaux Pods restent en Pending indéfiniment, ils ne sont assignés à aucun nœud.
Symptômes :
- Nouveaux Pods en état
Pending, sans événementScheduleddans les events - Peu ou pas d'événements récents liés au placement des Pods
- Le Pod
kube-schedulerest absent ou enCrashLoopBackOffdans kube-system
Diagnostic :
# Vérifier si le scheduler tournekubectl get pods -n kube-system -l component=kube-scheduler
# Logs du schedulerkubectl logs -n kube-system kube-scheduler-<node>
# Si kubectl ne fonctionne pas, aller sur le nœudssh <control-plane> "crictl ps -a | grep scheduler"ssh <control-plane> "crictl logs \$(crictl ps -a --name kube-scheduler -q | head -1)"Correction :
# Vérifier le manifestcat /etc/kubernetes/manifests/kube-scheduler.yaml
# Comparer avec la config attendue# Vérifier notamment :# - --kubeconfig=/etc/kubernetes/scheduler.conf# - image: registry.k8s.io/kube-scheduler:v1.XX.X# - ports: containerPort 10259
# Après correction du manifest, kubelet redémarre le Pod automatiquement# Vérifier :crictl ps | grep schedulerkube-controller-manager en panne
Section intitulée « kube-controller-manager en panne »Sans kube-controller-manager, de nombreuses boucles de contrôle cessent de converger : réplication, gestion des Jobs, node lifecycle, service accounts, garbage collection, etc.
Symptômes :
- Les ReplicaSets ne créent pas de nouveaux Pods
- Les Deployments ne progressent pas
- Le node lifecycle controller ne met plus à jour l'état des nœuds
- Les certificats ne sont plus automatiquement renouvelés
Diagnostic :
# Vérifier l'étatkubectl get pods -n kube-system -l component=kube-controller-manager
# Logskubectl logs -n kube-system kube-controller-manager-<node># Ou directement sur le nœud :crictl logs $(crictl ps -a --name kube-controller -q | head -1)Erreurs classiques dans les manifests :
# Vérifier le manifestcat /etc/kubernetes/manifests/kube-controller-manager.yaml
# Points à contrôler :# --kubeconfig=/etc/kubernetes/controller-manager.conf# --root-ca-file=/etc/kubernetes/pki/ca.crt# --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt# --cluster-signing-key-file=/etc/kubernetes/pki/ca.key# --service-account-private-key-file=/etc/kubernetes/pki/sa.keyMéthode générale pour les static Pods
Section intitulée « Méthode générale pour les static Pods »Pour tout composant du control plane qui ne démarre pas, appliquez cette séquence :
- Identifier : le conteneur tourne-t-il ? (
crictl ps -a | grep <composant>) - Logs conteneur,
crictl logs <container-id>, chercher l'erreur exacte - Logs kubelet,
journalctl -u kubelet | grep <composant>, le kubelet signale-t-il une erreur de manifest ? - Manifest,
cat /etc/kubernetes/manifests/<composant>.yaml, comparer avec un manifest fonctionnel - Corriger : éditer le manifest, kubelet détecte le changement et redémarre le Pod (quelques secondes)
- Valider,
crictl ps | grep <composant>puiskubectl get pods -n kube-system
Section 2, Pannes etcd
Section intitulée « Section 2, Pannes etcd »etcd est la base de données clé/valeur qui stocke tout l'état du cluster. Si etcd est en panne, l'API Server ne peut ni lire ni écrire, le cluster est paralysé.
Diagnostic etcd
Section intitulée « Diagnostic etcd »etcd tourne lui aussi en static Pod sur un cluster kubeadm, ce qui crée une dépendance circulaire au diagnostic : si etcd est mort, l'API Server l'est aussi, et kubectl logs ne répond plus. Commencez donc par la commande kubectl, mais basculez immédiatement sur crictl logs en SSH dès qu'elle échoue.
# État du Pod etcdkubectl get pods -n kube-system -l component=etcd
# Logs etcdkubectl logs -n kube-system etcd-<node>
# Ou en SSH sur le nœudcrictl logs $(crictl ps -a --name etcd -q | head -1)Vérifier la santé du cluster etcd
Section intitulée « Vérifier la santé du cluster etcd »etcdctl n'utilise aucune configuration implicite : les trois options --cacert, --cert et --key sont obligatoires, sinon la connexion TLS est refusée avant même d'atteindre la base. La variable ETCDCTL_API=3 que l'on voit encore dans beaucoup de procédures ne sert plus à rien depuis etcd 3.4 et est ignorée par le client 3.7.
Trois commandes, deux binaires. snapshot save s'adresse au serveur etcd
vivant, c'est etcdctl. snapshot status et snapshot restore travaillent sur
un fichier hors ligne, c'est etcdutl. Appeler etcdctl snapshot status
n'affiche aucune erreur : la commande sort en 0 sans rien vérifier, ce qui
fait passer un script de sauvegarde pour vert alors qu'il ne contrôle rien. endpoint health répond par un simple verdict de disponibilité, tandis que member list révèle la composition du cluster etcd, indispensable pour diagnostiquer une perte de quorum en HA.
# Depuis le nœud control planeetcdctl \ --endpoints=https://127.0.0.1:2379 \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key \ endpoint health
# Réponse attendue :# https://127.0.0.1:2379 is healthy: successfully committed proposal: took = 2.5ms
# Vérifier les membres du cluster etcdetcdctl \ --endpoints=https://127.0.0.1:2379 \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key \ member list -w tablePannes courantes etcd
Section intitulée « Pannes courantes etcd »Le message d'erreur d'etcd suffit presque toujours à trancher, à condition de savoir le lire. Deux familles dominent : le manque d'espace (etcd applique un quota et bascule en lecture seule bien avant que le disque soit plein) et les certificats, qui expirent au même rythme que le reste de ceux de kubeadm. Les cas de corruption de données sont plus rares mais imposent une restauration.
| Cause | Symptôme | Correction |
|---|---|---|
| Espace disque plein | mvcc: database space exceeded | Compacter et défragmenter (voir ci-dessous) |
| Certificats expirés | certificate has expired or is not yet valid | kubeadm certs renew etcd-server |
| Données corrompues | wal: crc mismatch ou crash en boucle | Restaurer depuis un snapshot |
| Perte de quorum (HA) | etcdserver: no leader | Restaurer un membre ou le cluster complet |
| Mauvais data-dir | open /var/lib/etcd/: permission denied | Corriger les permissions ou le chemin dans le manifest |
Compactage et défragmentation
Section intitulée « Compactage et défragmentation »etcd conserve l'historique de toutes les révisions de chaque clé. Le compactage supprime les révisions antérieures à celle que vous indiquez : l'opération est irréversible, les anciennes versions ne sont plus consultables. Il ne rend toutefois pas l'espace au système de fichiers, c'est le rôle de la défragmentation, qui réécrit le fichier de base. Cette seconde étape bloque brièvement les écritures, à lancer membre par membre sur un cluster HA.
Quand etcd signale database space exceeded :
# Récupérer la révision actuellerev=$(etcdctl \ --endpoints=https://127.0.0.1:2379 \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key \ endpoint status --write-out="json" | jq '.[0].Status.header.revision')
# Compacteretcdctl \ --endpoints=https://127.0.0.1:2379 \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key \ compact "$rev"
# Défragmenteretcdctl \ --endpoints=https://127.0.0.1:2379 \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key \ defragRestauration depuis un snapshot
Section intitulée « Restauration depuis un snapshot »Si etcd est irrécupérable, restaurez depuis un snapshot (voir le guide Sauvegarder et restaurer Kubernetes pour la procédure complète).
La procédure ci-dessous correspond au cas le plus fréquent en lab ou en CKA : cluster kubeadm avec un seul control plane. Sur un cluster HA, la restauration etcd dépend de la topologie, des membres et du quorum, et doit être traitée séparément.
# Arrêter etcd (renommer le manifest pour que kubelet l'arrête)mv /etc/kubernetes/manifests/etcd.yaml /etc/kubernetes/manifests/etcd.yaml.bak
# Supprimer l'ancien data-dirrm -rf /var/lib/etcd
# Restaurer depuis le snapshot, avec etcdutletcdutl snapshot restore /backup/etcd-snapshot.db \ --data-dir=/var/lib/etcd
# Remettre le manifest en placemv /etc/kubernetes/manifests/etcd.yaml.bak /etc/kubernetes/manifests/etcd.yaml
# Attendre que kubelet redémarre etcd, puis vérifiercrictl ps | grep etcdkubectl get pods -n kube-system -l component=etcdC'est l'exercice qui revient le plus souvent à l'examen, et il se joue sur un
détail : etcdctl n'a aucune configuration implicite. Les trois options
--cacert, --cert et --key sont obligatoires à chaque appel, et leurs
chemins par défaut sur un cluster kubeadm sont dans /etc/kubernetes/pki/etcd/.
Un candidat qui doit les chercher le jour J perd la moitié du temps alloué.
Section 3, Pannes des worker nodes
Section intitulée « Section 3, Pannes des worker nodes »Un nœud qui passe en NotReady ne reçoit plus de nouveaux Pods, et les Pods
existants sont évincés au bout de cinq minutes. Ce délai n'est plus réglé par
un drapeau du contrôleur : il vient d'une tolérance posée automatiquement sur
chaque Pod à sa création. Vous pouvez la lire sur n'importe lequel :
kubectl get pod <pod> -o jsonpath='{.spec.tolerations}'node.kubernetes.io/not-ready = 300s (NoExecute)node.kubernetes.io/unreachable = 300s (NoExecute)La nuance est utile en pratique : puisque c'est une tolérance, elle se règle
par charge de travail. Un service qui doit basculer vite peut abaisser ses
tolerationSeconds, un traitement long peut les allonger, là où un réglage
global imposait la même valeur à tout le cluster.
Diagnostic d'un nœud NotReady
Section intitulée « Diagnostic d'un nœud NotReady »kubectl get nodes signale le symptôme, mais c'est kubectl describe node qui contient la réponse. Les conditions listées en bas de la sortie distinguent deux situations très différentes : un nœud à court de ressources (MemoryPressure, DiskPressure ou PIDPressure à True) et un nœud qui ne communique plus du tout, où seule la condition Ready bascule avec un message de type kubelet stopped posting node status.
# Identifier le nœud en écheckubectl get nodes# NAME STATUS ROLES AGE VERSION# worker-1 NotReady <none> 10d v1.37.0
# Examiner les conditionskubectl describe node worker-1 | grep -A15 Conditions
# Conditions normales (tout à False sauf Ready) :# MemoryPressure False# DiskPressure False# PIDPressure False# Ready True ← Doit être Truekubelet ne démarre pas
Section intitulée « kubelet ne démarre pas »Le kubelet est le composant fondamental de chaque nœud, s'il ne tourne pas, le nœud ne communique plus avec le control plane.
# Se connecter au nœudssh worker-1
# Vérifier l'état du servicesystemctl status kubelet# Si "inactive (dead)" ou "activating (auto-restart)"
# Lire les logs pour l'erreur exactejournalctl -u kubelet --no-pager --since "5 min ago" | tail -50Causes fréquentes et corrections :
| Cause | Message dans journalctl | Correction |
|---|---|---|
| kubelet arrêté | Active: inactive (dead) | systemctl start kubelet |
| Crash en boucle | code=exited, status=1/FAILURE | Lire le message d'erreur exact dans les logs |
| Mauvaise config | failed to load kubelet config | Vérifier /var/lib/kubelet/config.yaml |
| Container runtime down | failed to get sandbox image ou CRI connection error | systemctl status containerd puis systemctl restart containerd |
| Certificat expiré | certificate has expired | Renouveler le certificat kubelet (voir section certificats) |
| Mauvais serveur API | dial tcp <ip>:6443: connect: connection refused | Vérifier /etc/kubernetes/kubelet.conf, l'URL du serveur API est-elle correcte ? |
Les pannes de kubelet posées à l'examen sont toujours subtiles : un chemin
de configuration modifié d'un caractère, un drapeau inconnu, un runtime arrêté.
Aucune ne se devine, toutes se lisent. La séquence qui les résout ne change
jamais : systemctl status kubelet pour savoir si le service tient, journalctl -u kubelet pour l'erreur exacte, la correction, puis systemctl restart kubelet. Résistez à l'envie de redémarrer avant d'avoir lu : un kubelet qui
repart sans que la cause soit traitée retombe quarante secondes plus tard.
Container runtime (containerd) en panne
Section intitulée « Container runtime (containerd) en panne »Le kubelet a besoin d'un container runtime fonctionnel. Si containerd (ou CRI-O) est arrêté, aucun Pod ne peut démarrer.
# Vérifier containerdsystemctl status containerd
# Si arrêté :systemctl start containerdsystemctl enable containerd
# Vérifier que le kubelet se reconnectesystemctl restart kubeletjournalctl -u kubelet --since "1 min ago" | grep -i "connected"Pression sur les ressources (MemoryPressure, DiskPressure, PIDPressure)
Section intitulée « Pression sur les ressources (MemoryPressure, DiskPressure, PIDPressure) »Quand un nœud manque de ressources, le kubelet place des conditions qui déclenchent l'éviction des Pods.
# Vérifier les conditions du nœudkubectl describe node <node> | grep -A5 Conditions
# Sur le nœud : diagnostic des ressourcesdf -h /var/lib/kubelet # Espace disquefree -m # Mémoire disponiblecat /proc/sys/kernel/pid_max # Limite PIDls /proc | grep -c '^[0-9]' # Nombre de processus actifsLes conditions MemoryPressure, DiskPressure et PIDPressure sont dérivées de signaux calculés par le kubelet. Les valeurs exactes dépendent de sa configuration. Par défaut sur Linux, Kubernetes applique notamment memory.available<100Mi, nodefs.available<10% et imagefs.available<15%.
| Condition | Indication | Remarque |
|---|---|---|
| MemoryPressure | Mémoire réellement disponible insuffisante | Le kubelet utilise ses propres signaux, pas uniquement free -m |
| DiskPressure | Pression sur nodefs, imagefs ou containerfs | Pas seulement /var/lib/kubelet |
| PIDPressure | Plus assez de PID disponibles | Dépend des seuils configurés du nœud |
Correction :
# DiskPressure : libérer de l'espacecrictl rmi --prune # Supprimer les images inutiliséesjournalctl --vacuum-size=500M # Nettoyer les logs
# MemoryPressure : identifier les processus gourmandsps aux --sort=-%mem | head -10# Si un processus hors-Kubernetes consomme trop, l'arrêter
# Après nettoyage, le kubelet réévalue périodiquement les signaux d'éviction# selon son housekeeping-interval (10 secondes par défaut)Section 4, Certificats
Section intitulée « Section 4, Certificats »Un cluster kubeadm utilise des dizaines de certificats TLS pour sécuriser les communications entre composants. Sur un cluster géré par kubeadm, les certificats clients générés par kubeadm expirent en général après 1 an. Leur expiration rend le cluster inutilisable.
Vérifier l'expiration des certificats
Section intitulée « Vérifier l'expiration des certificats »kubeadm certs check-expiration liste tous les certificats gérés par kubeadm, avec leur date d'expiration et le temps restant. La colonne RESIDUAL TIME est celle à surveiller : c'est le seul indicateur qui anticipe la panne, puisqu'un certificat expiré ne prévient pas avant de bloquer net les communications. La vérification par openssl sert de recours quand kubeadm n'est pas sur la machine.
# Commande kubeadm (la plus simple)kubeadm certs check-expiration
# Résultat type :# CERTIFICATE EXPIRES RESIDUAL TIME# admin.conf Mar 25, 2027 08:30 UTC 364d# apiserver Mar 25, 2027 08:30 UTC 364d# apiserver-etcd-client Mar 25, 2027 08:30 UTC 364d# apiserver-kubelet-client Mar 25, 2027 08:30 UTC 364d# ...# etcd-server Mar 25, 2027 08:30 UTC 364d
# Vérification manuelle d'un certificat spécifiqueopenssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates -subject# notBefore=Mar 25 08:30:00 2026 GMT# notAfter=Mar 25 08:30:00 2027 GMTRenouveler les certificats
Section intitulée « Renouveler les certificats »Le renouvellement seul ne suffit pas : les composants du control plane chargent leurs certificats au démarrage et continuent d'utiliser les anciens jusqu'à leur redémarrage. D'où la manipulation qui suit le renew, sortir puis remettre chaque manifest du répertoire surveillé par le kubelet, ce qui force la recréation du static Pod. Pensez également à recopier admin.conf dans votre ~/.kube/config, sinon kubectl continue de présenter un certificat périmé.
# Renouveler TOUS les certificatskubeadm certs renew all
# Ou renouveler un certificat spécifiquekubeadm certs renew apiserverkubeadm certs renew etcd-serverkubeadm certs renew apiserver-etcd-client
# Après renouvellement, redémarrer les composants du control plane# Méthode : déplacer puis remettre les manifestscd /etc/kubernetes/manifestsmv kube-apiserver.yaml /tmp/ && sleep 5 && mv /tmp/kube-apiserver.yaml .mv kube-controller-manager.yaml /tmp/ && sleep 5 && mv /tmp/kube-controller-manager.yaml .mv kube-scheduler.yaml /tmp/ && sleep 5 && mv /tmp/kube-scheduler.yaml .mv etcd.yaml /tmp/ && sleep 5 && mv /tmp/etcd.yaml .
# Vérifier que tout redémarrekubectl get pods -n kube-systemCertificat kubelet expiré sur un worker
Section intitulée « Certificat kubelet expiré sur un worker »Si un worker node perd la connexion à cause d'un certificat kubelet expiré :
# Sur le worker : vérifier le certificatopenssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -dates
# Si expiré et la rotation automatique est activée :# La rotation se fait automatiquement si le kubelet a le flag :# --rotate-certificates=true (dans /var/lib/kubelet/config.yaml)
# Vérifier la configgrep rotateCertificates /var/lib/kubelet/config.yaml# rotateCertificates: true ← doit être présent
# Si la rotation automatique ne permet plus la récupération :# 1. Vérifier d'abord le bootstrap kubeconfig et la configuration de rotationcat /etc/kubernetes/bootstrap-kubelet.conf# 2. Sur le control plane, créer un nouveau tokenkubeadm token create --print-join-command# 3. Sur le worker, arrêter le kubelet et supprimer l'ancien certificatsystemctl stop kubeletrm /var/lib/kubelet/pki/kubelet-client-current.pem# 4. Mettre à jour le bootstrap-kubeconfig avec le nouveau token, puis redémarrersystemctl start kubeletTrois commandes suffisent à traiter tout ce que l'examen pose sur les
certificats, et la troisième est celle qu'on oublie :
kubeadm certs check-expiration pour constater,
kubeadm certs renew all pour renouveler, puis le redémarrage des static
Pods, sans lequel les composants continuent d'utiliser les anciens certificats
chargés en mémoire. Un renouvellement qui ne change rien à l'état du cluster est
presque toujours un redémarrage oublié.
Section 5, Réseau et connectivité cluster
Section intitulée « Section 5, Réseau et connectivité cluster »Les problèmes réseau au niveau cluster empêchent la communication entre les composants, et sont souvent les plus difficiles à diagnostiquer.
CNI (Container Network Interface) en panne
Section intitulée « CNI (Container Network Interface) en panne »Le plugin CNI, Calico, Flannel ou Cilium, porte le réseau entre Pods. S'il ne fonctionne pas, les Pods ne communiquent plus et les nœuds nouvellement ajoutés restent en NotReady.
# Vérifier les Pods CNIkubectl get pods -n kube-system | grep -iE 'calico|flannel|cilium|weave'
# Si des Pods CNI sont en CrashLoopBackOffkubectl logs -n kube-system <cni-pod> --previous
# Vérifier la config CNI sur un nœudls /etc/cni/net.d/cat /etc/cni/net.d/*.conflistSymptômes d'un CNI défaillant :
| Symptôme | Diagnostic | Correction |
|---|---|---|
Nœuds NotReady + NetworkUnavailable: True | kubectl describe node | Réinstaller le CNI ou vérifier ses Pods |
| Pods ne communiquent pas entre nœuds | kubectl exec pod-A -- ping <pod-B-IP> | Vérifier les logs CNI et les routes réseau |
Pods bloqués en ContainerCreating | kubectl describe pod → erreur networkPlugin | Vérifier /etc/cni/net.d/ et le binaire CNI dans /opt/cni/bin/ |
kube-proxy défaillant
Section intitulée « kube-proxy défaillant »kube-proxy gère les règles réseau qui routent les Services. Sans lui, ni
ClusterIP ni NodePort ne répondent. Trois modes existent, et savoir lequel tourne
change les commandes de diagnostic : iptables reste le mode par défaut,
nftables est stable depuis la 1.33 et devient la cible recommandée sur les
noyaux récents, et ipvs est déprécié depuis la 1.35. Un cluster encore
en ipvs n'est pas en panne, mais il est sur un chemin qui se ferme : la migration
se prépare maintenant, pas le jour du retrait.
# Vérifier le DaemonSet kube-proxykubectl get ds -n kube-system kube-proxykubectl get pods -n kube-system -l k8s-app=kube-proxy
# Logskubectl logs -n kube-system -l k8s-app=kube-proxy --tail=30
# Identifier le mode de fonctionnementkubectl logs -n kube-system -l k8s-app=kube-proxy | grep "Using .* Proxier"
# Vérifier les règles selon le mode (iptables par défaut sur kubeadm)ssh <node> "iptables -t nat -L KUBE-SERVICES | head -20"CoreDNS ne résout pas
Section intitulée « CoreDNS ne résout pas »CoreDNS assure la résolution DNS interne du cluster. S'il est en panne, les Pods ne peuvent plus résoudre les noms de Services.
# Vérifier les Pods CoreDNSkubectl get pods -n kube-system -l k8s-app=kube-dns
# Tester la résolution depuis un Podkubectl run dnstest --rm -it --image=busybox:1.37@sha256:9db7b59979c38555a39def84a31fb98b5296952f9e3afd4f6f11f05b07adfab0 --restart=Never -- nslookup kubernetes.default
# Si la résolution échoue, vérifier les logs CoreDNSkubectl logs -n kube-system -l k8s-app=kube-dns --tail=30
# Vérifier le Service kube-dnskubectl get svc -n kube-system kube-dnskubectl get endpointslice -n kube-system -l kubernetes.io/service-name=kube-dnsPour le DNS, le bon ordre de vérification est : Pod CoreDNS → logs → Service kube-dns → endpoints → test nslookup depuis un Pod. Cette approche méthodique permet d'isoler rapidement l'origine du problème.
Section 6, Exercices CKA type examen
Section intitulée « Section 6, Exercices CKA type examen »Les quatre exercices ci-dessous reproduisent des pannes réellement posées en examen, avec la commande qui les provoque. Cassez le cluster volontairement, puis diagnostiquez sans regarder la solution : c'est le seul moyen de vérifier que la méthode est acquise et pas seulement lue. Travaillez sur un cluster de lab jetable, jamais sur un cluster utilisé par quelqu'un d'autre. Les durées indiquées correspondent au temps alloué le jour de l'examen.
Exercice 1 : API Server en panne (5 min)
Section intitulée « Exercice 1 : API Server en panne (5 min) »Le kube-apiserver ne démarre pas. Diagnostiquez et corrigez.
Simulation :
# Sur le control plane (en SSH)# Introduire une erreur dans le manifestsudo sed -i 's/--etcd-servers=https:\/\/127.0.0.1:2379/--etcd-servers=https:\/\/127.0.0.1:2399/' \ /etc/kubernetes/manifests/kube-apiserver.yamlSolution
# kubectl ne fonctionne pluskubectl get nodes# The connection to the server was refused
# Aller sur le nœud control plane en SSHssh control-plane
# Vérifier si le conteneur tournecrictl ps -a | grep apiserver# Le conteneur est en état "Exited"
# Lire les logs du conteneurcrictl logs $(crictl ps -a --name kube-apiserver -q | head -1)# "dial tcp 127.0.0.1:2399: connect: connection refused"# → Le port etcd est mauvais (2399 au lieu de 2379)
# Corriger le manifestsudo vi /etc/kubernetes/manifests/kube-apiserver.yaml# Changer --etcd-servers=https://127.0.0.1:2399# en --etcd-servers=https://127.0.0.1:2379
# Kubelet détecte le changement et redémarre le Pod# Patienter ~30 secondescrictl ps | grep apiserver# Le conteneur est en state "Running"
# Vérifierkubectl get nodes# Les nœuds réapparaissentExercice 2 : kubelet cassé sur un worker (5 min)
Section intitulée « Exercice 2 : kubelet cassé sur un worker (5 min) »Un nœud worker est NotReady. Identifiez la cause et corrigez.
Simulation :
# Sur le worker (en SSH)sudo sed -i 's|/var/lib/kubelet/config.yaml|/var/lib/kubelet/config-bad.yaml|' \ /etc/systemd/system/kubelet.service.d/10-kubeadm.confsudo systemctl daemon-reloadsudo systemctl restart kubeletSolution
# Sur le control planekubectl get nodes# worker-1 NotReady
# Se connecter au workerssh worker-1
# Vérifier kubeletsystemctl status kubelet# Active: activating (auto-restart)
# Lire les logsjournalctl -u kubelet --since "2 min ago" | tail -20# "failed to load kubelet config file, error: failed to read kubelet# config file /var/lib/kubelet/config-bad.yaml, error: open ... no such file"
# Le fichier de config est mauvais, vérifier le servicecat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf# --config=/var/lib/kubelet/config-bad.yaml ← erreur
# Corrigersudo sed -i 's|config-bad.yaml|config.yaml|' \ /etc/systemd/system/kubelet.service.d/10-kubeadm.confsudo systemctl daemon-reloadsudo systemctl restart kubelet
# Vérifiersystemctl status kubelet# Active: running
# Sur le control plane (après ~40 secondes)kubectl get nodes# worker-1 ReadyExercice 3 : Certificats expirés (3 min)
Section intitulée « Exercice 3 : Certificats expirés (3 min) »Le cluster ne répond plus, les certificats sont expirés.
Solution (procédure)
# Vérifier l'expirationkubeadm certs check-expiration# CERTIFICATE EXPIRES RESIDUAL TIME# apiserver Mar 25, 2025 08:30 UTC EXPIRED
# Renouveler tous les certificatskubeadm certs renew all# certificate embedded in admin.conf renewed# certificate apiserver renewed# ...
# Redémarrer les composants du control planecrictl pods --name kube-apiserver -q | xargs crictl rmpcrictl pods --name kube-controller -q | xargs crictl rmpcrictl pods --name kube-scheduler -q | xargs crictl rmpcrictl pods --name etcd -q | xargs crictl rmp# Kubelet les redémarre automatiquement
# Mettre à jour le kubeconfig admincp /etc/kubernetes/admin.conf ~/.kube/config
# Vérifierkubectl get nodesExercice 4 : Restauration etcd (5 min)
Section intitulée « Exercice 4 : Restauration etcd (5 min) »Le cluster est dans un état incohérent, vous devez restaurer depuis un snapshot etcd.
Solution (procédure)
# 1. Arrêter etcdmv /etc/kubernetes/manifests/etcd.yaml /tmp/etcd.yaml
# 2. Attendre que le conteneur s'arrêtecrictl ps | grep etcd # Doit être vide après ~10 secondes
# 3. Sauvegarder l'ancien data-dirmv /var/lib/etcd /var/lib/etcd.bak
# 4. Restaurer depuis le snapshot, avec etcdutletcdutl snapshot restore /backup/etcd-snapshot.db \ --data-dir=/var/lib/etcd
# 5. Remettre le manifestmv /tmp/etcd.yaml /etc/kubernetes/manifests/etcd.yaml
# 6. Attendre le redémarragesleep 15crictl ps | grep etcd
# 7. Vérifier l'état du clusterkubectl get nodeskubectl get pods -AChecklist récapitulative
Section intitulée « Checklist récapitulative »Ces quatre blocs condensent le guide en commandes prêtes à taper, regroupées par symptôme de départ. Mémorisez-les dans cet ordre : pendant l'incident, il ne faut plus avoir à réfléchir à la méthode.
Diagnostic rapide du cluster
Section intitulée « Diagnostic rapide du cluster »Ces quatre commandes se lancent depuis votre poste et suffisent à localiser la panne au niveau du cluster, du nœud ou d'un composant précis.
kubectl cluster-info # API accessible ?kubectl get nodes -o wide # Nœuds Ready ?kubectl get pods -n kube-system # Composants OK ?kubectl get events -n kube-system --sort-by='.lastTimestamp' | tail -10Control plane en panne
Section intitulée « Control plane en panne »À sortir dès que kubectl ne répond plus : tout se fait en local sur le nœud, par le runtime et les journaux du kubelet.
ssh <control-plane>crictl ps -a | grep -E 'apiserver|scheduler|controller|etcd'journalctl -u kubelet --since "5 min ago" | grep -i errorcat /etc/kubernetes/manifests/<composant>.yaml # Vérifier syntaxeWorker node NotReady
Section intitulée « Worker node NotReady »Sur un worker, l'ordre compte : le kubelet dépend du container runtime, qui dépend des ressources disponibles. Remonter cette chaîne évite de redémarrer un service qui n'était pas en cause.
ssh <worker>systemctl status kubelet # Service actif ?journalctl -u kubelet --since "5 min ago" | tail -20 # Erreur ?systemctl status containerd # Runtime OK ?df -h && free -m # Ressources ?Certificats
Section intitulée « Certificats »Réflexe à avoir devant tout message contenant certificate has expired, quel que soit le composant qui l'émet. Le redémarrage des Pods statiques fait partie de la procédure : il n'est pas optionnel.
kubeadm certs check-expiration # Expiration ?kubeadm certs renew all # Renouveler# Puis redémarrer les static Pods du control planeÀ retenir
Section intitulée « À retenir »- Si
kubectlne répond pas : connectez-vous en SSH au control plane et utilisezcrictl+journalctl - Static Pods du control plane : manifest dans
/etc/kubernetes/manifests/, kubelet les redémarre automatiquement à toute modification - kubelet arrêté = nœud
NotReady, diagnostic avecsystemctl status kubeletpuisjournalctl -u kubelet - etcd défaillant = cluster paralysé, vérifier avec
etcdctl endpoint health, restaurer depuis un snapshot si nécessaire - Certificats kubeadm expirent après 1 an, vérifier avec
kubeadm certs check-expiration, renouveler aveckubeadm certs renew all - CNI en panne = nœuds
NotReadyavecNetworkUnavailable: True, vérifier les Pods CNI dans kube-system - Méthode systématique : état global → composants → logs → manifest/config → corriger → valider
Testez vos connaissances
Section intitulée « Testez vos connaissances »Sept questions sur ce qui sépare un diagnostic rapide d'une demi-heure
perdue : où vivent les manifestes du control plane, ce que describe node répond vraiment, et quel port se sonde depuis où.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
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
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Préparer une maintenance : La panne qu'on provoque soi-même se prépare, à l'inverse de celle qu'on vient de diagnostiquer.
- Gérer les nœuds : Sortir un nœud du service proprement, geste qui suit souvent un diagnostic de panne matérielle.
- Mettre à jour un cluster : L'opération qui casse le plus de plans de contrôle, et celle où ce diagnostic sert le plus.