Introduction
Les opérateurs qui traitent le serveur d'API Kubernetes comme une boîte noire découvrent souvent que de petites erreurs de configuration peuvent mettre hors service des charges de travail, bloquer des déploiements ou exposer des données du cluster. Ce guide va au-delà de l'utilisation basique de kubectl get pods et explique comment le serveur d'API fonctionne réellement, comment vérifier son comportement et comment récupérer en toute sécurité des modes de défaillance courants. Vous apprendrez à observer avant de modifier, à limiter le rayon d'impact et à utiliser des commandes concrètes avec des sorties attendues.
Tout au long de cet article, remplacez les espaces réservés comme CLUSTER_CONTROL_PLANE_HOST par les valeurs de votre propre environnement. Ne collez jamais de véritables identifiants, jetons ou clés privées dans les commandes ou les fichiers de configuration.
Inventaire des versions et de l'environnement
Commencez toute investigation sur le serveur d'API en établissant la version installée, la topologie de déploiement et l'état actuel. Ces informations déterminent les drapeaux pris en charge, la disposition du plan de contrôle et les actions de récupération possibles.
Étape 1 : Identifier la version de Kubernetes et l'image du serveur d'API
Exécutez sur toute machine disposant d'un accès kubectl :
kubectl version --short
La sortie attendue ressemble à :
Client Version: v1.28.2
Server Version: v1.28.2
Si la version du serveur est plus ancienne que prévu, planifiez les mises à niveau avec soin. La version du serveur d'API définit les fonctionnalités et drapeaux disponibles. Par exemple, le drapeau --service-account-issuer est devenu stable en v1.22 et attend une URL ; les versions antérieures acceptaient une chaîne sans validation.
Ensuite, identifiez les pods du serveur d'API et leurs images :
kubectl get pods -n kube-system -l component=kube-apiserver -o wide
La sortie attendue montre les nœuds du plan de contrôle et l'état des pods :
NAME READY STATUS RESTARTS AGE IP NODE
kube-apiserver-node1 1/1 Running 2 10d 10.0.0.1 node1
Vérifiez l'étiquette de l'image :
kubectl get pod -n kube-system kube-apiserver-node1 -o jsonpath='{.spec.containers[0].image}'
Exemple de sortie : registry.k8s.io/kube-apiserver:v1.28.2. Cette étiquette doit correspondre à la version du serveur ; une incohérence indique une mise à niveau partielle.
Étape 2 : Comprendre la topologie de déploiement
Déterminez si le cluster est géré (par exemple, EKS, GKE, AKS) ou autogéré. Sur un cluster autogéré, le serveur d'API s'exécute sous forme de pods statiques définis dans /etc/kubernetes/manifests/kube-apiserver.yaml. Pour afficher le manifeste actuel sans le modifier :
sudo cat /etc/kubernetes/manifests/kube-apiserver.yaml
Sur les clusters gérés, vous n'avez peut-être pas d'accès direct aux nœuds du plan de contrôle. Récupérez plutôt la configuration du serveur d'API via la CLI ou la console du fournisseur cloud. Par exemple, sur EKS :
aws eks describe-cluster --name my-cluster --query 'cluster.kubernetesVersion'
Étape 3 : Capturer les métriques de référence
Avant d'apporter toute modification, enregistrez les taux de requêtes, la latence et les taux d'erreur actuels. Si vous avez Prometheus, exécutez des requêtes comme :
sum(rate(apiserver_request_total[5m])) by (verb, resource)
Sinon, utilisez kubectl get --raw /metrics pour récupérer les métriques directement du serveur d'API :
kubectl get --raw /metrics | grep apiserver_request_total
Enregistrez cette sortie dans un fichier pour comparaison ultérieure :
kubectl get --raw /metrics > baseline-metrics.txt
Liste de contrôle de sécurité opérationnelle pour l'inventaire
- [ ] Version capturée et enregistrée dans un runbook.
- [ ] Topologie de déploiement identifiée (pod statique, géré ou autre).
- [ ] Métriques de référence sauvegardées avec horodatage.
- [ ] Aucun secret n'a été imprimé dans les journaux du terminal ou stocké en texte brut.
Chemin de configuration sécurisé
Le serveur d'API possède des dizaines de drapeaux qui peuvent modifier le comportement de l'authentification, de l'autorisation, de l'admission et du stockage. La voie sûre consiste à comprendre chaque drapeau, à tester d'abord dans un cluster hors production et à apporter une modification à la fois avec vérification.
Drapeaux courants et leur impact
Voici un tableau des drapeaux fréquemment utilisés avec leur objectif et un exemple de valeur sûre. Les valeurs dépendent de la configuration de votre cluster.
| Drapeau | Objectif | Exemple de valeur sûre | Signal de vérification |
|---|---|---|---|
--authorization-mode | Définit comment les requêtes sont autorisées (par exemple, RBAC, Node, Webhook) | RBAC,Node | kubectl auth can-i list pods --as=system:serviceaccount:default:test renvoie yes ou no comme prévu |
--enable-admission-plugins | Active les contrôleurs d'admission qui valident ou mutent les requêtes | NamespaceLifecycle,LimitRanger,ServiceAccount | kubectl get validatingwebhookconfigurations affiche les webhooks enregistrés |
--service-account-issuer | Définit l'émetteur des jetons de compte de service | https://kubernetes.default.svc.cluster.local | kubectl get --raw /.well-known/openid-configuration renvoie un JSON avec l'émetteur |
--etcd-servers | Spécifie les points de terminaison etcd pour le stockage | https://127.0.0.1:2379 | kubectl get events renvoie des événements sans erreurs etcd |
--tls-cert-file et --tls-private-key-file | Chemins vers le certificat et la clé de service | /etc/kubernetes/pki/apiserver.crt, /etc/kubernetes/pki/apiserver.key | openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout affiche les noms DNS et la validité corrects |
Exemple de modification de configuration étape par étape : activer un plugin d'admission
Supposons que vous deviez activer le plugin d'admission PodSecurityPolicy sur un cluster de test. Procédure :
- Lire les drapeaux actuels à partir de la spécification du pod du serveur d'API :
kubectl get pod -n kube-system kube-apiserver-node1 -o jsonpath='{.spec.containers[0].command}' | tr ' ' '\n' | grep enable-admission
La sortie peut être vide ou afficher les plugins actuels.
- Modifier le manifeste sur le nœud du plan de contrôle :
sudo cp /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml.bak
sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
- Ajouter le drapeau dans la commande du conteneur :
- --enable-admission-plugins=NodeRestriction,PodSecurityPolicy
- Appliquer et attendre le redémarrage du serveur d'API (kubelet redémarre automatiquement les pods statiques). Vérifiez l'état de préparation :
kubectl wait --for=condition=Ready pod -n kube-system -l component=kube-apiserver --timeout=60s
Sortie attendue :
pod/kube-apiserver-node1 condition met
- Vérifier que le plugin est actif en tentant de créer un pod qui viole une PodSecurityPolicy. La requête doit être refusée avec un message d'erreur mentionnant la politique.
- Revenir en arrière si nécessaire : Si le serveur d'API ne démarre pas, copiez le manifeste de sauvegarde et redémarrez kubelet :
sudo cp /etc/kubernetes/manifests/kube-apiserver.yaml.bak /etc/kubernetes/manifests/kube-apiserver.yaml
sudo systemctl restart kubelet
Contrôle du rayon d'impact
- Effectuez les modifications de configuration pendant une fenêtre de maintenance, même dans les environnements de test.
- Utilisez un nœud canari : appliquez la modification à un nœud du plan de contrôle si vous en avez plusieurs, puis vérifiez avant de passer aux autres.
- Ayez toujours un plan de retour en arrière : copiez le fichier manifeste d'origine vers une sauvegarde horodatée avant de le modifier.
Vérification et diagnostics
Savoir à quoi ressemble un état sain est essentiel. Cette section fournit des commandes pour vérifier la santé du serveur d'API, inspecter les journaux et diagnostiquer les problèmes courants.
Points de terminaison de santé et de préparation
Le serveur d'API expose les points de terminaison /healthz, /livez et /readyz. Utilisez curl depuis un nœud du plan de contrôle ou via kubectl get --raw :
kubectl get --raw '/healthz?verbose'
Une sortie saine comprend :
[+]ping ok
[+]log ok
[+]etcd ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
healthz check passed
Si un contrôle échoue, la sortie affiche un signe moins et une erreur. Par exemple :
[-]etcd failed: reason withheld
healthz check failed
Cela indique un problème de connectivité etcd. Vérifiez l'état d'etcd et le réseau.
Inspection des journaux du serveur d'API
Sur un cluster autogéré, les journaux sont écrits dans des fichiers comme /var/log/kube-apiserver.log ou capturés par journald. Utilisez :
sudo journalctl -u kube-apiserver -n 100 --no-pager
Sur les clusters gérés, utilisez la collecte de journaux du fournisseur cloud. Par exemple, sur GKE :
gcloud logging read "resource.type=k8s_cluster AND logName=projects/my-project/logs/kube-apiserver" --limit=50
Filtrez les problèmes courants :
sudo journalctl -u kube-apiserver | grep -i "error\|failed\|denied"
Exemple d'erreur de certificat TLS :
E1010 10:00:00.123456 1 authentication.go:63] Unable to authenticate the request due to an error: x509: certificate has expired or is not yet valid
Diagnostic des échecs de requête
Lorsqu'une commande kubectl échoue avec The connection to the server ... was refused, vérifiez l'état du pod du serveur d'API :
kubectl get pods -n kube-system -l component=kube-apiserver
Si le pod est en CrashLoopBackOff, inspectez les journaux du conteneur précédent :
kubectl logs -n kube-system kube-apiserver-node1 --previous
Recherchez des messages de sortie tels que des fichiers manquants, des valeurs de drapeau invalides ou des conflits de ports.
Profilage des performances du serveur d'API
Pour diagnostiquer la latence, activez le drapeau --profiling et utilisez les points de terminaison pprof (uniquement hors production). Exemple :
kubectl get --raw '/debug/pprof/goroutine?debug=1' | head -20
Cela produit des traces de pile. Analysez avec go tool pprof si nécessaire.
Modes de défaillance et récupération
Cette section décrit les scénarios de défaillance courants, leurs symptômes et les étapes de récupération.
Défaillance 1 : Le serveur d'API ne peut pas atteindre etcd
Symptôme : Les commandes kubectl se bloquent ou renvoient etcdserver: request timed out. Le point de terminaison healthz affiche etcd failed.
Diagnostic : Vérifiez l'état et les journaux du pod etcd :
kubectl get pods -n kube-system -l component=etcd
kubectl logs -n kube-system etcd-node1 --tail=50
Vérifiez également la connectivité réseau du conteneur du serveur d'API vers les points de terminaison etcd.
Récupération : Si etcd est en panne, redémarrez-le. Si le réseau est en cause, rétablissez la connectivité ou mettez à jour --etcd-servers avec les bons points de terminaison. Dans les cas extrêmes, restaurez etcd à partir d'une sauvegarde.
Défaillance 2 : Expiration du certificat
Symptôme : Le serveur d'API ne démarre pas avec x509: certificate has expired, ou les clients obtiennent des erreurs TLS.
Diagnostic : Vérifiez les dates d'expiration du certificat :
sudo openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates
La sortie affiche notBefore et notAfter. Si la date actuelle est postérieure à notAfter, le certificat est expiré.
Récupération : Renouvelez le certificat. Si vous utilisez kubeadm, exécutez kubeadm certs renew apiserver puis redémarrez le serveur d'API. Pour les clusters avec cert-manager ou une PKI externe, déclenchez le renouvellement selon votre configuration. Après renouvellement, vérifiez avec openssl x509 -dates et redémarrez les composants concernés.
Défaillance 3 : Webhook d'admission mal configuré
Symptôme : Le serveur d'API se bloque lors de la création d'objets ou renvoie InternalError avec webhook timeout.
Diagnostic : Vérifiez la configuration du webhook :
kubectl get validatingwebhookconfigurations
Testez la joignabilité du webhook depuis le serveur d'API en utilisant curl vers l'URL du service du webhook.
Récupération : Désactivez temporairement le webhook en supprimant ou en modifiant sa configuration pour définir failurePolicy: Ignore. Réparez le service du webhook, puis réactivez-le. Si le webhook est critique et ne peut pas être corrigé rapidement, envisagez de revenir sur la modification du plugin d'admission qui l'a introduit.
Défaillance 4 : Trop de descripteurs de fichiers ouverts
Symptôme : Les journaux du serveur d'API affichent too many open files et certaines requêtes échouent.
Diagnostic : Vérifiez les limites du processus :
sudo cat /proc/$(pgrep kube-apiserver)/limits | grep "Max open files"
Récupération : Augmentez la limite système pour le service kube-apiserver. Pour un serveur d'API géré par systemd, modifiez le fichier unité pour définir LimitNOFILE=65536 (ou plus), puis redémarrez. Pour les pods statiques, assurez-vous que le kubelet a des limites suffisamment élevées.
Principes généraux de récupération
- Sauvegardez toujours les fichiers de configuration et les données etcd avant d'apporter des modifications.
- Utilisez
kubectl drainpour isoler un nœud du plan de contrôle (le cas échéant) avant la maintenance afin d'éviter toute interruption des requêtes. - Documentez la modification exacte, le comportement attendu et les étapes de retour en arrière dans un runbook.
Liste de contrôle des opérations
Utilisez cette liste de contrôle pour toute session de maintenance ou de dépannage du serveur d'API. Attribuez un responsable unique à chaque élément et révisez-la chaque semaine ou après chaque modification.
| # | Élément | Responsable | Fréquence | Méthode de vérification |
|---|---|---|---|---|
| 1 | Vérifier que la version du serveur d'API et l'étiquette d'image correspondent aux attentes | Ingénieur plateforme (par exemple, Priya Shah) | Mensuelle | kubectl version --short et vérification de l'image du pod |
| 2 | Examiner les journaux du serveur d'API pour les erreurs et avertissements | Responsable SRE (par exemple, Marcus Chen) | Hebdomadaire | journalctl -u kube-apiserver --since "1 week ago" |
| 3 | Vérifier les points de terminaison de santé /healthz, /readyz | Ingénieur d'astreinte | Quotidienne (automatisée) | Alerte de surveillance si le point de terminaison renvoie un code autre que 200 |
| 4 | Valider les dates d'expiration des certificats (serveur d'API, etcd) | Ingénieur sécurité (par exemple, Elena Rodriguez) | Mensuelle | openssl x509 -dates ou statut cert-manager |
| 5 | Tester les webhooks d'admission avec un objet canari | Responsable de l'équipe applicative | Avant chaque changement majeur | Créer un pod de test dans un espace de noms dédié et observer |
| 6 | Examiner les sauvegardes etcd et tester la procédure de restauration | Responsable infrastructure (par exemple, David Kim) | Trimestrielle | Exécuter une restauration etcd dans un bac à sable et vérifier l'intégrité des données |
| 7 | Mettre à jour la documentation de configuration du serveur d'API | Propriétaire de la plateforme API (par exemple, Sarah Johnson) | Après chaque modification | Revue de la documentation par un pair |
Lorsqu'un élément échoue à la vérification, le responsable doit ouvrir un ticket d'incident et suivre les procédures de récupération de la section précédente.
Pièges courants et comment les éviter
De nombreux problèmes du serveur d'API proviennent d'erreurs évitables. Voici les pièges fréquents, pourquoi ils surviennent et comment les prévenir ou les récupérer.
Piège 1 : Ignorer l'écart de version
Pourquoi cela arrive : Les équipes mettent à niveau les nœuds de travail mais oublient les composants du plan de contrôle, ou vice versa. Kubernetes prend en charge un écart de version maximal entre le serveur d'API et le kubelet d'une version mineure.
Comment éviter : Vérifiez toujours kubectl version avant et après les mises à niveau. Utilisez un outil de cycle de vie du cluster comme kubeadm ou les fonctionnalités de mise à niveau gérées pour garder les versions alignées.
Récupération : Si l'écart est trop important, mettez à niveau ou rétrogradez les composants dans la plage prise en charge. Un retour en arrière peut nécessiter une restauration à partir d'un instantané etcd si le serveur d'API a déjà écrit des données incompatibles.
Piège 2 : Faire plusieurs modifications de drapeaux à la fois
Pourquoi cela arrive : Le désir d'efficacité conduit à modifier plusieurs lignes du manifeste simultanément.
Comment éviter : Modifiez un drapeau, redémarrez, vérifiez la santé, puis passez au suivant. Utilisez git pour versionner les fichiers manifestes et suivre les modifications.
Récupération : Si plusieurs modifications provoquent un état irrécupérable, restaurez le manifeste précédent à partir de la sauvegarde (ou de git) et redémarrez. Réappliquez ensuite les modifications une par une.
Piège 3 : Coder en dur des adresses IP dans --etcd-servers
Pourquoi cela arrive : Copier la configuration d'un cluster spécifique sans généraliser.
Comment éviter : Utilisez un templating spécifique à l'environnement (par exemple, les valeurs Helm, kustomize) pour injecter les bons points de terminaison. Préférez localhost pour etcd sur le même nœud, ou utilisez des noms de service au sein du cluster.
Récupération : Mettez à jour le drapeau avec les valeurs correctes et redémarrez le serveur d'API. Si etcd a déménagé, assurez la connectivité et la résolution DNS.
Piège 4 : Ne pas tester les webhooks d'admission avant le déploiement en production
Pourquoi cela arrive : Les équipes supposent que le webhook se comporte comme documenté.
Comment éviter : Déployez d'abord les webhooks dans un environnement de préproduction avec des charges de travail réalistes. Utilisez failurePolicy: Fail et timeoutSeconds adaptés à votre tolérance de latence, mais testez également avec une panne simulée du webhook pour voir comment le serveur d'API se comporte.
Récupération : Si un webhook de production échoue, définissez failurePolicy sur Ignore si le webhook n'est pas critique pour la sécurité, ou corrigez rapidement le service du webhook.
Piège 5 : Négliger le renouvellement des certificats
Pourquoi cela arrive : Les certificats ont une longue validité (par exemple, un an) et les processus de renouvellement sont oubliés.
Comment éviter : Configurez des alertes de surveillance pour l'expiration des certificats au moins 30 jours à l'avance. Automatisez le renouvellement avec cert-manager ou la commande de renouvellement intégrée de kubeadm.
Récupération : Renouvelez manuellement les certificats avec kubeadm certs renew all (pour les clusters kubeadm) ou votre système PKI, puis redémarrez les composants du plan de contrôle.
Conclusion
Une approche opérationnelle solide du serveur d'API Kubernetes nécessite de comprendre ses composants internes, sa surface de configuration et ses modes de défaillance. En appliquant systématiquement les pratiques de ce guide, vous pouvez réduire les temps d'arrêt, améliorer la sécurité et apporter des modifications en toute confiance.
Comme prochaine étape, choisissez une vérification de la liste de contrôle des opérations, comme la vérification des points de terminaison de santé du serveur d'API ou de l'expiration des certificats. Effectuez cette vérification dans votre environnement, comparez le résultat avec le signal attendu et documentez toute divergence. Ensuite, examinez votre configuration actuelle par rapport au chemin de configuration sécurisé pour identifier les drapeaux à risque.
Rappelez-vous : observez d'abord, apportez de petites modifications réversibles, vérifiez avec des commandes explicites et ayez toujours un plan de retour en arrière.