Le 1ᵉʳ juillet 2026, le projet containerd a publié cinq bulletins de sécurité qui concernent directement les clusters Kubernetes déployés en Europe. Cinq CVE, dont deux notées CRITICAL avec un score CVSS 3.1 grimpant jusqu’à 9.9, touchent le plugin CRI utilisé par la quasi-totalité des installations EKS, GKE, AKS et des clusters on-premise sous containerd. Le point commun de ces failles : la fonctionnalité de checkpoint/restore, encore récente dans containerd, qui permet à un attaquant disposant de simples droits de création de pod d’empoisonner le cache d’images d’un nœud, d’exécuter du code sur l’hôte ou de lire des fichiers arbitraires. Ce tutoriel détaille, en douze étapes concrètes, comment auditer vos nœuds, appliquer les correctifs et durcir un cluster Kubernetes avant la sortie de la version 1.37, dont le calendrier de sortie communiqué par le projet vise fin août 2026.

Pourquoi les CVE containerd de juillet 2026 changent la donne pour Kubernetes

La plupart des alertes de sécurité Kubernetes visent le plan de contrôle : kube-apiserver, etcd, ou les webhooks d’admission. Cette fois, le problème se situe une couche plus bas, dans le runtime de conteneurs lui-même. Containerd exécute les conteneurs sur chaque nœud, sous kubelet, et c’est précisément là que se trouvent les cinq failles publiées début juillet. Une politique RBAC stricte ou une NetworkPolicy bien pensée ne suffit pas à s’en protéger, puisque l’attaque exploite directement le processus containerd, pas l’API Kubernetes.

Les cinq vulnérabilités touchent les branches containerd 1.7, 2.0, 2.1, 2.2 et 2.3, soit pratiquement toutes les versions activement maintenues à la date de publication. Le vecteur commun reste la fonction de checkpoint/restore, qui permet de figer l’état d’un conteneur puis de le relancer ailleurs. Cette capacité s’appuie sur le feature gate Kubernetes ContainerCheckpoint, passé au stade Beta depuis la version 1.30. Beaucoup d’équipes ignorent qu’il est disponible sur leur cluster, ce qui rend l’audit d’autant plus nécessaire.

Le risque grimpe fortement sur les clusters multi-tenants, où plusieurs équipes ou clients partagent les mêmes nœuds. C’est exactement le scénario visé par la CVE la plus sévère du lot, qui permet à un pod malveillant d’empoisonner le cache d’images partagé par d’autres pods sur le même nœud. Sur un cluster EKS ou GKE où des équipes distinctes déploient leurs propres charges de travail sur des node pools communs, la surface d’attaque est réelle dès aujourd’hui, pas seulement théorique.

Red Hat référence également ces mêmes CVE dans sa propre base de sécurité, ce qui confirme leur impact sur OpenShift et les distributions Enterprise Linux qui embarquent containerd. Pour une équipe plateforme qui gère à la fois des clusters EKS et des clusters OpenShift on-premise, cela veut dire une seule et même campagne de correctifs à mener des deux côtés, avec les mêmes numéros de version cibles. Ne traitez pas ces environnements comme deux problèmes distincts, le runtime sous-jacent et le correctif sont identiques.

Les 5 vulnérabilités containerd CVE-2026 à connaître absolument

Chaque CVE a été publiée le 1ᵉʳ juillet 2026 et documentée dans la base NVD. Voici le résumé des cinq failles, classées par score CVSS 3.1 décroissant.

CVECVSS 3.1ImpactVersions corrigées
CVE-2026-501959.9 CRITICALEmpoisonnement du cache d’images via un checkpoint non validé, exécution de code entre pods2.3.2, 2.2.5, 2.1.9
CVE-2026-534929.6 CRITICALAnnotations CDI d’un checkpoint non fiable acceptées telles quelles, injection de périphériques et de montages hôte2.3.2, 2.2.5, 2.1.9
CVE-2026-534888.8 HIGHLabels d’image (instruction LABEL) propagés sans validation, exécution de commande arbitraire sur l’hôte1.7.33, 2.3.2, 2.2.5, 2.1.9, 2.0.10
CVE-2026-534896.5 MEDIUMRestauration de container.log via un lien symbolique non validé, lecture de fichier arbitraire sur l’hôte via kubectl logs2.3.2, 2.2.5, 2.1.9
CVE-2026-472625.5 MEDIUMImage forgée provoquant un épuisement mémoire, déni de service par OOM kill de containerd1.7.33, 2.0.10, 2.1.9, 2.2.5, 2.3.2

