Un pod créé par un Deployment, un DaemonSet ou un Job existe parce qu’un contrôleur, via le serveur API, en a décidé ainsi. Un static pod suit une logique radicalement différente : il est géré directement par le kubelet d’un nœud, à partir d’un fichier manifeste local, sans jamais passer par le serveur API pour exister.
Ce qui rend un static pod différent
Le kubelet surveille en continu un répertoire local (/etc/kubernetes/manifests par défaut) : tout fichier YAML déposé là devient un pod géré directement, sans intervention d’aucun contrôleur ni du scheduler. C’est exactement ce mécanisme qui permet de faire tourner le control plane lui-même comme des pods Kubernetes ordinaires : kube-apiserver, etcd, kube-scheduler tournent souvent comme static pods sur un cluster kubeadm, un problème d’œuf et de poule résolu élégamment (le control plane démarre avant même qu’un serveur API ne soit disponible pour le gérer).
# Tout fichier déposé ici devient un pod géré
# directement par le kubelet, sans passer par l'API server
ls /etc/kubernetes/manifests/
# etcd.yaml kube-apiserver.yaml kube-scheduler.yaml
Le mirror pod : une fenêtre en lecture seule vers l’API
Le kubelet publie une copie en lecture seule de chaque static pod dans l’API Kubernetes, un « mirror pod », visible via kubectl get pods exactement comme n’importe quel autre pod. Cette visibilité est trompeuse : le mirror pod n’est qu’un reflet, jamais la source de vérité, et modifier ou supprimer ce reflet via l’API n’a aucun effet sur le static pod réel géré par le kubelet.
# Le mirror pod apparaît normalement,
# mais supprimer ce reflet ne supprime rien de réel
kubectl delete pod kube-apiserver-node1 -n kube-system
# Le kubelet recrée immédiatement le pod,
# puisque le fichier manifeste local existe toujours
Pourquoi kubectl delete échoue silencieusement
Une tentative de suppression d’un static pod via kubectl delete supprime bien le mirror pod dans l’API, mais le kubelet, qui surveille toujours le fichier manifeste local, recrée immédiatement le pod réel, ce qui republie un nouveau mirror pod presque instantanément. Ce comportement ressemble à une commande qui échoue silencieusement, alors qu’elle réussit parfaitement sur ce qu’elle contrôle réellement (le mirror pod), sans jamais toucher à la source de vérité (le fichier manifeste et le processus que le kubelet gère).
La bonne façon de modifier ou supprimer un static pod
Modifier ou supprimer un static pod exige d’agir directement sur le fichier manifeste, sur le nœud lui-même, jamais via l’API Kubernetes.
# La seule action qui a un effet réel :
# modifier ou déplacer le fichier manifeste local
mv /etc/kubernetes/manifests/my-static-pod.yaml /tmp/
# Le kubelet détecte l'absence du fichier
# et arrête le pod correspondant
Le kubelet surveille ce répertoire en continu : déplacer, modifier ou supprimer le fichier déclenche la même action côté pod, presque immédiatement, sans jamais passer par kubectl.
À retenir
Un static pod est géré directement par le kubelet à partir d’un fichier manifeste local, un mécanisme entièrement différent des pods gérés par le serveur API, et c’est précisément ce qui permet de faire tourner le control plane lui-même avant qu’un serveur API ne soit disponible. Le mirror pod visible via kubectl get pods n’est qu’un reflet en lecture seule : le supprimer via l’API ne fait rien de durable, puisque le kubelet recrée immédiatement le pod réel tant que le fichier manifeste existe. La seule action qui compte se passe sur le nœud lui-même, un détail qui évite une confusion classique lors du dépannage d’un cluster Kubernetes auto-géré.