Une image construite sur distroless ou scratch n’a ni shell, ni curl, ni ps, par choix de sécurité délibéré : moins de binaires embarqués, c’est moins de surface d’attaque en cas de compromission du conteneur. Le prix de ce choix se paie au moment du diagnostic : kubectl exec -it mon-pod -- sh échoue avec exec: "sh": executable file not found, précisément quand un pod se comporte mal et qu’on a le plus besoin d’y regarder de près.
Le conteneur éphémère : un outil de debug attaché à chaud
Un conteneur éphémère s’attache à un pod déjà en cours d’exécution, partage ses namespaces réseau et process, sans redémarrer aucun conteneur existant ni modifier la spec du pod de façon permanente.
kubectl debug -it mon-pod \
--image=busybox:1.36 \
--target=app-container
--target précise avec quel conteneur du pod partager l’espace de noms process : sans lui, le conteneur de debug voit ses propres processus, pas ceux du conteneur applicatif qu’on cherche justement à inspecter. Une fois attaché, la boîte à outils complète de busybox (ou n’importe quelle image de debug préférée) devient disponible, sans qu’un seul octet n’ait été ajouté à l’image de production.
Ce qui distingue un conteneur éphémère d’un exec classique
kubectl exec s’exécute dans un conteneur déjà existant, avec les seuls binaires qu’il embarque déjà. kubectl debug en ajoute un nouveau au pod, temporairement, avec l’image de son choix. C’est la différence entre chercher un outil qui n’existe pas dans une pièce vide et apporter sa propre boîte à outils sans avoir à déménager la pièce.
Copier un pod entier pour un debug plus invasif
Certains diagnostics demandent de modifier des variables d’environnement ou d’ajouter des capacités système que le pod original n’a pas : kubectl debug propose alors de créer une copie du pod plutôt que d’y attacher un conteneur éphémère.
kubectl debug mon-pod -it \
--copy-to=mon-pod-debug \
--container=app-container \
--set-image=app-container=mon-image:debug
Cette copie tourne en parallèle de l’original, laissé intact, ce qui permet d’expérimenter (changer une image, ajouter une capacité) sans jamais risquer le pod de production lui-même. Une fois le diagnostic terminé, la copie se supprime, sans laisser de trace sur le pod original.
Déboguer un nœud directement
Le même mécanisme s’étend au nœud lui-même, utile quand le problème n’est pas dans un pod mais dans le nœud qui l’héberge :
kubectl debug node/mon-noeud -it --image=busybox:1.36
Cette commande crée un pod privilégié sur le nœud ciblé, avec son système de fichiers monté sous /host, ce qui permet d’inspecter directement l’état du nœud (logs système, configuration réseau) sans passer par SSH quand l’accès SSH n’est pas configuré ou disponible.
Ce que ça change à la stratégie d’image
Savoir que kubectl debug existe change le calcul de sécurité autour des images minimales : la peur de « ne plus pouvoir déboguer » qui pousse certaines équipes à garder un shell dans leurs images de production (au prix d’une surface d’attaque plus large) n’a plus de justification technique une fois qu’un outil de diagnostic à chaud, entièrement séparé de l’image elle-même, est disponible.
À retenir
Une image distroless sans shell n’est pas un obstacle au diagnostic, seulement l’absence d’un shell qu’on n’a jamais besoin d’embarquer en production. Les conteneurs éphémères attachent un outillage de debug complet à un pod déjà en cours d’exécution, sans le redémarrer ; --copy-to permet un debug plus invasif sans jamais risquer l’original ; le même mécanisme s’étend aux nœuds eux-mêmes. Ce réflexe complète directement les outils de diagnostic déjà mentionnés dans l’entrée glossaire sur CrashLoopBackOff, pour les cas où l’image elle-même ne laisse aucun accès direct. Réduire la surface d’attaque des images tout en gardant un vrai outillage de diagnostic fait partie de ce qui se pose dès l’industrialisation d’une chaîne CI/CD.