Trois de ces cinq failles partagent le même point d’entrée : un checkpoint image forgé, importé par un attaquant qui dispose du droit de créer des pods. C’est un détail important, parce que ce droit est souvent accordé assez largement dans les pipelines CI/CD, aux comptes de service de déploiement, ou aux développeurs sur des clusters de préproduction. Un audit RBAC de qui peut créer des pods, combiné à la vérification de votre version de containerd, constitue donc le point de départ logique de ce guide, avant même de toucher aux nœuds.

Prérequis techniques avant de commencer

Avant de démarrer, réunissez les éléments suivants. Le tutoriel suppose un cluster Kubernetes en version 1.32 ou supérieure (les branches activement supportées à ce jour sont 1.32 à 1.36), avec containerd comme runtime de conteneurs sur les nœuds.

Comptez une trentaine de minutes pour valider l’ensemble de la procédure sur un premier nœud de test, du diagnostic initial jusqu’à la vérification finale. Le reste dépend ensuite de la taille de votre flotte et de votre stratégie de rolling update. Gardez également à portée de main la documentation officielle du feature d’audit des CVE Kubernetes, qui centralise les avis de sécurité publiés par le projet et facilite le suivi si de nouvelles failles apparaissent après la publication de ce guide.

  • Accès kubectl avec des droits cluster-admin, ou au minimum les permissions nécessaires pour lister les nœuds, gérer les namespaces et les objets RBAC
  • Accès SSH ou SSM aux nœuds, sauf si vous gérez un cluster entièrement managé via node pool (auquel cas vous mettrez à jour l’image de nœud plutôt que containerd directement)
  • containerd en version corrigée pour votre branche : 1.7.33, 2.0.10, 2.1.9, 2.2.5 ou 2.3.2 minimum (la branche 2.3.4 et la 2.4.0 sont disponibles et recommandées si vous migrez)
  • Les outils crictl et ctr installés sur au moins un nœud de test
  • Une sauvegarde etcd récente et un cluster de staging pour valider les changements avant la production
  • cosign (projet Sigstore) si vous comptez signer vos images à l’étape 10
  • Une fenêtre de maintenance planifiée, ou une stratégie de rolling update nœud par nœud si votre cluster ne peut pas tolérer d’interruption

Étape 1 : identifier la version de containerd sur chaque nœud

Commencez par un inventaire complet. Sur un nœud accessible en SSH, la commande la plus directe reste containerd --version. Sur un cluster entier, il est plus rapide de passer par crictl, déjà présent sur la plupart des images de nœud Kubernetes.

# Sur un nœud, en SSH
containerd --version
crictl version

# Depuis un poste avec accès à tous les nœuds via kubectl debug
kubectl get nodes -o name | while read node; do
  echo "=== $node ==="
  kubectl debug "$node" -it --image=busybox -- chroot /host containerd --version
done

Notez chaque version dans un tableau, avec le node pool ou le groupe d’auto-scaling correspondant. Sur les clusters managés (EKS, GKE, AKS), la version de containerd dépend directement de l’image de nœud (AMI, node image, VHD). Consultez les notes de version de votre fournisseur pour savoir si votre AMI ou votre node pool embarque déjà une version corrigée avant de lancer un patch manuel qui pourrait entrer en conflit avec la prochaine mise à jour d’image gérée par le fournisseur.

Étape 2 : vérifier l’exposition réelle de votre cluster

Toutes les failles ne s’appliquent pas de la même façon selon votre configuration. Les CVE liées au CDI (CVE-2026-53492) ne concernent que les nœuds où le Container Device Interface est activé, typiquement les clusters GPU ou avec des périphériques matériels partagés. Si vous ne gérez aucun device plugin custom, cette faille précise est moins prioritaire, mais reste à corriger dès que possible puisqu’une mise à jour de containerd corrige les cinq d’un coup.

