CKA - Domaine 1 : Troubleshooting de Cluster (30%)
🎯 Objectifs
À la fin de ce module, tu seras capable de :
- ✅ Appliquer une méthodologie structurée pour diagnostiquer n'importe quel problème
- ✅ Debugger des applications qui crashent ou ne démarrent pas
- ✅ Identifier et corriger une panne du control plane
- ✅ Réparer un worker node défaillant (kubelet, réseau)
- ✅ Résoudre des problèmes de connectivité réseau entre pods
- ✅ Lire et interpréter les logs des composants Kubernetes
📋 Prérequis
- Tous les autres modules CKA lus
- Bon niveau en Linux :
systemctl,journalctl,vim,ls,cat
🧭 Méthodologie générale
Le troubleshooting à l'examen est stressant parce qu'on panique. Voici une méthode qui calme.
Étape 1 : Vue d'ensemble
bash
# État de tous les pods dans tout le cluster
kubectl get pods -A
# État des nodes
kubectl get nodes
# Événements récents (triés par date)
kubectl get events -A --sort-by='.lastTimestamp' | tail -30Étape 2 : Identifier l'objet problématique
bash
# Quel pod est KO ?
kubectl get pods -A | grep -v Running | grep -v Completed
# Quel node est KO ?
kubectl get nodes | grep -v ReadyÉtape 3 : Examiner l'objet
bash
# Describe : la section "Events" en bas est la plus utile
kubectl describe pod <pod> -n <namespace>
kubectl describe node <node>Étape 4 : Lire les logs
bash
# Logs du pod
kubectl logs <pod> -n <namespace>
# Logs du conteneur qui a crashé (run précédent)
kubectl logs <pod> -n <namespace> --previous
# Logs d'un conteneur spécifique (pod multi-conteneurs)
kubectl logs <pod> -n <namespace> -c <container>
# Suivre les logs en temps réel
kubectl logs <pod> -n <namespace> -fÉtape 5 : Entrer dans le conteneur
bash
# Shell interactif dans un conteneur en cours d'exécution
kubectl exec -it <pod> -n <namespace> -- /bin/sh
# Lancer un pod de debug temporaire
kubectl run debug --image=busybox --rm -it --restart=Never -- sh
kubectl run debug --image=nicolaka/netshoot --rm -it --restart=Never -- bash💥 Application failures
Scénario 1 : Pod en CrashLoopBackOff
bash
kubectl get pod <pod>
# STATUS: CrashLoopBackOff
kubectl describe pod <pod>
# → Events : "Back-off restarting failed container"
# → Voir "Last State" pour le code de sortie
kubectl logs <pod> --previous
# → Voir pourquoi le conteneur a crashéCauses fréquentes et solutions :
| Symptôme dans les logs | Cause probable | Solution |
|---|---|---|
command not found | Mauvaise commande | Corriger command: ou args: |
permission denied | Droits insuffisants | Vérifier securityContext |
connection refused :5432 | DB non disponible | Vérifier le Service DB, les NetworkPolicies |
OOMKilled | Pas assez de mémoire | Augmenter limits.memory |
Scénario 2 : Pod en ImagePullBackOff
bash
kubectl describe pod <pod>
# Events: "Failed to pull image"Causes fréquentes :
- Nom d'image incorrect (typo, tag qui n'existe pas)
- Registry privé sans
imagePullSecrets - Pas de connectivité internet depuis le node
bash
# Vérifier le nom de l'image
kubectl get pod <pod> -o yaml | grep image
# Vérifier les imagePullSecrets
kubectl describe pod <pod> | grep -A3 "Image Pull"Scénario 3 : Pod en Pending
bash
kubectl describe pod <pod>
# Events: "0/2 nodes are available"Causes fréquentes :
- Pas assez de ressources sur les nodes → vérifier
kubectl top nodes - Taint sur tous les nodes sans toleration correspondante →
kubectl describe node | grep Taint - Node Affinity trop restrictive → vérifier les labels des nodes
- PVC non lié →
kubectl get pvc
bash
# Chercher la cause dans describe
kubectl describe pod <pod> | grep -A10 EventsScénario 4 : Le Service ne répond pas
bash
# 1. Le Service existe ?
kubectl get svc <nom>
# 2. Le selector correspond à des pods ?
kubectl get endpoints <nom>
# Si "Endpoints: <none>" → le selector ne matche aucun pod
# 3. Vérifier les labels des pods vs. le selector du Service
kubectl get pods --show-labels
kubectl describe svc <nom> | grep Selector
# 4. Tester depuis l'intérieur du cluster
kubectl run test --image=busybox --rm -it --restart=Never -- \
wget -qO- http://<service>.<namespace>.svc.cluster.local
# 5. Le pod répond sur le bon port ?
kubectl exec -it <pod> -- netstat -tlnp # ou ss -tlnp🏗️ Control Plane failures
Identifier les composants défaillants
bash
# Les composants du control plane sont des static pods
kubectl get pods -n kube-system
# Si un composant n'apparaît pas ici, chercher dans les manifests statiques
ls /etc/kubernetes/manifests/kube-apiserver down
bash
# kubectl ne fonctionne plus ! On doit travailler directement sur le node
# Vérifier le manifest statique
cat /etc/kubernetes/manifests/kube-apiserver.yaml
# Voir si le container tourne
crictl ps | grep apiserver # ou docker ps
# Logs via crictl (pas kubectl !)
crictl logs <container-id>
# Logs du kubelet (qui gère les static pods)
journalctl -u kubelet | grep apiserverCauses fréquentes :
- Flag incorrect dans le manifest (
--etcd-serversavec mauvaise IP) - Certificat expiré (
--tls-cert-filepointe vers un cert expiré) - Port déjà utilisé
bash
# Correction : éditer le manifest statique
vim /etc/kubernetes/manifests/kube-apiserver.yaml
# Kubelet recrée automatiquement le podetcd down
bash
# Vérifier l'état d'etcd
kubectl get pods -n kube-system | grep etcd
# Logs etcd
kubectl logs -n kube-system etcd-controlplane
# Tester la santé d'etcd directement
ETCDCTL_API=3 etcdctl endpoint health \
--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.keykube-scheduler / controller-manager down
bash
# Symptôme : les Pods restent en Pending indéfiniment
kubectl get pods -n kube-system | grep -E "scheduler|controller"
# Vérifier le manifest
cat /etc/kubernetes/manifests/kube-scheduler.yaml
cat /etc/kubernetes/manifests/kube-controller-manager.yaml
# Logs
kubectl logs -n kube-system kube-scheduler-controlplane
kubectl logs -n kube-system kube-controller-manager-controlplane🖥️ Worker Node failures
Node en NotReady
bash
# Identifier le node problématique
kubectl get nodes
# STATUS: NotReady
# Détails
kubectl describe node <node>
# → Section "Conditions" : chercher KubeletNotReady, MemoryPressure, DiskPressure, PIDPressure
# → Section "Events"Réparer le kubelet
bash
# Se connecter au node défaillant
ssh <node>
# Vérifier l'état du kubelet
systemctl status kubelet
# Voir les logs d'erreur
journalctl -u kubelet --no-pager | tail -50
# Erreurs communes dans les logs
# "failed to get node info" → apiserver inaccessible
# "Unable to load client CA file" → certificat manquant
# "failed to parse" → erreur de syntaxe dans un config file
# Redémarrer le kubelet
systemctl restart kubelet
systemctl enable kubelet
# Vérifier depuis le control plane
kubectl get node <node>Fichiers de configuration du kubelet
bash
# Configuration du kubelet
cat /var/lib/kubelet/config.yaml
# kubeconfig du kubelet (pour parler à l'apiserver)
cat /etc/kubernetes/kubelet.conf
# Systemd unit
cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf🌐 Network failures
DNS ne résout pas
bash
# Depuis un pod de test
kubectl run dns-test --image=busybox --rm -it --restart=Never -- \
nslookup kubernetes.default.svc.cluster.local
# Si échec, vérifier CoreDNS
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns
# Vérifier que le pod a le bon DNS configuré
kubectl exec -it <pod> -- cat /etc/resolv.conf
# "nameserver 10.96.0.10" (ou l'IP du service kube-dns)
kubectl get svc kube-dns -n kube-systemPods qui ne peuvent pas se joindre
bash
# 1. Vérifier kube-proxy
kubectl get pods -n kube-system | grep kube-proxy
kubectl logs -n kube-system <kube-proxy-pod>
# 2. Vérifier le CNI
kubectl get pods -n kube-system | grep -E "flannel|calico|weave|cilium"
# 3. Vérifier les NetworkPolicies
kubectl get networkpolicies -A
# Si une NetworkPolicy bloque, la décrire
kubectl describe networkpolicy <nom> -n <namespace>
# 4. Test direct pod-à-pod (bypasse le Service)
kubectl get pods -o wide # noter les IPs
kubectl exec -it <pod-a> -- ping <IP-pod-b>
kubectl exec -it <pod-a> -- curl http://<IP-pod-b>:<port>Service avec Endpoints vides
bash
kubectl get endpoints <service>
# Si ENDPOINTS = <none>, le selector ne matche aucun pod
# Comparer le selector du Service avec les labels des pods
kubectl describe svc <service> | grep Selector
kubectl get pods --show-labels -n <namespace>
# → Les labels des pods doivent inclure tous les labels du selector📜 Lire les logs des composants
Depuis kubectl (si kube-apiserver est Up)
bash
# Static pods du control plane
kubectl logs -n kube-system kube-apiserver-controlplane
kubectl logs -n kube-system kube-controller-manager-controlplane
kubectl logs -n kube-system kube-scheduler-controlplane
kubectl logs -n kube-system etcd-controlplane
# Sur un worker
kubectl logs -n kube-system kube-proxy-xxxxDepuis le node directement (si kubectl ne fonctionne pas)
bash
# Kubelet
journalctl -u kubelet -f
journalctl -u kubelet --since "5 minutes ago"
# Container runtime (containerd)
journalctl -u containerd -f
# Via crictl (CLI pour containerd)
crictl ps -a # tous les containers (même arrêtés)
crictl logs <container-id> # logs d'un container
crictl inspect <container-id> # détails🛠️ Techniques rapides d'examen
Forcer la suppression d'un pod bloqué
bash
kubectl delete pod <pod> --force --grace-period=0
# Raccourci avec l'alias défini en début d'examen :
# export now="--force --grace-period 0"
kubectl delete pod <pod> $nowTester une correction rapidement
bash
# Éditer un pod en place
kubectl edit pod <pod>
# Recréer depuis le YAML existant
kubectl get pod <pod> -o yaml > pod.yaml
kubectl delete pod <pod>
# modifier pod.yaml
kubectl apply -f pod.yamlAccéder à un container qui n'a pas de shell
bash
# Utiliser kubectl debug (v1.23+)
kubectl debug -it <pod> --image=busybox --target=<container>Vérifier les resources du cluster
bash
kubectl top nodes # CPU/Mémoire des nodes
kubectl top pods -A # CPU/Mémoire de tous les pods
kubectl describe node <n> # "Allocated resources" en bas📊 Tableau de diagnostic rapide
| Symptôme | Où regarder | Commande clé |
|---|---|---|
| Pod CrashLoopBackOff | Logs du pod | kubectl logs <pod> --previous |
| Pod Pending | Events du pod | kubectl describe pod <pod> |
| Pod ImagePullBackOff | Events du pod | kubectl describe pod <pod> |
| Node NotReady | Kubelet sur le node | journalctl -u kubelet |
| Service inaccessible | Endpoints | kubectl get endpoints <svc> |
| DNS cassé | CoreDNS | kubectl logs -n kube-system -l k8s-app=kube-dns |
| kubectl timeout | kube-apiserver | crictl logs <apiserver-container-id> |
| Pods en Pending (scheduler) | kube-scheduler | kubectl logs -n kube-system kube-scheduler-* |
| Rollout bloqué | controller-manager | kubectl logs -n kube-system kube-controller-manager-* |
🚀 Prochaines Étapes
- Retour au guide : CKA : Guide et Stratégie
- Entraîne-toi : utilise killercoda.com/cka pour des scénarios de troubleshooting sur des vrais clusters cassés
- Entraîne-toi : killer.sh (inclus dans l'achat de l'examen, 2 sessions de 36h) pour simuler les conditions exactes de l'examen
- Référence : kubernetes.io/docs/tasks/debug/