Introduction
Le serveur d'API Kubernetes est la porte d'entrée de votre cluster. Chaque commande kubectl, chaque contrôleur et chaque interaction entre composants passe par lui. Lorsqu'il tombe en panne, tout le plan de contrôle peut devenir inutilisable. Le dépannage du serveur d'API exige une approche systématique : identifier la version et la topologie, lire les journaux, vérifier les certificats et la configuration, puis valider la connectivité. Ce guide fournit des exemples pratiques et des commandes pour diagnostiquer et récupérer des problèmes courants du serveur d'API.
Nous nous concentrerons sur les scénarios les plus pertinents pour les développeurs, les ingénieurs DevOps et les équipes techniques de startups. L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact et vérifier le résultat. Tous les exemples utilisent des espaces réservés explicites et des commandes en lecture seule d'abord, afin que vous puissiez diagnostiquer sans perturber la production.
Inventaire de la version et de l'environnement
Avant de dépanner, rassemblez les faits essentiels. Exécutez ces commandes en lecture seule pour identifier la version de Kubernetes, la méthode de déploiement du serveur d'API et l'état des nœuds.
Identifier la version de Kubernetes et le déploiement du serveur d'API
Utilisez kubectl pour obtenir la version du serveur :
kubectl version --client
La sortie attendue inclut à la fois les versions client et serveur. Par exemple :
Client Version: v1.28.2
Server Version: v1.28.2
Si la version du serveur est vide ou si la commande expire, le serveur d'API est peut-être injoignable. Dans ce cas, vérifiez le kubeconfig et la connectivité réseau.
Déterminez comment le serveur d'API est déployé. Sur un cluster kubeadm, il s'exécute comme un pod statique géré par le kubelet. Vérifiez avec :
kubectl get pods -n kube-system | grep kube-apiserver
Sur un cluster géré (EKS, GKE, AKS), vous ne pouvez pas accéder directement au pod du serveur d'API ; vous devez plutôt vous fier aux journaux et aux métriques du fournisseur cloud.
Topologie du cluster et aperçu de la santé
Obtenez la liste des nœuds et leur état :
kubectl get nodes
Exemple de sortie :
NAME STATUS ROLES AGE VERSION
control-plane Ready control-plane 10d v1.28.2
worker-1 Ready <none> 10d v1.28.2
worker-2 NotReady <none> 10d v1.28.2
Si des nœuds sont NotReady, le serveur d'API fonctionne peut-être encore, mais des problèmes de communication avec le kubelet ou de CNI peuvent provoquer des symptômes qui ressemblent à des problèmes de serveur d'API. Vérifiez toujours l'état des nœuds en premier.
Vérifiez l'état des composants du plan de contrôle (si accessible) :
kubectl get componentstatuses
Remarque : Cette commande est obsolète et peut ne pas montrer tous les composants dans les versions plus récentes. À la place, vérifiez les pods dans kube-system :
kubectl get pods -n kube-system
Recherchez kube-apiserver, kube-controller-manager, kube-scheduler et etcd. Ils doivent tous être en état Running et ne pas être en CrashLoopBackOff.
Prérequis et accès
Assurez-vous d'avoir :
- kubectl installé et configuré.
- Des autorisations d'administrateur du cluster, ou au moins un accès en lecture à l'espace de noms kube-system et aux journaux des nœuds.
- Un accès SSH aux nœuds du plan de contrôle si le serveur d'API ne répond pas.
Chemin de configuration sûr
Lorsque le serveur d'API se comporte mal, évitez de faire des changements arbitraires. Suivez plutôt un chemin sûr et progressif.
Sauvegarder la configuration actuelle
Avant de modifier un manifeste ou une configuration du serveur d'API, sauvegardez-le. Sur un nœud du plan de contrôle, le manifeste du pod statique se trouve généralement dans /etc/kubernetes/manifests/kube-apiserver.yaml. Copiez-le :
sudo cp /etc/kubernetes/manifests/kube-apiserver.yaml /root/kube-apiserver.yaml.backup-$(date +%Y%m%d)
Sauvegardez également les journaux actuels du kubelet ou du serveur d'API pour comparaison :
sudo journalctl -u kubelet --since "1 hour ago" > /root/kubelet-before.log
Inspection en lecture seule
Vérifiez les journaux du pod du serveur d'API sans rien redémarrer :
kubectl logs -n kube-system kube-apiserver-control-plane --tail=100
Si le pod est en boucle de crash, vous devrez peut-être inspecter les journaux précédents :
kubectl logs -n kube-system kube-apiserver-control-plane --previous
Cherchez des lignes d'erreur telles que des problèmes de certificats, des échecs de connexion etcd ou des drapeaux invalides.
Changement minimal justifié
Les changements sûrs courants incluent :
- Corriger une faute de frappe dans l'URL d'un webhook d'admission.
- Renouveler un certificat expiré.
- Ajuster les limites de ressources.
Appliquez un changement à la fois. Par exemple, si le serveur d'API est OOMKilled, augmentez sa limite de mémoire dans le manifeste :
resources:
requests:
memory: "512Mi"
limits:
memory: "1Gi" # augmenté de 512Mi
Après l'édition, enregistrez le fichier. Le kubelet redémarrera automatiquement le pod.
Vérification
Vérifiez que le pod redémarre et passe à l'état Running :
kubectl get pod -n kube-system kube-apiserver-control-plane
Puis vérifiez les journaux pour les messages de démarrage réussi :
kubectl logs -n kube-system kube-apiserver-control-plane --tail=20
La sortie attendue inclut des lignes comme :
"Serving securely on [::]:6443"
Si le pod échoue à nouveau, revenez à la sauvegarde.
Vérification et diagnostics
Cette section couvre les commandes de diagnostic clés et ce qu'elles révèlent.
Santé du point de terminaison du serveur d'API
Vérifiez le point de terminaison healthz. Depuis le nœud du plan de contrôle :
curl -k https://localhost:6443/healthz
Attendu : ok
Pour une vérification plus détaillée, utilisez :
curl -k https://localhost:6443/livez?verbose
Cela renvoie une liste de vérifications et leur statut.
Depuis l'extérieur du cluster, utilisez kubectl pour vérifier :
kubectl get --raw='/readyz?verbose'
Problèmes d'authentification et d'autorisation
Si vous obtenez 403 Forbidden ou 401 Unauthorized, vérifiez le kubeconfig et les autorisations de l'utilisateur.
Affichez votre contexte actuel :
kubectl config current-context
Vérifiez si votre certificat est valide :
kubectl config view --raw -o jsonpath='{.users[0].user.client-certificate-data}' | base64 -d | openssl x509 -noout -dates
Cela affiche les dates de début et d'expiration du certificat.
Testez l'accès avec une lecture simple :
kubectl auth can-i list pods --namespace=default
Attendu : yes si autorisé.
Vérification des certificats
Les certificats du serveur d'API causent souvent des pannes. Vérifiez le certificat de service :
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates
Assurez-vous que le certificat n'est pas expiré et que les SAN incluent l'IP du plan de contrôle, le nom d'hôte et le DNS de l'équilibreur de charge.
Si vous utilisez kubeadm, vérifiez l'expiration des certificats :
kubeadm certs check-expiration
Exemple de sortie :
CERTIFICATE EXPIRES RESIDUAL TIME
apiserver Jan 01, 2025 12:00 UTC 364d
apiserver-etcd-client Jan 01, 2025 12:00 UTC 364d
...
Connectivité etcd
Le serveur d'API dépend d'etcd. Testez la connectivité depuis le plan de contrôle :
curl -k https://127.0.0.1:2379/health
Etcd peut exiger des certificats clients. Utilisez :
curl --cacert /etc/kubernetes/pki/etcd/ca.crt --cert /etc/kubernetes/pki/etcd/server.crt --key /etc/kubernetes/pki/etcd/server.key https://127.0.0.1:2379/health
Attendu : {"health":"true"}
Si les journaux du serveur d'API montrent des erreurs comme "etcdserver: request timed out", examinez la santé du cluster etcd.
Modes de défaillance et récupération
Comprendre les modes de défaillance typiques aide à accélérer la récupération.
CrashLoopBackOff du serveur d'API
Causes :
- Drapeaux manquants ou invalides dans le manifeste.
- Webhooks d'admission mal configurés.
- Ressources insuffisantes.
- Certificats expirés.
Étapes de récupération :
- Vérifiez les journaux :
kubectl logs -n kube-system kube-apiserver-control-plane --previous
- Examinez le manifeste pour les erreurs :
sudo cat /etc/kubernetes/manifests/kube-apiserver.yaml
- Validez la syntaxe YAML :
sudo python3 -c 'import yaml, sys; print(yaml.safe_load(open("/etc/kubernetes/manifests/kube-apiserver.yaml")))'
Aucune sortie ne signifie que le YAML est valide (ou ajustez la commande).
- Corrigez le problème. Par exemple, si un webhook d'admission est injoignable, retirez-le soit du drapeau
--enable-admission-plugins, soit assurez-vous que le service du webhook fonctionne.
- Le pod devrait redémarrer automatiquement. Vérifiez :
kubectl get pod -n kube-system kube-apiserver-control-plane
Serveur d'API qui ne répond pas
Si les commandes kubectl se bloquent, le serveur d'API est peut-être en panne ou injoignable.
Vérifiez si le processus est en cours d'exécution :
sudo crictl ps | grep kube-apiserver
Ou
sudo docker ps | grep kube-apiserver
S'il n'y a pas de conteneur, vérifiez l'état du kubelet :
sudo systemctl status kubelet
Consultez les journaux du kubelet :
sudo journalctl -u kubelet -n 100 --no-pager
Si le kubelet ne peut pas extraire l'image du serveur d'API, vérifiez le réseau et l'accès au registre d'images.
Certificat expiré
L'expiration du certificat du serveur d'API est une cause fréquente de panne.
Renouvelez les certificats avec kubeadm :
sudo kubeadm certs renew apiserver
Ensuite, redémarrez le serveur d'API (ou laissez le kubelet prendre en compte les changements) :
sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/
sudo mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/
Ou simplement :
sudo kill -s SIGHUP $(pidof kube-apiserver)
Vérifiez :
curl -k https://localhost:6443/healthz
Panne d'etcd
Si etcd est en panne, le serveur d'API ne peut pas persister l'état. Vérifiez la santé du cluster etcd :
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 health
Si etcd est en mauvaise santé, référez-vous aux guides de dépannage d'etcd. Ensuite, redémarrez etcd si nécessaire.
Liste de contrôle des opérations
Utilisez cette liste pour traiter méthodiquement les problèmes du serveur d'API. Chaque élément inclut une commande ou une action et le résultat attendu.
| Étape | Action | Commande / Vérification | Résultat attendu |
|---|---|---|---|
| 1 | Vérifier la version du cluster | kubectl version --client | Version du serveur connue |
| 2 | Vérifier l'état du pod du serveur d'API | kubectl get pods -n kube-system | Pod Running, pas de CrashLoop |
| 3 | Lire les journaux | kubectl logs -n kube-system kube-apiserver-<node> | Pas d'erreurs fatales |
| 4 | Tester healthz | curl -k https://localhost:6443/healthz | Renvoie ok |
| 5 | Valider les certificats | kubeadm certs check-expiration | Non expirés |
| 6 | Vérifier la connectivité etcd | curl --cacert ... https://127.0.0.1:2379/health | {"health":"true"} |
| 7 | Vérifier l'état des nœuds | kubectl get nodes | Tous les nœuds Ready |
| 8 | Confirmer l'autorisation de l'utilisateur | kubectl auth can-i list pods | yes |
| 9 | Inspecter le manifeste | cat /etc/kubernetes/manifests/kube-apiserver.yaml | Drapeaux et config valides |
| 10 | Sauvegarder avant les modifications | cp kube-apiserver.yaml backup | La sauvegarde existe |
Mettez à jour cette liste après chaque incident pour inclure les contrôles des modes de défaillance nouvellement découverts. Attribuez un propriétaire unique (par exemple, l'ingénieur SRE de garde) pour la maintenir et la réviser mensuellement.
Pièges courants et erreurs
1. Modifier le manifeste sans sauvegarde
Pourquoi cela arrive : La pression pour réparer rapidement conduit à des modifications directes.
Comment l'éviter : Copiez toujours le manifeste vers une sauvegarde horodatée avant de le modifier. Si le serveur d'API ne démarre pas, restaurez immédiatement.
2. Utiliser kubectl pour diagnostiquer lorsque le serveur d'API est en panne
Pourquoi cela arrive : Habitude ou manque de connaissance des outils au niveau du nœud.
Comment l'éviter : Si kubectl ne répond pas, passez aux outils au niveau du nœud : crictl, docker, journalctl et des commandes curl directes. Utilisez SSH pour accéder au plan de contrôle.
3. Ignorer l'expiration des certificats
Pourquoi cela arrive : Les certificats expirent rarement, donc les équipes oublient de les surveiller.
Comment l'éviter : Configurez des alertes de surveillance pour l'expiration des certificats (par exemple, en utilisant Prometheus et un cert-exporter). Exécutez régulièrement kubeadm certs check-expiration.
4. Ne pas vérifier la santé d'etcd
Pourquoi cela arrive : Les erreurs du serveur d'API pointent souvent vers lui-même, mais la cause racine peut être etcd.
Comment l'éviter : Incluez toujours les vérifications de santé d'etcd dans votre routine de diagnostic. Si etcd est en panne, le serveur d'API ne peut pas fonctionner.
5. Appliquer plusieurs modifications à la fois
Pourquoi cela arrive : Tenter de corriger plusieurs problèmes suspects simultanément.
Comment l'éviter : Faites un changement à la fois et vérifiez. Si le changement échoue, revenez en arrière. Cela isole la cause.
6. Négliger les webhooks d'admission
Pourquoi cela arrive : Des webhooks mal configurés peuvent bloquer les requêtes API, mais les journaux ne le disent pas explicitement.
Comment l'éviter : Vérifiez les journaux du serveur d'API pour les erreurs de délai d'attente du webhook ou de connexion refusée. Désactivez temporairement les webhooks suspects pour tester.
Conclusion
Le dépannage du serveur d'API Kubernetes exige une approche structurée. Commencez par des observations en lecture seule, rassemblez les détails de version et de topologie, inspectez les journaux, puis vérifiez les certificats et la connectivité etcd. Lorsqu'un changement est nécessaire, effectuez le plus petit ajustement possible, sauvegardez la configuration et vérifiez le résultat. Les modes de défaillance et la liste de contrôle de cet article fournissent une voie pratique pour restaurer rapidement le service.
En suivant ces étapes et en évitant les pièges courants, vous pouvez réduire les temps d'arrêt et maintenir un plan de contrôle sain. Mettez régulièrement à jour vos runbooks et surveillez l'expiration des certificats et la santé d'etcd pour prévenir les problèmes avant qu'ils ne surviennent.