Vérifiez également qui peut créer des pods sur le cluster. C’est le prérequis commun à trois des cinq CVE. Un audit rapide des RoleBindings et ClusterRoleBindings donne une première photographie de l’exposition réelle, bien plus utile qu’une simple lecture du score CVSS hors contexte.

Le tableau suivant résume, branche par branche, le seuil de version en dessous duquel un nœud reste exposé. Comparez-le à l’inventaire relevé à l’étape 1 pour prioriser vos mises à jour, en commençant par les node pools qui hébergent des charges de travail multi-tenants ou exposées à Internet.

Branche containerdVulnérable si version <Version corrigéeRemarque
1.7.x1.7.331.7.33Branche encore largement déployée sur des clusters plus anciens
2.0.x2.0.102.0.10Migration vers 2.1 ou 2.3 recommandée à moyen terme
2.1.x2.1.92.1.9Non concernée par CVE-2026-53488 avant 2.1.9
2.2.x2.2.52.2.5 (2.2.7 disponible)Préférez la dernière version mineure disponible
2.3.x2.3.22.3.2 (2.3.4 disponible)Branche la plus récente, alignée avec Kubernetes 1.36

Si votre inventaire fait apparaître plusieurs branches différentes sur un même cluster, ce qui arrive souvent après des années d’ajouts successifs de node pools, traitez chaque branche séparément plutôt que de chercher à toutes les aligner sur la même version en une seule campagne. La priorité reste de sortir chaque nœud de la zone vulnérable, pas d’unifier les branches.

kubectl get clusterrolebindings -o json | \
  jq -r '.items[] | select(.roleRef.name=="cluster-admin") | .subjects[]?.name'

kubectl auth can-i create pods --all-namespaces --as=system:serviceaccount:ci:deployer

Étape 3 : planifier la fenêtre de maintenance et sauvegarder l’état du cluster

Une mise à jour de containerd redémarre le runtime, ce qui interrompt brièvement les conteneurs en cours d’exécution sur le nœud concerné. Sur un cluster de production, procédez nœud par nœud avec kubectl drain, jamais en mise à jour simultanée sur toute la flotte. Prenez aussi un instantané etcd avant de commencer, au cas où une modification RBAC ou une politique d’admission mal configurée bloquerait des déploiements légitimes.

etcdctl snapshot save /backup/etcd-pre-durcissement-$(date +%F).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

Étape 4 : mettre à jour containerd vers une version corrigée

Sur des nœuds Ubuntu ou Debian gérés en dehors d’un provider managé, la mise à jour passe par le gestionnaire de paquets ou par le binaire officiel publié sur le dépôt GitHub du projet. Ciblez au minimum les versions corrigées listées plus haut, ou la dernière version de votre branche si vous préférez rester sur un cycle de correctifs plus court.

# Vérifier la version disponible dans les dépôts
apt-cache policy containerd.io

# Mettre à jour vers la version corrigée
sudo apt-get update
sudo apt-get install --only-upgrade containerd.io

# Sur RHEL / distributions dérivées
sudo dnf update containerd.io

Sur EKS, GKE ou AKS, préférez la mise à jour de l’image de nœud plutôt qu’un patch manuel du binaire, qui serait écrasé à la prochaine rotation gérée par le fournisseur. Vérifiez les notes de version de l’AMI EKS optimisée, de l’image de nœud GKE ou du VHD AKS pour confirmer qu’elle embarque une version containerd corrigée, puis déclenchez un remplacement de node pool.

Étape 5 : redémarrer et valider le service sur chaque nœud

Une fois le paquet mis à jour, redémarrez le service et confirmez que containerd répond correctement avant de décordonner le nœud. Un redémarrage silencieusement échoué laisse le nœud à moitié fonctionnel, ce qui complique le diagnostic plus tard.

kubectl drain node-01 --ignore-daemonsets --delete-emptydir-data

sudo systemctl restart containerd
sudo systemctl status containerd --no-pager
crictl info | grep -A2 '"version"'

