Sécurité Docker et Kubernetes : conteneurs sécurisés et cluster défendable
Docker encapsule votre application et ses dépendances dans une image immuable ; Kubernetes orchestre ces conteneurs à l’échelle du cluster. Ensemble, ils simplifient le déploiement — mais une mauvaise configuration peut transformer un simple conteneur en pivot pour attaquer le reste de l’infrastructure. Ce guide pose les bases de la sécurité Docker, de la sécurité Kubernetes et d’un cluster sécurisé, pour développeurs et DevOps débutants à intermédiaires, avec des exemples concrets et des scénarios d’attaque réalistes.
Il complète les autres volets d’OmbreLoup Sec : DevSecOps Basics, sécurité API, CI/CD sécurisé et outillage.
Pourquoi sécuriser Docker et Kubernetes est critique
Un conteneur n’est pas une machine virtuelle complète : il partage le noyau de l’hôte. Si un processus root dans le conteneur exploite une faille du runtime ou du noyau, les conséquences peuvent dépasser le simple pod. Côté Kubernetes, le plan de données (kubelet, CNI, stockage) et le plan de contrôle concentrent les secrets de l’organisation : tokens de service, certificats, accès au cloud.
Sans isolation ni contrôle d’accès, une compromission — image trojanisée, credential volé, NetworkPolicy absente — permet souvent une élévation de privilèges ou un mouvement latéral entre namespaces. Les rapports d’incidents montrent régulièrement des clusters exposés sur Internet (API server, dashboards) ou des workloads over-privileged qui facilitent la prise d’empreinte du cluster.
En résumé : sécuriser Docker réduit la surface dans chaque image ; sécuriser Kubernetes structure la défense en profondeur (identité, réseau, politiques de pods). Les deux s’alignent avec une approche DevSecOps : la même image doit être scannée en CI (pipeline sécurisé) et durcie au runtime.
Comprendre Docker : image, runtime et surface d’attaque
Une image est empilée de couches en lecture seule ; un conteneur est une instance exécutable de cette image. La sécurité Docker commence par ce que vous mettez dans l’image et comment le processus tourne.
Pourquoi éviter l’utilisateur root dans le conteneur
Par défaut, beaucoup d’images historiques lancent le processus en root (UID 0). En cas de vulnérabilité applicative ou de mauvaise isolation du runtime, un attaquant part avec les privilèges maximum à l’intérieur du conteneur — ce qui facilite l’élévation vers l’hôte selon le contexte (capabilities, montages).
Créer un utilisateur dédié et basculer avec USER limite ce que le processus peut faire même si le code est compromis :
FROM node:20-alpine
RUN addgroup -g 1001 app && adduser -u 1001 -G app -D app
WORKDIR /app
COPY --chown=app:app . .
USER app
CMD ["node", "index.js"]
Sur Kubernetes, combinez cela avec Pod Security Standards (profil restricted) pour refuser les pods qui exigent root ou des capabilities dangereuses.
Images minimales et surface d’attaque
Chaque paquet inutile dans l’image est une CVE potentielle. Les images Alpine, distroless ou les images « slim » réduisent les binaires présents : moins de shell, moins d’outils pour un attaquant, moins de mises à jour à suivre. Ce n’est pas de l’esthétique : c’est une réduction mesurable de la surface d’attaque pour des conteneurs sécurisés.
Scanner les images (Trivy) et intégrer le secret hors de l’image
Avant de pousser vers un registry, analysez l’image avec Trivy (ou équivalent) :
trivy image --exit-code 1 --severity HIGH,CRITICAL myapp:latest
Les secrets (clés API, PEM) ne doivent jamais être copiés dans l’image : utilisez des variables d’environnement injectées au runtime, Kubernetes Secrets (idéalement chiffrés au repos avec KMS ou external-secrets / Vault), ou des références au secret manager de votre cloud. Une image publiée avec un .env embarqué est une fuite en attente.
Kubernetes : un cluster sécurisé repose sur l’identité, le réseau et les politiques
RBAC : qui peut faire quoi dans le cluster
Le RBAC (Role-Based Access Control) lie des Roles (ou ClusterRoles) à des sujets (User, ServiceAccount) via des RoleBindings. Sans RBAC strict, un compte de déploiement peut par exemple lire tous les secrets du cluster — scénario classique après vol de token.
Exemple minimal : lecture seule sur un namespace pour un outil d’observabilité :
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: reader
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list", "watch"]
Principe : moindre privilège — accorder uniquement les verbs et resources nécessaires ; les ServiceAccounts par défaut ne doivent pas avoir des droits étendus « pour faire vite ».
Network Policies : isolation des workloads (cas concret)
Sans NetworkPolicy, tout pod peut généralement joindre tout autre pod sur le réseau overlay : un conteneur compromis (web vulnérable) peut scanner le réseau et atteindre une base de données ou l’API Kubernetes.
Cas concret : un namespace frontend ne doit parler qu’au service api sur le port 8080 ; la base postgres n’accepte que le trafic depuis les pods avec le label role=api.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
Une politique « deny all » par défaut, puis des règles explicites par application, segmentent les workloads et limitent la propagation après compromission.
Pod Security Standards et secrets
Les Pod Security Standards (profils privileged, baseline, restricted) s’appliquent au niveau namespace : par exemple restricted impose utilisateur non-root, pas de montage sensible arbitraire, etc.
Pour les Secrets Kubernetes : préférez le chiffrement au repos (etcd chiffré, KMS), rotation, et évitez de monter des secrets en clair dans des volumes partagés sans besoin. Les applications exposées en HTTP doivent aussi suivre les bonnes pratiques sécurité API — le conteneur sain ne remplace pas TLS ni auth applicative.
Cas d’attaque réels (simplifiés)
Conteneur compromis via image ou vulnérabilité
Une image tirée d’un registry public est trojanisée ou une CVE critique dans une lib système permet l’exécution de code. Sans réseau segmenté, le malware tente la sortie vers Internet ou le mouvement latéral. Réponse : images signées, scans, NetworkPolicy, runtime security (Falco, etc. — voir outils).
Élévation de privilèges
Un pod monté avec privileged: true ou avec toutes les capabilities peut faciliter l’échappement vers le nœud. Les politiques PSS et des SecurityContext stricts (runAsNonRoot, readOnlyRootFilesystem quand possible) réduisent cette surface.
Mauvaise configuration Kubernetes
API Server exposé, kubeconfig commité, dashboard non protégé : autant de portes ouvertes documentées dans la littérature offensive. Durcissement du plan de contrôle, authentification forte pour l’accès humain et audit des kubectl sont indispensables pour un cluster sécurisé.
Erreurs fréquentes
- Déployer en root « parce que ça marchait en local ».
- Utiliser la tag
latestsans traçabilité ni rebuild systématique après correctif. - Pas de NetworkPolicy : tout le monde parle à tout le monde sur le réseau des pods.
- Secrets en clair dans les manifests Git ou dans l’image Docker.
- RBAC trop large pour les CI/CD ou les outils externes (token avec
cluster-admin« pour aller vite »). - Négliger la sécurité du pipeline qui construit les images (CI/CD).
Bonnes pratiques avancées : isolation et défense en profondeur
- Namespaces par équipe ou par environnement, quotas et limites pour éviter la consommation abusive.
- Admission controllers (OPA Gatekeeper, Kyverno) pour imposer labels, images autorisées, profils PSS.
- Workload identity : lier les pods à des rôles IAM du cloud sans injecter de clés longue durée.
- Mises à jour du cluster et du CRI (containerd, etc.) pour corriger les failles du runtime.
- SBOM et politique de bases d’images approuvées en entreprise.
Ces pratiques renforcent l’isolation des workloads : chaque application vit dans une « bulle » définie par identité, réseau et politique de pod — exactement ce qu’attend un modèle DevSecOps mature, décrit dans nos fondamentaux.
Conclusion
La sécurité Docker et la sécurité Kubernetes se construisent couche par couche : images minimales et scannées, processus non-root, secrets hors des images, RBAC minimal, Network Policies explicites, Pod Security Standards et cluster à jour. Ce n’est pas une liste de cases à cocher pour un audit : c’est une façon de livrer des conteneurs sécurisés sans figer la vélocité des équipes.
Pour aller plus loin sur OmbreLoup Sec : DevSecOps Basics, Sécurité API, CI/CD Security et Outils & Ressources (Trivy, kube-bench, Falco, politiques, etc.).