## 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 :

```bash
kubectl version --client
```

La sortie attendue inclut à la fois les versions client et serveur. Par exemple :

```text
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 :

```bash
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 :

```bash
kubectl get nodes
```

Exemple de sortie :

```text
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) :

```bash
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 :

```bash
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 :

```bash
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 :

```bash
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 :

```bash
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 :

```bash
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 :

```yaml
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 :

```bash
kubectl get pod -n kube-system kube-apiserver-control-plane
```

Puis vérifiez les journaux pour les messages de démarrage réussi :

```bash
kubectl logs -n kube-system kube-apiserver-control-plane --tail=20
```

La sortie attendue inclut des lignes comme :

```text
"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 :

```bash
curl -k https://localhost:6443/healthz
```

Attendu : `ok`

Pour une vérification plus détaillée, utilisez :

```bash
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 :

```bash
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 :

```bash
kubectl config current-context
```

Vérifiez si votre certificat est valide :

```bash
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 :

```bash
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 :

```bash
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 :

```bash
kubeadm certs check-expiration
```

Exemple de sortie :

```text
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 :

```bash
curl -k https://127.0.0.1:2379/health
```

Etcd peut exiger des certificats clients. Utilisez :

```bash
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 :

1. Vérifiez les journaux :

```bash
kubectl logs -n kube-system kube-apiserver-control-plane --previous
```

2. Examinez le manifeste pour les erreurs :

```bash
sudo cat /etc/kubernetes/manifests/kube-apiserver.yaml
```

3. Validez la syntaxe YAML :

```bash
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).

4. 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.

5. Le pod devrait redémarrer automatiquement. Vérifiez :

```bash
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 :

```bash
sudo crictl ps | grep kube-apiserver
```

Ou

```bash
sudo docker ps | grep kube-apiserver
```

S'il n'y a pas de conteneur, vérifiez l'état du kubelet :

```bash
sudo systemctl status kubelet
```

Consultez les journaux du kubelet :

```bash
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 :

```bash
sudo kubeadm certs renew apiserver
```

Ensuite, redémarrez le serveur d'API (ou laissez le kubelet prendre en compte les changements) :

```bash
sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/
sudo mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/
```

Ou simplement :

```bash
sudo kill -s SIGHUP $(pidof kube-apiserver)
```

Vérifiez :

```bash
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 :

```bash
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.