kubectl uncordon node-01

Sortie attendue de crictl info après une mise à jour réussie :

{
  "status": {
    "conditions": [
      {"type": "RuntimeReady", "status": true},
      {"type": "NetworkReady", "status": true}
    ]
  },
  "runtimeVersion": "2.3.4",
  "runtimeApiVersion": "v1"
}

Étape 6 : désactiver le Container Device Interface si vous ne l’utilisez pas

CVE-2026-53492 exploite spécifiquement les annotations CDI héritées d’un checkpoint. Si votre cluster n’utilise pas de device plugin s’appuyant sur CDI (typiquement pour des GPU ou du matériel spécialisé), le plus simple reste de désactiver la fonctionnalité dans la configuration containerd, sur le fichier /etc/containerd/config.toml.

[plugins."io.containerd.grpc.v1.cri"]
  enable_cdi = false
  cdi_spec_dirs = ["/etc/cdi", "/var/run/cdi"]

Si vous dépendez du CDI pour des GPU NVIDIA ou tout autre périphérique, laissez-le activé mais assurez-vous que la mise à jour de containerd de l’étape 4 est bien appliquée. C’est le correctif du plugin CRI qui empêche l’acceptation d’annotations CDI provenant d’un checkpoint non fiable, pas la désactivation de la fonctionnalité elle-même.

Étape 7 : restreindre l’API de checkpoint du kubelet

Le feature gate ContainerCheckpoint, en Beta depuis Kubernetes 1.30, expose une sous-ressource de checkpoint sur l’API du kubelet. Si votre équipe n’utilise pas cette fonctionnalité pour de la migration à chaud ou du debug avancé, le plus sûr est de la laisser désactivée explicitement au niveau du kubelet, ou de restreindre par RBAC les comptes de service autorisés à déclencher un checkpoint.

# Extrait de KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
featureGates:
  ContainerCheckpoint: false

Si vous en avez besoin en environnement de debug, limitez son usage aux namespaces d’observabilité, avec un Role dédié, plutôt que de l’ouvrir cluster-wide via un ClusterRole.

Étape 8 : isoler le cache d’images avec une politique de pull stricte

CVE-2026-50195 profite d’un cache d’images partagé entre pods d’un même nœud, combiné à une politique imagePullPolicy: IfNotPresent ou Never. Sur les nœuds multi-tenants, forcer Always réduit fortement la fenêtre d’exploitation, puisque chaque pull revérifie l’image auprès du registre plutôt que de faire confiance au tag local.

apiVersion: v1
kind: Pod
metadata:
  name: exemple-durci
spec:
  containers:
    - name: app
      image: registry.exemple.eu/app:1.4.2
      imagePullPolicy: Always

Complétez avec une NetworkPolicy par défaut qui bloque le trafic sortant non nécessaire, ce qui limite les conséquences d’une exécution de code obtenue via CVE-2026-53488 même si le correctif n’a pas encore été déployé sur tous les nœuds pendant la fenêtre de rollout.

Étape 9 : déployer Pod Security Admission au niveau du namespace

Pod Security Admission, intégré nativement depuis plusieurs versions de Kubernetes, remplace l’ancien PodSecurityPolicy et s’applique par simple label de namespace. Le niveau restricted bloque les conteneurs privilégiés, les montages hostPath non nécessaires et l’exécution en root, ce qui réduit l’impact d’une éventuelle exécution de code sur l’hôte.

kubectl label namespace production \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/enforce-version=latest \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/warn=restricted

Déployez d’abord en mode audit et warn seuls sur un namespace de test, observez les violations dans les logs pendant quelques jours, puis passez en enforce une fois les workloads non conformes corrigés. Passer directement en enforce sur un namespace de production sans cette étape intermédiaire est l’une des erreurs les plus fréquentes, détaillée plus bas.

Étape 10 : corriger les configurations RBAC trop permissives

Puisque trois des cinq CVE nécessitent uniquement le droit de créer des pods, resserrer le RBAC réduit directement la surface d’attaque, indépendamment du patch containerd. Listez tous les comptes de service disposant de create sur les pods au niveau cluster, puis remplacez les ClusterRoleBindings larges par des RoleBindings scopés au namespace.

