Sécuriser Kubernetes en Production : Checklist 2026 des 15 Erreurs Fatales

Sécuriser Kubernetes en Production : Checklist 2026 des 15 Erreurs Fatales

82% des clusters Kubernetes en production contiennent au moins une vulnérabilité critique exploitable (Red Hat State of Kubernetes Security 2026). Les attaques ciblant les clusters K8s ont augmenté de +350% en 2025, avec des cryptomineurs exploitant les pods mal configurés et des ransomwares chiffrant les etcd.

Kubernetes 1.32-1.35 apporte des améliorations majeures de sécurité : Pod Security Standards (PSS) remplaçant PSP deprecated, Enhanced RBAC avec fine-grained permissions, Image signing natif avec Sigstore, mais 67% des organisations n'activent pas ces protections (CNCF Survey 2026).

Cet article technique vous guide à travers les 15 erreurs fatales à éviter absolument, avec pour chacune : l'exploitation concrète, l'impact business, et la configuration sécurisée recommandée pour 2026.

Erreur #1 : Pas de RBAC ou RBAC Trop Permissif

L'Exploitation

Configuration vulnérable :

# ❌ DANGER : ClusterRoleBinding donnant cluster-admin à tous
apiVersion: rbac.authorization.k8s.io/v1
kind:ClusterRoleBinding
metadata:
  name: default-admin
subjects:
kind: ServiceAccount
  name: default
  namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

Attaque : 1. Attaquant compromise un pod quelconque 2. ServiceAccount default a cluster-admin 3. Attaquant peut lister tous les secrets, créer pods privilégiés, modifier etcd

Impact : Contrôle total du cluster en < 5 minutes.

Configuration Sécurisée

# ✅ Principe du moindre privilège
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: app-role
  namespace: production
rules:
apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]  # Read-only sur pods seulement
apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: app-rolebinding
  namespace: production
subjects:
kind: ServiceAccount
  name: myapp-sa
  namespace: production
roleRef:
  kind: Role
  name: app-role
  apiGroup: rbac.authorization.k8s.io
---
# ServiceAccount dédié (pas default)
apiVersion: v1
kind: ServiceAccount
metadata:
  name: myapp-sa
  namespace: production
automountServiceAccountToken: false  # ✅ Désactiver si pas besoin K8s API

Audit RBAC :

# Lister tous les ClusterRoleBindings dangereux
kubectl get clusterrolebindings -o json | \
  jq '.items[] select(.roleRef.name=="cluster-admin") .metadata.name'

Erreur #2 : Pods Privilégiés en Production

L'Exploitation

# ❌ Pod privilégié = root sur le nœud
apiVersion: v1
kind: Pod
metadata:
  name: vulnerable-pod
spec:
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      privileged: true  # ❌ DANGER
      capabilities:
        add: ["SYS_ADMIN", "NET_ADMIN"]

Attaque :

# Depuis le pod privilégié
kubectl exec -it vulnerable-pod -- bash

# Accès au système de fichiers de l'hôte
ls /host/root/.ssh
cat /host/etc/shadow

Configuration Sécurisée (Pod Security Standards)

# ✅ Pod Security Standard : Restricted
apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
  labels:
    pod-security.kubernetes.io/enforce: restricted
spec:
  serviceAccountName: myapp-sa
  automountServiceAccountToken: false
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 2000
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      runAsNonRoot: true
      runAsUser: 1000
      capabilities:
        drop: ["ALL"]  # Drop toutes capabilities
    resources:
      limits:
        memory: "512Mi"
        cpu: "500m"
      requests:
        memory: "256Mi"
        cpu: "250m"

Enforcer PSS au namespace :

apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

Erreur #3 : Pas de Network Policies

L'Exploitation

Sans Network Policies : Tous les pods peuvent communiquer avec tous les autres (flat network).

Attaque : 1. Compromission d'un pod frontend 2. Pivot vers base de données directement 3. Exfiltration données

Configuration Sécurisée

# ✅ Default Deny All
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
---
# ✅ Allow Frontend → Backend seulement
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: frontend-to-backend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080
---
# ✅ Allow Backend → Database seulement
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-to-db
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: postgres
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: backend
    ports:
    - protocol: TCP
      port: 5432
---
# ✅ Egress : Allow DNS + Internet HTTPS seulement
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-https
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: kube-system
    ports:
    - protocol: UDP
      port: 53  # DNS
  - to:
    - namespaceSelector: {}
    ports:
    - protocol: TCP
      port: 443  # HTTPS externe

Erreur #4 : Secrets en Plaintext dans Git/ConfigMaps

L'Exploitation

# ❌ Secret exposé dans ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DATABASE_URL: "postgres://user:SuperSecret123@db:5432/mydb"
  API_KEY: "sk-1234567890abcdef"

Attaque : Simple kubectl get configmap → secrets exposés.

Configuration Sécurisée

Option 1 : Sealed Secrets (Bitnami) :

# Installer Sealed Secrets Controller
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml

# Créer secret chiffré
echo -n "SuperSecret123" | \
  kubectl create secret generic db-password --dry-run=client --from-file=password=/dev/stdin -o yaml | \
  kubeseal -o yaml > sealed-secret.yaml

Option 2 : External Secrets Operator (AWS Secrets Manager, Vault) :

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-credentials
  namespace: production
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets-manager
    kind: SecretStore
  target:
    name: db-credentials
    creationPolicy: Owner
  data:
  - secretKey: password
    remoteRef:
      key: prod/database/password
  - secretKey: username
    remoteRef:
      key: prod/database/username

Utilisation dans Pod :

apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  containers:
  - name: app
    image: myapp:latest
    env:
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-credentials
          key: password

Erreur #5 : Images Non Signées et Non Scannées

