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

<style>
.eno-quiz-widget{margin:2rem 0;padding:1.5rem;border-radius:12px;background:var(--eno-surface-lowest,#f7f7f8);border:1px solid var(--eno-border-soft,#e2e2e6);font-family:var(--eno-font-body,Inter,sans-serif)}
.eno-quiz-widget .eno-quiz-kicker{font-family:var(--eno-font-label,"JetBrains Mono",monospace);font-size:.75rem;letter-spacing:.05em;text-transform:uppercase;color:var(--eno-text-muted,#5f5f68);margin:0 0 .5rem}
.eno-quiz-widget .eno-quiz-question{font-family:var(--eno-font-heading,"Hanken Grotesk",sans-serif);font-size:1.0625rem;font-weight:600;margin:0 0 1rem;color:var(--eno-text-strong,#1a1a1f)}
.eno-quiz-widget .eno-quiz-options{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.eno-quiz-widget .eno-quiz-option{display:block;width:100%;min-height:44px;text-align:left;padding:.625rem .875rem;border-radius:8px;border:1.5px solid var(--eno-border-soft,#e2e2e6);background:#fff;font-size:.9375rem;cursor:pointer;transition:border-color var(--eno-motion-base,180ms ease-out),background var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-option:hover{border-color:var(--eno-primary,#0059bb)}
.eno-quiz-widget .eno-quiz-option:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-option[aria-pressed="true"]{border-color:var(--eno-primary,#0059bb);background:rgb(0 89 187 / 0.06)}
.eno-quiz-widget .eno-quiz-option[data-correct="true"].eno-quiz-revealed{border-color:var(--eno-success,#17803a);background:rgb(23 128 58 / 0.08)}
.eno-quiz-widget .eno-quiz-option[data-correct="false"].eno-quiz-revealed.eno-quiz-was-selected{border-color:var(--eno-error,#ba1a1a);background:var(--eno-error-soft,#ffdad6)}
.eno-quiz-widget .eno-quiz-option-icon{display:inline-block;width:1.1em;margin-right:.4em;font-weight:700}
.eno-quiz-widget .eno-quiz-submit{margin-top:1rem;min-height:44px;padding:.5rem 1.25rem;border-radius:8px;border:none;background:var(--eno-primary,#0059bb);color:#fff;font-weight:600;font-size:.9375rem;cursor:pointer;transition:opacity var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-submit:disabled{opacity:.5;cursor:not-allowed}
.eno-quiz-widget .eno-quiz-submit:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-explanation{margin-top:1rem;padding:.875rem 1rem;border-radius:8px;font-size:.9375rem;line-height:1.5;display:none}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-visible{display:block}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-correct{background:rgb(23 128 58 / 0.08);color:var(--eno-success,#17803a)}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-incorrect{background:var(--eno-error-soft,#ffdad6);color:var(--eno-error,#ba1a1a)}
@media (prefers-reduced-motion: reduce){.eno-quiz-widget *{transition:none!important}}
</style><div class="eno-quiz-widget" role="group" aria-label="Question rapide">
Question rapide 1 sur 2

Que fait le kube-apiserver dans un cluster Kubernetes ?

- Il exécute le runtime de conteneurs.
- Il valide et configure les données des objets de l'API.
- Il planifie les charges de travail sur les nœuds.
- Il fournit le stockage pour l'état du cluster.

<button type="button" class="eno-quiz-submit" disabled>Valider</button>
<div class="eno-quiz-explanation">Le kube-apiserver valide et configure les données des objets de l&#39;API, notamment les pods, les services, les replicationcontrollers, etc.</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
  document.querySelectorAll('.eno-quiz-widget:not([data-eno-quiz-bound])').forEach(function (widget) {
    widget.setAttribute('data-eno-quiz-bound', '1');
    var options = Array.prototype.slice.call(widget.querySelectorAll('.eno-quiz-option'));
    var submitBtn = widget.querySelector('.eno-quiz-submit');
    var explanation = widget.querySelector('.eno-quiz-explanation');
    var selected = null;
    options.forEach(function (opt) {
      opt.addEventListener('click', function () {
        if (widget.hasAttribute('data-eno-quiz-answered')) return;
        options.forEach(function (o) { o.setAttribute('aria-pressed', 'false'); });
        opt.setAttribute('aria-pressed', 'true');
        selected = opt;
        submitBtn.disabled = false;
      });
    });
    submitBtn.addEventListener('click', function () {
      if (!selected || widget.hasAttribute('data-eno-quiz-answered')) return;
      widget.setAttribute('data-eno-quiz-answered', '1');
      submitBtn.disabled = true;
      var correct = selected.getAttribute('data-correct') === 'true';
      options.forEach(function (o) {
        o.classList.add('eno-quiz-revealed');
        if (o === selected) o.classList.add('eno-quiz-was-selected');
        var icon = o.querySelector('.eno-quiz-option-icon');
        if (o.getAttribute('data-correct') === 'true') icon.textContent = '\u2713';
        else if (o === selected) icon.textContent = '\u2717';
      });
      explanation.classList.add('eno-quiz-visible', correct ? 'eno-quiz-correct' : 'eno-quiz-incorrect');
    });
  });
});
</script>

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

<style>
.eno-quiz-widget{margin:2rem 0;padding:1.5rem;border-radius:12px;background:var(--eno-surface-lowest,#f7f7f8);border:1px solid var(--eno-border-soft,#e2e2e6);font-family:var(--eno-font-body,Inter,sans-serif)}
.eno-quiz-widget .eno-quiz-kicker{font-family:var(--eno-font-label,"JetBrains Mono",monospace);font-size:.75rem;letter-spacing:.05em;text-transform:uppercase;color:var(--eno-text-muted,#5f5f68);margin:0 0 .5rem}
.eno-quiz-widget .eno-quiz-question{font-family:var(--eno-font-heading,"Hanken Grotesk",sans-serif);font-size:1.0625rem;font-weight:600;margin:0 0 1rem;color:var(--eno-text-strong,#1a1a1f)}
.eno-quiz-widget .eno-quiz-options{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.eno-quiz-widget .eno-quiz-option{display:block;width:100%;min-height:44px;text-align:left;padding:.625rem .875rem;border-radius:8px;border:1.5px solid var(--eno-border-soft,#e2e2e6);background:#fff;font-size:.9375rem;cursor:pointer;transition:border-color var(--eno-motion-base,180ms ease-out),background var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-option:hover{border-color:var(--eno-primary,#0059bb)}
.eno-quiz-widget .eno-quiz-option:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-option[aria-pressed="true"]{border-color:var(--eno-primary,#0059bb);background:rgb(0 89 187 / 0.06)}
.eno-quiz-widget .eno-quiz-option[data-correct="true"].eno-quiz-revealed{border-color:var(--eno-success,#17803a);background:rgb(23 128 58 / 0.08)}
.eno-quiz-widget .eno-quiz-option[data-correct="false"].eno-quiz-revealed.eno-quiz-was-selected{border-color:var(--eno-error,#ba1a1a);background:var(--eno-error-soft,#ffdad6)}
.eno-quiz-widget .eno-quiz-option-icon{display:inline-block;width:1.1em;margin-right:.4em;font-weight:700}
.eno-quiz-widget .eno-quiz-submit{margin-top:1rem;min-height:44px;padding:.5rem 1.25rem;border-radius:8px;border:none;background:var(--eno-primary,#0059bb);color:#fff;font-weight:600;font-size:.9375rem;cursor:pointer;transition:opacity var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-submit:disabled{opacity:.5;cursor:not-allowed}
.eno-quiz-widget .eno-quiz-submit:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-explanation{margin-top:1rem;padding:.875rem 1rem;border-radius:8px;font-size:.9375rem;line-height:1.5;display:none}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-visible{display:block}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-correct{background:rgb(23 128 58 / 0.08);color:var(--eno-success,#17803a)}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-incorrect{background:var(--eno-error-soft,#ffdad6);color:var(--eno-error,#ba1a1a)}
@media (prefers-reduced-motion: reduce){.eno-quiz-widget *{transition:none!important}}
</style><div class="eno-quiz-widget" role="group" aria-label="Question rapide">
Question rapide 2 sur 2

Si le serveur d'API n'est pas joignable, quelle est la première vérification de connectivité de base à effectuer ?

- Vérifier les journaux du kube-apiserver.
- Exécuter `ping` pour tester la joignabilité de l'hôte.
- Vérifier l'état de etcd.
- Inspecter les fichiers manifestes.

<button type="button" class="eno-quiz-submit" disabled>Valider</button>
<div class="eno-quiz-explanation">Vérifiez si l&#39;hôte du serveur d&#39;API est joignable à l&#39;aide de la commande `ping`.</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
  document.querySelectorAll('.eno-quiz-widget:not([data-eno-quiz-bound])').forEach(function (widget) {
    widget.setAttribute('data-eno-quiz-bound', '1');
    var options = Array.prototype.slice.call(widget.querySelectorAll('.eno-quiz-option'));
    var submitBtn = widget.querySelector('.eno-quiz-submit');
    var explanation = widget.querySelector('.eno-quiz-explanation');
    var selected = null;
    options.forEach(function (opt) {
      opt.addEventListener('click', function () {
        if (widget.hasAttribute('data-eno-quiz-answered')) return;
        options.forEach(function (o) { o.setAttribute('aria-pressed', 'false'); });
        opt.setAttribute('aria-pressed', 'true');
        selected = opt;
        submitBtn.disabled = false;
      });
    });
    submitBtn.addEventListener('click', function () {
      if (!selected || widget.hasAttribute('data-eno-quiz-answered')) return;
      widget.setAttribute('data-eno-quiz-answered', '1');
      submitBtn.disabled = true;
      var correct = selected.getAttribute('data-correct') === 'true';
      options.forEach(function (o) {
        o.classList.add('eno-quiz-revealed');
        if (o === selected) o.classList.add('eno-quiz-was-selected');
        var icon = o.querySelector('.eno-quiz-option-icon');
        if (o.getAttribute('data-correct') === 'true') icon.textContent = '\u2713';
        else if (o === selected) icon.textContent = '\u2717';
      });
      explanation.classList.add('eno-quiz-visible', correct ? 'eno-quiz-correct' : 'eno-quiz-incorrect');
    });
  });
});
</script>

## 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 /healthz renvoie ok .

- [ ] Vérifier les ressources principales : kubectl get nodes renvoie 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.