kubectl get clusterroles -o json | \
  jq -r '.items[] | select(.rules[]?.resources[]? == "pods") | .metadata.name'

# Exemple de correction : remplacer un ClusterRoleBinding par un RoleBinding namespacé
kubectl delete clusterrolebinding ci-deployer-global
kubectl create rolebinding ci-deployer \
  --clusterrole=edit \
  --serviceaccount=ci:deployer \
  --namespace=staging

Étape 11 : signer et vérifier vos images avec Cosign

La signature d’images ne corrige pas directement les CVE containerd, mais elle empêche qu’une image de checkpoint ou une image applicative forgée entre dans votre chaîne de déploiement sans passer par votre pipeline CI/CD officiel. Le projet Sigstore, avec son outil cosign, s’est imposé comme référence pour la signature et la vérification d’images de conteneurs.

# Signer une image après build, dans le pipeline CI
cosign sign --key cosign.key registry.exemple.eu/app:1.4.2

# Vérifier la signature avant déploiement, côté admission controller ou en local
cosign verify --key cosign.pub registry.exemple.eu/app:1.4.2

Combinez cette vérification avec un admission controller qui refuse tout pod dont l’image n’est pas signée par votre clé d’entreprise. Cela ferme une bonne partie de la chaîne d’attaque qui repose sur des images de checkpoint ou des images applicatives non fiables.

Pour les équipes qui débutent avec la signature d’images, commencez par un registre unique et une seule équipe pilote plutôt qu’un déploiement cluster-wide immédiat. La gestion des clés, leur rotation, et la synchronisation entre le pipeline CI et l’admission controller demandent une période de rodage avant d’être appliquées à l’ensemble des namespaces de production.

Étape 12 : surveiller le runtime avec Falco et les logs d’audit

Le patch et le durcissement ne remplacent pas la détection. Falco, projet open source dédié à la sécurité runtime des conteneurs, surveille les appels système au niveau du noyau et peut détecter des comportements caractéristiques d’une tentative d’exploitation, comme un processus containerd qui ouvre un fichier hors de son espace attendu ou un conteneur qui tente un montage hostPath imprévu.

# Règle Falco simplifiée : détecter un accès en lecture hors périmètre attendu
- rule: Lecture de fichier host suspecte via containerd
  desc: Détecte une lecture de fichier hôte potentiellement liée à un checkpoint malveillant
  condition: >
    open_read and container and
    fd.name startswith /host and
    proc.name = "containerd-shim"
  output: >
    Lecture fichier hôte suspecte (fichier=%fd.name conteneur=%container.name)
  priority: WARNING

Activez également les logs d’audit Kubernetes sur les verbes create et update pour la sous-ressource checkpoint, afin de garder une trace exploitable en cas d’incident, même après avoir restreint l’accès à l’étape 7.

Vérifier votre travail : à quoi ressemble un cluster durci

Une fois les douze étapes appliquées, un audit rapide doit confirmer trois points : la version de containerd sur chaque nœud correspond à une version corrigée, les namespaces sensibles portent le label pod-security.kubernetes.io/enforce=restricted, et plus aucun ClusterRoleBinding large ne permet la création de pods à un compte de service générique.

kubectl get nodes -o custom-columns=NAME:.metadata.name,CONTAINERD:.status.nodeInfo.containerRuntimeVersion

# Sortie attendue
NAME       CONTAINERD
node-01    containerd://2.3.4
node-02    containerd://2.3.4
node-03    containerd://2.3.4

Si un nœud affiche encore une version antérieure à 2.3.2, 2.2.5, 2.1.9, 2.0.10 ou 1.7.33 selon sa branche, il reste exposé et doit repasser par l’étape 4.

Prévoyez aussi un contrôle applicatif, pas seulement une vérification de version. Déployez un pod de test avec un securityContext délibérément non conforme (root, capacité SYS_ADMIN, montage hostPath) dans un namespace protégé par Pod Security Admission, et confirmez qu’il est bien rejeté à la création. Un rejet immédiat, visible dans la sortie de kubectl apply, est la meilleure preuve que votre politique fonctionne réellement, plutôt qu’une simple présence du label sur le namespace.

