
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.
Prérequis
Section intitulée « Prérequis »- Un cluster Kubernetes fonctionnel (kubeadm, lab ou playground)
- Accès SSH aux nœuds (control plane et workers)
- Connaissances de base sur l’architecture d’un cluster Kubernetes
- Familiarité avec le control plane et les worker nodes
Méthodologie de diagnostic cluster
Section intitulée « Méthodologie de diagnostic cluster »Face à une panne d’infrastructure, appliquez cette séquence systématique :
- É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)
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é systématiquement sur toutes les distributions. À défaut, utilisez les logs du kubelet (journalctl -u kubelet) et les outils natifs du runtime (ex: ctr pour containerd).
Les ports critiques d’un cluster Kubernetes :
| Port | Composant | Rôle |
|---|---|---|
| 6443 | kube-apiserver | Entrée principale de l’API |
| 2379 | etcd (client) | Requêtes lecture/écriture |
| 2380 | etcd (peer) | Réplication entre membres |
| 10250 | kubelet | API kubelet (métriques, exec) |
| 10256 | kube-proxy | Health check |
| 10257 | kube-controller-manager | Health check |
| 10259 | kube-scheduler | Health check |
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 »# É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 »# Depuis le nœud control planeETCDCTL_API=3 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 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_API=3 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 \ member list -w tablePannes courantes etcd
Section intitulée « Pannes courantes etcd »| 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 »Quand etcd signale database space exceeded :
# Récupérer la révision actuellerev=$(ETCDCTL_API=3 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_API=3 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 \ compact "$rev"
# DéfragmenterETCDCTL_API=3 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 \ 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 snapshotETCDCTL_API=3 etcdctl 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=etcdSection 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 progressivement évincés (après le pod-eviction-timeout, par défaut 5 minutes).
Diagnostic d’un nœud NotReady
Section intitulée « Diagnostic d’un nœud NotReady »# Identifier le nœud en écheckubectl get nodes# NAME STATUS ROLES AGE VERSION# worker-1 NotReady <none> 10d v1.30.2
# 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 ? |
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 »# 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 »# 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 kubeletSection 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, Cilium…) est responsable du réseau entre Pods. S’il ne fonctionne pas, les Pods ne peuvent pas communiquer 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 pour le routage des Services. Selon la configuration du cluster, il fonctionne en mode iptables, ipvs (déprécié depuis v1.35), ou nftables. Sans lui, les Services ClusterIP et NodePort ne fonctionnent pas.
# 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.36 --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 endpoints -n kube-system 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 »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 snapshotETCDCTL_API=3 etcdctl 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 »Diagnostic rapide du cluster
Section intitulée « Diagnostic rapide du cluster »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 »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 »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 »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