L'Exploitation

Attaque Supply Chain : 1. Attaquant publie image malveillante nginx:latest-backdoor 2. Développeur pull l'image (typosquatting) 3. Cryptominer s'exécute sur tous les pods

Configuration Sécurisée

Image Signing avec Sigstore/Cosign :

# Signer image
cosign sign --key cosign.key myregistry.io/myapp:v1.0.0

Policy Controller (Enforce signatures) :

apiVersion: policy.sigstore.dev/v1beta1
kind: ClusterImagePolicy
metadata:
  name: require-signed-images
spec:
  images:
  - glob: "myregistry.io/**"
  authorities:
  - keyless:
      url: https://fulcio.sigstore.dev
      identities:
      - issuer: https://token.actions.githubusercontent.com
        subject: "https://github.com/myorg/myrepo/*"

Image Scanning avec Trivy :

# Scan local
trivy image myapp:latest

Admission Controller :

# OPA Gatekeeper : Bloquer images non scannées
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sAllowedRepos
metadata:
  name: allowed-repos
spec:
  match:
    kinds:
    - apiGroups: [""]
      kinds: ["Pod"]
  parameters:
    repos:
    - "myregistry.io"  # Seulement registry interne

Erreur #6 : etcd Non Chiffré

L'Exploitation

# Si attaquant accède au nœud master
etcdctl get / --prefix --keys-only

Configuration Sécurisée

Chiffrement etcd at-rest :

# /etc/kubernetes/enc/encryption-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
resources:
  - secrets
  - configmaps
  providers:
  - aescbc:
      keys:
      - name: key1
        secret: 
  - identity: {}  # Fallback pour anciens secrets

Activer dans kube-apiserver :

# /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
  containers:
  - command:
    - kube-apiserver
    - --encryption-provider-config=/etc/kubernetes/enc/encryption-config.yaml
    volumeMounts:
    - name: enc
      mountPath: /etc/kubernetes/enc
      readOnly: true
  volumes:
  - name: enc
    hostPath:
      path: /etc/kubernetes/enc
      type: DirectoryOrCreate

Rotation clés :

# Générer nouvelle clé
head -c 32 /dev/urandom | base64

Erreur #7-15 : Checklist Rapide

#7 : Pas d'Audit Logs

# ✅ Activer audit
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
level: RequestResponse
  verbs: ["create", "update", "patch", "delete"]
  resources:
  - group: ""
    resources: ["secrets", "configmaps"]

#8 : Service Accounts Tokens Jamais Expirés

# ✅ Token expiration (K8s 1.32+)
apiVersion: v1
kind: ServiceAccount
metadata:
  name: myapp-sa
automountServiceAccountToken: false
---
# Volume projection avec expiration
volumes:
name: sa-token
  projected:
    sources:
    - serviceAccountToken:
        expirationSeconds: 3600  # 1h
        path: token

#9 : Pas de Resource Limits

# ✅ Toujours définir limits
resources:
  limits:
    memory: "512Mi"
    cpu: "500m"
  requests:
    memory: "256Mi"
    cpu: "250m"

#10 : Kubelet Anonymous Auth Activé

# ✅ Désactiver dans kubelet-config
anonymous-auth=false
authorization-mode=Webhook

#11 : Dashboard K8s Exposé Publiquement

# ✅ Désactiver ou restreindre
kubectl delete deployment kubernetes-dashboard -n kubernetes-dashboard

#12 : Pas de Pod Disruption Budgets

# ✅ PDB pour haute disponibilité
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: myapp-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: myapp

#13 : Host Path Volumes en Production

# ❌ NE JAMAIS
volumes:
name: host-data
  hostPath:
    path: /var/data

# ✅ Utiliser PVC
volumes:
name: data
  persistentVolumeClaim:
    claimName: myapp-pvc

#14 : Pas de Monitoring Sécurité

# ✅ Installer Falco
helm install falco falcosecurity/falco \
  --set falco.grpc.enabled=true \
  --set falco.grpc_output.enabled=true

#15 : Pas de Disaster Recovery

# ✅ Backup etcd quotidien
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-$(date +%Y%m%d).db \
  --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

Scanning et Audit Automatisé

Kubescape (CNCF)

# Scan complet cluster
kubescape scan --verbose

# Frameworks spécifiques
kubescape scan framework nsa  # NSA/CISA guidelines
kubescape scan framework mitre  # MITRE ATT&CK

kube-bench (CIS Benchmark)

# Audit conformité CIS
kube-bench run --targets master,node,etcd,policies

Conclusion : Sécurité K8s en 2026

82% des clusters ont des vulnérabilités critiques, mais toutes sont évitables en appliquant ces 15 bonnes pratiques. La sécurité Kubernetes n'est pas une option en 2026, c'est une nécessité business avec des attaques de plus en plus sophistiquées.

Checklist minimale production :

  • ✅ RBAC avec principe moindre privilège
  • ✅ Pod Security Standards (Restricted)
  • ✅ Network Policies (Default Deny All)
  • ✅ Secrets chiffrés (Sealed Secrets/External Secrets)
  • ✅ Images signées + scannées
  • ✅ etcd chiffré at-rest
  • ✅ Audit logs activés
  • ✅ Monitoring sécurité (Falco)

Audits réguliers :

  • Hebdomadaire : kubescape scan
  • Mensuel : kube-bench run
  • Trimestriel : Pentest externe

Pour approfondir la sécurité cloud-native, consultez nos guides sur Kubernetes pour développeurs pour les fondamentaux, ArgoCD 3.0 GitOps pour déploiements sécurisés, et sécuriser code généré par IA pour la supply chain.

Sécurité Kubernetes = RBAC + PSS + NetworkPolicies + Secrets Management + Monitoring continu.