Projet complet : manifeste Kubernetes durci prêt à l’emploi

Voici un manifeste qui rassemble les principaux réflexes de durcissement abordés dans ce guide : image pull strict, exécution non privilégiée, filesystem en lecture seule, et une NetworkPolicy qui limite le trafic sortant. À adapter à votre application, mais utilisable comme base de référence pour vos nouveaux déploiements.

apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: latest
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-durci
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: app-durci
  template:
    metadata:
      labels:
        app: app-durci
    spec:
      automountServiceAccountToken: false
      containers:
        - name: app
          image: registry.exemple.eu/app:1.4.2
          imagePullPolicy: Always
          securityContext:
            runAsNonRoot: true
            runAsUser: 10001
            readOnlyRootFilesystem: true
            allowPrivilegeEscalation: false
            capabilities:
              drop: ["ALL"]
          resources:
            limits:
              memory: "512Mi"
              cpu: "500m"
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: app-durci-egress
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: app-durci
  policyTypes: ["Egress"]
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
      ports:
        - protocol: UDP
          port: 53

6 erreurs fréquentes qui annulent votre durcissement

Patcher containerd sans redémarrer le kubelet. Le nouveau binaire est en place, mais le processus en cours d’exécution charge toujours l’ancienne version tant que le service n’a pas été relancé proprement. Vérifiez toujours crictl info après coup.

Mettre à jour l’AMI EKS sans remplacer les nœuds existants. Changer la version de lancement d’un node group ne met pas à jour les instances déjà en service. Il faut déclencher un rolling replace explicite, sans quoi les anciens nœuds restent vulnérables des semaines après le patch.

Passer Pod Security Admission en enforce directement en production. Sans phase d’audit préalable, des workloads legacy tournant en root ou avec un montage hostPath se retrouvent bloqués sans préavis, souvent en pleine nuit lors d’un déploiement automatisé.

Oublier les node pools de staging et de CI. Ces clusters secondaires sont souvent négligés lors des campagnes de patch, alors qu’ils accordent fréquemment des droits de création de pod plus larges qu’en production, exactement le prérequis des CVE les plus critiques.

Désactiver le CDI sans vérifier les device plugins existants. Sur un cluster GPU, couper enable_cdi sans transition casse silencieusement l’allocation de GPU aux pods qui en dépendent. Testez toujours sur un node pool non critique d’abord.

Considérer le patch containerd comme suffisant à lui seul. La mise à jour ferme les CVE connues, mais un cluster avec un RBAC trop permissif reste vulnérable à la prochaine faille de ce type. Le RBAC restrictif et Pod Security Admission sont des filets de sécurité indépendants du patch, pas des options facultatives.

Dépannage : 8 problèmes courants et leurs solutions

containerd refuse de redémarrer après la mise à jour. Vérifiez la syntaxe de /etc/containerd/config.toml avec containerd config dump. Une clé mal indentée après une modification manuelle suffit à bloquer le démarrage.

Les pods restent en ContainerCreating après le redémarrage. Le kubelet a parfois besoin d’un redémarrage lui aussi pour rétablir la connexion gRPC au socket containerd. Un systemctl restart kubelet après containerd résout la majorité des cas.

crictl renvoie une erreur de connexion au socket. Vérifiez que le chemin du socket dans /etc/crictl.yaml correspond bien à celui de votre nouvelle installation, notamment après une migration de branche majeure de containerd.

Des pods sont rejetés massivement après l’activation de pod-security.kubernetes.io/enforce=restricted. Repassez temporairement en audit et warn, consultez les événements du namespace pour identifier les violations, corrigez les securityContext des workloads concernés, puis réactivez enforce.

Un device plugin GPU ne détecte plus les GPU après désactivation du CDI. Réactivez enable_cdi = true et confirmez plutôt que la version containerd corrigée est bien en place. La CVE liée au CDI est neutralisée par le patch, pas nécessairement par la désactivation de la fonctionnalité.

