Introduction
Le serveur d'API Kube est la porte d'entrée d'un cluster Kubernetes. Lorsqu'il tombe en panne, les commandes kubectl se bloquent, les contrôleurs cessent de se réconcilier et les charges de travail deviennent ingérables. Ce guide rassemble les erreurs les plus courantes du serveur d'API Kube, leurs causes et des correctifs concrets avec commandes, sorties attendues et étapes de récupération.
Il s'adresse aux développeurs, consultants DevOps et équipes techniques de startups qui exploitent des clusters Kubernetes versions 1.26 à 1.30. L'accent est mis sur kube-apiserver lui-même ; les composants du plan de contrôle associés comme kubelet, kube-controller-manager et RBAC ne sont mentionnés que lorsqu'ils affectent les prérequis, la sécurité ou l'observabilité du serveur d'API.
Le flux de travail suit des principes de sécurité opérationnelle :
- Observer avant de modifier.
- Capturer l'état actuel avec des commandes en lecture seule.
- Utiliser des espaces réservés au lieu de véritables identifiants, jetons ou clés privées dans les exemples.
- Limiter les modifications à un seul élément ciblé à la fois.
- Vérifier le résultat après chaque intervention.
- Disposer d'un chemin de récupération testé avant d'effectuer une modification.
Chaque section nomme le composant concerné, les versions prises en charge, les prérequis, une observation en lecture seule, la plus petite modification justifiée et le signal de vérification.
Inventaire des versions et de l'environnement
Avant de dépanner, établissez la version exacte et la topologie. Le binaire kube-apiserver est généralement déployé en tant que Pod statique géré par le kubelet sur les nœuds du plan de contrôle, ou en tant que service systemd dans les configurations non conteneurisées.
Identifier la version et le déploiement
Observation en lecture seule
kubectl version --short
Sortie attendue sur un cluster fonctionnel :
Client Version: v1.28.3
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.28.3
Si le serveur d'API est en panne, kubectl ne peut pas se connecter. Dans ce cas, vérifiez uniquement la version du client kubectl :
kubectl version --client
Ou inspectez le binaire directement sur le nœud du plan de contrôle :
/usr/local/bin/kube-apiserver --version
Sortie attendue :
Kubernetes v1.28.3
Pour déterminer le type de déploiement, vérifiez si le Pod kube-apiserver est visible (cela nécessite un serveur d'API fonctionnel) :
kubectl get pods -n kube-system | grep kube-apiserver
Si le serveur d'API est en panne, recherchez le fichier manifeste du Pod statique :
ls -la /etc/kubernetes/manifests/kube-apiserver.yaml
Si ce fichier existe, le kubelet gère le kube-apiserver en tant que Pod statique. Sinon, cherchez une unité systemd :
systemctl status kube-apiserver
Prérequis
- Accès à un nœud du plan de contrôle via SSH ou console.
- Permission de lecture sur /etc/kubernetes/manifests/ ou les fichiers d'unité systemd.
- kubectl configuré pour le cluster (lorsque le serveur d'API est en marche).
Rayon d'impact
Ces commandes sont en lecture seule et sûres à exécuter.
Vérifier la santé du serveur d'API
Une fois que vous connaissez la version et le déploiement, vérifiez le point de terminaison de santé.
Observation en lecture seule
Depuis un nœud du plan de contrôle, exécutez :
curl -k https://localhost:6443/healthz?verbose
Sortie attendue lorsqu'il est sain :
[+]ping ok
[+]log ok
[+]etcd ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
[+]poststarthook/generic-apiserver-start-informers ok
[+]poststarthook/priority-and-fairness-config-consumer ok
[+]poststarthook/priority-and-fairness-filter ok
[+]poststarthook/storage-object-count-tracker-hook ok
[+]poststarthook/start-apiextensions-informers ok
[+]poststarthook/start-apiextensions-controllers ok
[+]poststarthook/crd-informer-synced ok
[+]poststarthook/bootstrap-controller ok
[+]poststarthook/rbac/bootstrap-roles ok
[+]poststarthook/scheduling/bootstrap-system-priority-classes ok
[+]poststarthook/start-cluster-authentication-info-controller ok
[+]poststarthook/start-kube-apiserver-identity-lease-controller ok
[+]poststarthook/start-deprecated-alpha-api-gateway-trickster ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
healthz check passed
Si un contrôle échoue, notez le composant défaillant ; il pointe souvent directement vers la cause racine (par exemple, un échec etcd signifie que le serveur d'API ne peut pas atteindre sa base de données backend).
Plus petite modification justifiée
Aucune modification pour l'instant. Enregistrez l'état actuel et passez aux diagnostics.
Chemin de configuration sûr
La plupart des mauvaises configurations de kube-apiserver proviennent de modifications de son fichier manifeste (/etc/kubernetes/manifests/kube-apiserver.yaml) ou de son unité systemd (/etc/systemd/system/kube-apiserver.service). Suivez ce chemin sûr pour éviter d'aggraver les choses.
Avant de modifier : capturer une base de référence
Observation en lecture seule
- Copiez le fichier manifeste ou d'unité actuel vers une sauvegarde horodatée :
sudo cp /etc/kubernetes/manifests/kube-apiserver.yaml /var/tmp/kube-apiserver.yaml.$(date +%Y%m%d%H%M%S)
- Enregistrez l'état actuel du Pod et les journaux récents :
kubectl get pods -n kube-system -l component=kube-apiserver -o wide
kubectl logs -n kube-system -l component=kube-apiserver --tail=50
Si le serveur d'API est en panne, consultez les journaux du kubelet ou le journal systemd :
journalctl -u kubelet -n 50 --no-pager
ou
journalctl -u kube-apiserver -n 50 --no-pager
Prérequis
- Accès en écriture à un emplacement de sauvegarde sûr (par exemple, /var/tmp).
- Privilèges sudo sur le nœud du plan de contrôle.
Rayon d'impact
La sauvegarde et la capture des journaux sont en lecture seule et sûres.
Modifier la configuration en toute sécurité
Exemple : modifier l'adresse annoncée
Supposons que le serveur d'API annonce une mauvaise IP parce que l'IP du nœud a changé. Vous devez mettre à jour --advertise-address.
- Ouvrez le manifeste avec un éditeur de texte :
sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
- Trouvez les arguments du conteneur et modifiez :
spec:
containers:
- command:
- kube-apiserver
- --advertise-address=192.168.1.10 # changer vers la nouvelle IP
- --etcd-servers=https://127.0.0.1:2379
...
- Enregistrez et quittez. Le kubelet détectera le changement et redémarrera automatiquement le kube-apiserver en quelques secondes.
Vérification
Vérifiez le point de terminaison et la santé du serveur d'API :
kubectl get --raw /healthz
Sortie attendue :
ok
Et vérifiez l'adresse annoncée :
kubectl get endpoints kubernetes -n default -o yaml
Extrait attendu :
subsets:
- addresses:
- ip: 192.168.1.10
ports:
- name: https
port: 6443
protocol: TCP
Chemin de récupération
Si le serveur d'API ne démarre pas après la modification, restaurez la sauvegarde :
sudo cp /var/tmp/kube-apiserver.yaml.<horodatage> /etc/kubernetes/manifests/kube-apiserver.yaml
Le kubelet redémarrera le serveur d'API avec l'ancienne configuration. Ensuite, recherchez la cause racine.
Vérification et diagnostics
Lorsque vous soupçonnez un problème, exécutez un ensemble systématique de diagnostics. Cette section couvre les vérifications courantes et ce que signifient leurs sorties.
Vérifier les journaux du serveur d'API
Observation en lecture seule
Sur un déploiement avec Pod statique :
kubectl logs -n kube-system -l component=kube-apiserver --tail=100
Sur systemd :
journalctl -u kube-apiserver -n 100 --no-pager
Recherchez les erreurs répétées telles que :
etcdserver: request timed out– problème de connectivité vers etcd.x509: certificate signed by unknown authority– problème de confiance de certificat.Unauthorized– problème d'authentification ou de RBAC.the server is currently unable to handle the request– serveur d'API surchargé.
Vérifier les métriques du serveur d'API
Le serveur d'API expose des métriques Prometheus sur le port 6443 (ou un port de métriques séparé si configuré).
Observation en lecture seule
curl -k https://localhost:6443/metrics | grep apiserver_request_total | head
Exemple de sortie :
apiserver_request_total{client="kubelet", code="200", content_type="application/vnd.kubernetes.protobuf", dry_run="", group="", resource="pods", scope="cluster", subresource="", verb="GET", version="v1"} 1200
Métriques clés à surveiller :
apiserver_request_duration_seconds_bucket– une latence élevée indique une surcharge.apiserver_request_total– taux d'erreurs par verbe/ressource.etcd_request_duration_seconds_bucket– latence etcd, qui impacte souvent les performances du serveur d'API.
Vérifier les performances du serveur d'API
Si les requêtes sont lentes, vérifiez les paramètres de priorité et d'équité de l'API ainsi que les webhooks d'admission.
Observation en lecture seule
Listez les webhooks d'admission :
kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations
Si un webhook a un timeoutSeconds élevé ou est injoignable, il peut bloquer les requêtes. Consultez les journaux du webhook ou testez la connectivité.
Interrogez les niveaux de priorité :
kubectl get prioritylevelconfigurations
Si un niveau de priorité est saturé, vous devrez peut-être ajuster ses assuredConcurrencyShares.
Plus petite modification justifiée
Si un webhook se comporte mal, désactivez-le temporairement en définissant failurePolicy: Ignore, mais ne le supprimez pas. Vérifiez ensuite que les performances s'améliorent.
Vérification
Après désactivation, exécutez une commande kubectl simple et mesurez le temps :
time kubectl get pods
Attendu : la commande revient en moins d'une seconde (sauf si le cluster est énorme).
Récupération
Réactivez le webhook en définissant failurePolicy: Fail et corrigez le service sous-jacent.
Modes de défaillance et récupération
Cette section liste des scénarios de défaillance concrets avec symptômes, diagnostic et étapes de récupération.
Scénario 1 : le serveur d'API ne peut pas démarrer en raison d'un drapeau invalide
Symptôme
kubectl affiche The connection to the server 192.168.1.10:6443 was refused - did you specify the right host or port?
Diagnostic
Consultez les journaux du kubelet ou le journal systemd pour le crash du conteneur du serveur d'API :
journalctl -u kubelet -n 100 | grep kube-apiserver
Exemple d'erreur :
Error: unknown flag: --advertise-addresss
Cause
Faute de frappe dans le nom du drapeau ou valeur invalide.
Récupération
- Restaurez le manifeste précédent à partir de la sauvegarde.
- Corrigez le drapeau.
- Vérifiez avec
kubectl get --raw /healthz.
Scénario 2 : le serveur d'API ne peut pas atteindre etcd
Symptôme
Le serveur d'API démarre mais les journaux affichent des erreurs répétées :
etcdserver: request timed out
Diagnostic
Vérifiez la santé d'etcd depuis le nœud du plan de contrôle :
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
Attendu si sain :
https://127.0.0.1:2379 is healthy: successfully committed proposal: took = 2.345678ms
Si malsain, consultez les journaux etcd et la connectivité réseau.
Récupération
- Assurez-vous que le service etcd est en cours d'exécution.
- Vérifiez les règles de pare-feu entre le serveur d'API et etcd (port par défaut 2379).
- Vérifiez la validité des certificats :
openssl x509 -in /etc/kubernetes/pki/etcd/server.crt -noout -dates. - Si etcd est en panne, restaurez à partir d'une sauvegarde ou redémarrez etcd.
Scénario 3 : erreurs de certificat sur les requêtes client
Symptôme
Les commandes kubectl échouent avec :
Unable to connect to the server: x509: certificate signed by unknown authority
Diagnostic
Vérifiez le certificat utilisé par le serveur d'API :
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -subject -issuer -dates
Attendu :
subject=CN=kube-apiserver
issuer=CN=kubernetes
notBefore=...
notAfter=...
Vérifiez les informations du certificat kubeconfig du client :
kubectl config view --raw
Cause
- Certificat client expiré ou non approuvé.
- Certificat du serveur d'API expiré ou non signé par l'autorité de certification du cluster.
Récupération
- Renouvelez les certificats du serveur d'API avec kubeadm :
kubeadm certs renew apiserver - Pour le certificat client, régénérez le kubeconfig ou utilisez un certificat valide.
- Si vous utilisez une autorité de certification personnalisée, assurez-vous que le kubeconfig du client contient les bonnes
certificate-authority-data.
Scénario 4 : le serveur d'API refuse les requêtes en raison de RBAC
Symptôme
Un utilisateur ou une charge de travail obtient :
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:my-sa" cannot list resource "pods" in API group "" in the namespace "default"
Diagnostic
Vérifiez les rôles et les liaisons de rôles pour l'utilisateur/compte de service :
kubectl auth can-i list pods --as=system:serviceaccount:default:my-sa -n default
Attendu : no
Cause
RoleBinding ou ClusterRoleBinding manquant.
Récupération
Créez les ressources RBAC nécessaires, par exemple un Role qui permet de lister les pods :
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: ServiceAccount
name: my-sa
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Appliquez et vérifiez :
kubectl auth can-i list pods --as=system:serviceaccount:default:my-sa -n default
Attendu : yes
Liste de contrôle des opérations
Utilisez cette liste de contrôle pour la maintenance de routine et la réponse aux incidents.
Liste de contrôle pré-changement
- [ ] Enregistrer la version actuelle :
kubectl version --short - [ ] Vérifier le point de terminaison de santé :
curl -k https://localhost:6443/healthz?verbose - [ ] Sauvegarder le manifeste ou le fichier d'unité :
sudo cp /etc/kubernetes/manifests/kube-apiserver.yaml /var/tmp/backup-$(date +%s).yaml - [ ] Noter l'état actuel du Pod du serveur d'API :
kubectl get pods -n kube-system -l component=kube-apiserver - [ ] Identifier la portée du changement et l'impact attendu.
Pendant le changement
- [ ] Modifier un seul élément de configuration à la fois.
- [ ] Utiliser le contrôle de version pour les modifications du manifeste si possible (par exemple, GitOps).
- [ ] Enregistrer une copie du nouveau fichier avant de redémarrer.
Vérification post-changement
- [ ] Vérifier la santé :
kubectl get --raw /healthzrenvoieok. - [ ] Vérifier les ressources principales :
kubectl get nodesrenvoie la liste des nœuds. - [ ] Vérifier les journaux pour de nouvelles erreurs :
kubectl logs -n kube-system -l component=kube-apiserver --tail=50 - [ ] En cas d'échec, restaurer la sauvegarde et documenter l'incident.
Liste de contrôle de récupération
- [ ] Arrêter le changement, restaurer la configuration précédente.
- [ ] Vérifier que le serveur d'API est de nouveau sain.
- [ ] Rechercher la cause racine à l'aide des journaux et des métriques avant de réappliquer.
- [ ] Tester le changement dans un cluster de préproduction si possible.
Conclusion
Le dépannage du serveur d'API Kube nécessite une approche méthodique : identifier l'environnement, observer les symptômes, diagnostiquer avec des commandes ciblées, appliquer un correctif minimal et vérifier la récupération. Ce guide a fourni des commandes concrètes pour les scénarios d'erreur courants, des fautes de frappe dans la configuration aux problèmes de connectivité etcd et de certificats.
Comme prochaine étape, choisissez une vérification à faible risque dans la liste de contrôle des opérations, exécutez-la sur votre cluster et enregistrez la sortie attendue par rapport à la sortie réelle. Cette pratique développera la mémoire musculaire pour gérer le prochain incident kube-apiserver. N'oubliez pas : ne changez jamais plus d'une chose à la fois, ayez toujours une sauvegarde et vérifiez avant de déclarer victoire.