Les meilleures pratiques en gestion des containers Kubernetes

Introduction
Gérer des containers sur Kubernetes en production est très différent de suivre un tutoriel. Après avoir opéré des clusters en production chez KNDS (défense), Okeiro (e-santé), Bloomflow (5 ans de SRE), Coopengo (HDS), et plusieurs autres, j'ai compilé les meilleures pratiques qui évitent les incidents et optimisent les coûts.
Les images de base : légèreté et sécurité
Le choix de l'image de base impacte la sécurité, la taille et le temps de démarrage. J'ai abandonné les images ubuntu et debian au profit de alpine ou des images distroless de Google. Chez Bloomflow, la migration vers des images distroless a réduit la taille des images de 350 Mo à 45 Mo et le nombre de CVE détectées par Trivy de 120 à 3. Les images distroless n'ont pas de shell, ce qui empêche un attaquant qui compromettrait le container d'exécuter des commandes. Pour le debugging en production, je déploie un pod éphémère kubectl debug avec une image contenant les outils nécessaires, plutôt que de les embarquer dans l'image de production. Cette pratique est devenue standard sur tous mes projets.
Le user non-root : une obligation
Faire tourner un container en root est une faille de sécurité majeure. Chez KNDS, les policies OPA/Gatekeeper interdisaient tout container root. Dans le Dockerfile, j'ajoute systématiquement un user dédié (USER 1000) et je vérifie que l'application fonctionne avec des permissions restreintes. Chez Okeiro en environnement e-santé, le Helm chart FHIR que j'ai développé imposait un securityContext strict : runAsNonRoot: true, readOnlyRootFilesystem: true, allowPrivilegeEscalation: false, et un profil seccomp RuntimeDefault. Ces contraintes semblent restrictives mais évitent des classes entières de vulnérabilités. Un container qui ne peut pas écrire sur son filesystem ne peut pas être utilisé pour stocker un malware.
Les labels et annotations : l'organisation du cluster
Un cluster Kubernetes sans labels cohérents devient ingérable en quelques semaines. J'applique un standard de labeling sur tous mes projets : app.kubernetes.io/name, app.kubernetes.io/version, app.kubernetes.io/component, et des labels custom comme team, environment, et cost-center. Chez F2R2, avec 25 modules Terraform et des dizaines de services EKS, ces labels permettaient de filtrer les métriques Prometheus par équipe, de calculer le coût par service via Kubecost, et de cibler les NetworkPolicies par label. Les annotations servent à stocker des métadonnées opérationnelles : le commit de déploiement, l'URL du pipeline CI, le contact de l'équipe propriétaire. En cas d'incident, ces annotations accélèrent le diagnostic.
La gestion des limites de ressources
Chaque container doit avoir des requests et des limits définis. Les requests déterminent le scheduling (sur quel node le pod sera placé), les limits protègent contre les fuites de ressources. Chez Metronome, j'avais déployé le Vertical Pod Autoscaler en mode recommandation qui analysait la consommation réelle et suggérait des ajustements. En 2 semaines de collecte, le VPA a identifié que 60% des pods étaient sur-provisionnés en CPU (requests 2x supérieures à l'utilisation réelle) et 20% sous-provisionnés en mémoire (risque d'OOM). L'ajustement a libéré 4 nodes sur 12, soit une économie de 33% sur la facture OVH. La règle que j'applique : requests = P50 de la consommation réelle, limits = P99.
Les health checks avancés
Les probes Kubernetes (liveness, readiness, startup) sont le mécanisme de base pour la résilience. Mais au-delà des simples HTTP checks, je configure des probes qui vérifient réellement la santé de l'application. Chez Cardiologs, la readiness probe vérifiait non seulement que l'API répondait, mais aussi que la connexion à PostgreSQL était active et que le worker de traitement ECG consommait bien les messages de la queue. Si la connexion à la base était perdue, le pod sortait du load balancer en quelques secondes. La liveness probe, plus agressive, redémarrait le pod si l'API ne répondait plus du tout. Cette distinction entre "je ne peux plus servir de nouvelles requêtes" (readiness) et "je suis planté" (liveness) est fondamentale pour éviter les cascades de redémarrage.
Conclusion
Les meilleures pratiques Kubernetes ne sont pas des recommandations théoriques : elles sont le fruit de dizaines d'incidents évités ou résolus en production. Images légères et non-root, labels cohérents, resources correctement dimensionnées, et health checks intelligents forment le socle d'un cluster fiable et économique. Chaque pratique est simple individuellement, mais leur combinaison systématique fait la différence entre un cluster qui tient la charge et un cluster qui s'écroule au premier pic de trafic.