Le pipeline CI échoue après la restriction RBAC des comptes de service. Le compte de service de déploiement a probablement perdu un droit dont il avait réellement besoin. Utilisez kubectl auth can-i --list --as=system:serviceaccount:ci:deployer pour comparer les droits avant et après la modification, plutôt que de rouvrir un ClusterRoleBinding large par réflexe.

La vérification Cosign échoue en admission alors que l’image est légitime. Vérifiez que la clé publique déployée sur l’admission controller correspond bien à la dernière rotation de clé côté CI. Les rotations de clé Cosign non synchronisées entre pipeline et cluster sont une cause fréquente de faux rejets.

Falco génère un volume d’alertes ingérable après déploiement. Commencez par les règles fournies par défaut en mode WARNING, désactivez les règles trop bruyantes pour votre environnement, puis n’ajoutez des règles personnalisées comme celle de l’étape 12 qu’une fois le bruit de fond sous contrôle.

Le remplacement de node pool EKS ou GKE prend beaucoup plus de temps que prévu. Un rolling replace respecte les PodDisruptionBudgets et attend que chaque pod retrouve un nœud disponible avant de continuer. Si vos budgets de disruption sont trop stricts par rapport à la taille réelle du node pool, la campagne peut se bloquer à mi-parcours. Desserrez temporairement les PodDisruptionBudgets non critiques le temps du remplacement, plutôt que d’interrompre la procédure en urgence.

Astuces avancées pour les équipes plateforme

Pour les équipes qui gèrent plusieurs clusters, automatisez l’inventaire de version containerd dans votre pipeline d’observabilité plutôt que de le vérifier manuellement à chaque alerte CVE. Un exportateur Prometheus qui expose containerRuntimeVersion par nœud, croisé avec une règle d’alerte sur les versions non corrigées, transforme un audit ponctuel en contrôle continu.

Sur les clusters où le feature gate ContainerCheckpoint est réellement utilisé pour du debug avancé, envisagez un cluster dédié à cet usage plutôt que de l’autoriser sur votre cluster de production. Cela isole complètement la surface d’attaque liée au checkpoint/restore du reste de vos charges de travail critiques.

Enfin, intégrez la vérification de version containerd directement dans votre outil de conformité (OPA/Gatekeeper ou Kyverno), sous forme de politique qui refuse tout nouveau nœud dont la version de runtime est antérieure à votre seuil de sécurité. Cela empêche un node pool mal configuré de réintroduire une version vulnérable après votre campagne de patch initiale.

Documentez chaque changement dans un registre de conformité interne, avec la date de correction par node pool et la version cible atteinte. En cas d’audit de sécurité ou de question client sur votre posture face à ces CVE, un tableau de suivi à jour vaut largement mieux qu’une reconstitution a posteriori à partir des logs de déploiement, souvent incomplets plusieurs mois après les faits.

Bonus : le durcissement des runtimes ne s’arrête pas à Kubernetes

La même discipline de patch s’applique aux fonctions serverless. AWS documente actuellement des runtimes Lambda basés sur Amazon Linux 2023 pour Node.js 24 (identifiant nodejs24.x, dépréciation prévue le 30 avril 2028), ainsi que Java 25 et Java 21 sur AL2023, avec une dépréciation fixée au 30 juin 2029. Java 17, 11 et 8 restent également disponibles en version *.al2023, sans date de dépréciation planifiée à ce jour, mais AWS recommande explicitement de migrer les fonctions encore sur Amazon Linux 2 vers ces images AL2023 dès que possible.

RuntimeIdentifiantOSDépréciation
Node.js 24nodejs24.xAmazon Linux 202330 avril 2028
Java 25java25Amazon Linux 202330 juin 2029
Java 21java21Amazon Linux 202330 juin 2029
Java 17 (AL2023)java17.al2023Amazon Linux 2023Non planifiée
Python 3.11python3.11Amazon Linux 230 juin 2027

Si votre organisation gère à la fois des clusters Kubernetes et des fonctions Lambda, un même calendrier de revue trimestrielle des versions de runtime, côté nœuds comme côté serverless, évite que l’un des deux périmètres ne prenne du retard pendant que l’autre concentre toute l’attention.

La logique de fond reste la même des deux côtés de l’infrastructure. Un runtime, qu’il s’agisse de containerd sur un nœud Kubernetes ou d’un environnement d’exécution Lambda, est une surface d’attaque à part entière, distincte du code applicatif qu’il héberge. Les équipes qui traitent les mises à jour de runtime comme un chantier de sécurité récurrent, avec un propriétaire clair et un calendrier fixe, ferment ce type de faille bien plus vite que celles qui attendent une alerte CVE pour agir dans l’urgence.

Foire aux questions

Faut-il mettre à jour containerd immédiatement ou attendre Kubernetes 1.37 ?

Ne mélangez pas les deux campagnes. Les correctifs containerd (1.7.33, 2.0.10, 2.1.9, 2.2.5, 2.3.2 selon votre branche) sont déjà disponibles et indépendants de la sortie de Kubernetes 1.37. Patchez containerd dès maintenant, la mise à jour de la version majeure de Kubernetes peut suivre son propre calendrier de test.

Mon cluster GKE ou AKS est-il automatiquement corrigé ?

Pas nécessairement, et pas immédiatement. Les fournisseurs managés poussent des images de nœud corrigées selon leur propre calendrier, qui peut prendre plusieurs semaines après la publication des CVE. Vérifiez les notes de version de votre offre managée avant de supposer que le correctif est déjà en place, puis déclenchez un rolling replace des nœuds si nécessaire.

Ces failles concernent-elles aussi Docker Desktop ou Docker Engine ?

Docker Engine embarque containerd comme runtime sous-jacent, donc oui, si votre version de Docker inclut une des branches vulnérables. Vérifiez la version de containerd embarquée avec docker info | grep -i containerd et appliquez la même logique de mise à jour que pour un nœud Kubernetes.

Le feature gate ContainerCheckpoint est-il activé par défaut ?

Il est au stade Beta depuis Kubernetes 1.30, ce qui ne garantit pas qu’il soit actif par défaut sur toutes les distributions. Vérifiez la configuration réelle de votre kubelet plutôt que de vous fier au statut officiel du feature gate, certaines distributions managées activent les fonctionnalités Beta plus tôt que le calendrier upstream.

Combien de temps prend le durcissement complet d’un cluster de taille moyenne ?

Comptez environ 30 minutes pour un premier nœud testé de bout en bout, puis un rythme de rolling update qui dépend surtout de votre capacité à drainer les nœuds sans impact utilisateur. Sur un cluster de 20 à 30 nœuds avec des PodDisruptionBudgets bien configurés, une campagne complète tient généralement en une seule fenêtre de maintenance de quelques heures.

Faut-il désactiver complètement le checkpoint/restore si on ne l’utilise pas ?

C’est recommandé. Une fonctionnalité Beta non utilisée qui reste activée n’apporte aucun bénéfice et élargit inutilement la surface d’attaque. Désactivez le feature gate ContainerCheckpoint au niveau du kubelet si aucune équipe ne s’appuie dessus pour du debug ou de la migration à chaud.

Ce guide s’applique-t-il aux clusters on-premise sous k3s ou RKE2 ?

Oui dans les grandes lignes, puisque k3s et RKE2 embarquent également containerd comme runtime par défaut. Vérifiez la version embarquée via k3s --version ou rke2 --version, puis suivez le calendrier de release de votre distribution pour obtenir le correctif, plutôt que de patcher le binaire containerd isolément.

Que faire si je ne peux pas mettre à jour containerd immédiatement ?

Si une contrainte de compatibilité applicative retarde la mise à jour, appliquez d’abord les mitigations qui ne dépendent pas du patch : RBAC restreint sur la création de pods, Pod Security Admission en restricted, désactivation du feature gate ContainerCheckpoint si inutilisé, et imagePullPolicy: Always sur les nœuds partagés. Ces mesures réduisent nettement la probabilité d’exploitation en attendant la fenêtre de maintenance qui permettra le patch complet, mais elles ne remplacent pas la mise à jour de containerd, elles ne font que gagner du temps.

Articles similaires