Skip to content

Mise à jour des workers : qui patche quoi, et comment on l'apprend

Ce document répond à une question simple et mal posée en général : qui met à jour les nœuds d'un cluster EKS, et comment sait-on qu'une mise à jour existe ?

Il traite le cycle de vie des workers (les nœuds qui exécutent les pods). La montée de version du plan de contrôle est un autre sujet, traité dans Version du cluster.


Le point de départ

AWS publie une AMI corrigée. Personne ne l'installe à votre place.

Une AMI (Amazon Machine Image) est l'image disque à partir de laquelle une machine démarre. L'AMI EKS optimisée contient le noyau Linux, containerd et le kubelet — l'agent Kubernetes qui tourne sur chaque nœud.

AWS en publie une nouvelle toutes les deux à quatre semaines, avec les correctifs de sécurité du noyau et des composants.

Un node group créé en janvier tourne encore sur l'AMI de janvier en décembre. Il n'y a ni dégradation, ni avertissement, ni erreur. Il accumule simplement des vulnérabilités connues, en silence.


Trois couches, trois responsables, trois rythmes

La confusion vient de là : « EKS est managé » est vrai pour une couche et faux pour les deux autres.

Couche Qui corrige Rythme Qui déclenche
Plan de contrôle (l'API Kubernetes) AWS continu, invisible AWS
AMI des workers (noyau, kubelet, containerd) AWS publie l'image 2 à 4 semaines vous
Addons (VPC CNI, CoreDNS, kube-proxy) AWS publie les versions variable vous

La deuxième ligne est celle qui est oubliée. AWS fait la moitié du travail : il produit l'image corrigée. L'autre moitié — remplacer les machines — reste au client, et rien ne la réclame.


Ce que ce dépôt épingle réellement

Mesuré le 2026-09-05 sur terraform/modules/eks/main.tf :

Attribut Valeur dans le code
release_version (la version d'AMI du node group) absent
ami_type absent
AMI dans le launch template absente

Rien n'est épinglé. Le code délègue le choix à AWS, qui prend la dernière AMI compatible avec la version du cluster, à chaque création de node group.

Ce n'est ni bien ni mal en soi. C'est une conséquence à comprendre, et elle change complètement selon la durée de vie du cluster.


Le cas d'un cluster permanent : ce qui se passe si on ne fait rien

L'AMI ne bouge pas

Un managed node group ne se met jamais à jour de lui-même. La version d'AMI est un attribut mémorisé du node group, et elle ne change qu'avec un appel explicite à UpdateNodegroupVersion.

Conséquence rassurante au passage : si le cluster monte en charge et ajoute des nœuds, les nouveaux naissent sur la même AMI que les anciens. Le parc reste homogène. Vieux, mais homogène — ce qui est préférable à une flotte mélangée où un bug n'apparaît que sur certaines machines.

Le retard finit par bloquer la montée de version

Kubernetes tolère un écart limité entre le kubelet des nœuds et l'API server du plan de contrôle : trois versions mineures depuis Kubernetes 1.28. Au-delà, la montée est refusée.

Des nœuds qu'on laisse dériver créent donc une dette qui se paie au pire moment : quand le cluster est déjà en fin de support et qu'il faut monter vite.

Le signal existe, mais il est passif

C'est la nuance qui compte. Il est faux de dire que « rien ne le signale ». Il est vrai que rien ne vient jusqu'à vous.

Signal Où il vit Pourquoi il est raté
Badge « Update available » console EKS il faut ouvrir la console
Champ health.issues aws eks describe-nodegroup il faut appeler la commande
AWS Health courriel concerne surtout la fin de support d'une version, pas chaque AMI

Un contrôle que personne ne va lire n'existe pas. C'est le même motif qu'un scan de conformité joué à la main : il ne prouve rien sur la durée.


Comment être prévenu, pour de bon

Quatre canaux, du plus passif au plus fiable.

flowchart TD
    A["AWS publie une nouvelle AMI EKS"] --> B["Topic SNS public<br/>amazon-eks-ami-updates"]
    A --> C["Paramètre SSM<br/>.../recommended/image_id"]
    D["Fin de support d'une version"] --> E["AWS Health<br/>AWS_EKS_PLANNED_LIFECYCLE_EVENT"]
    B --> F["Abonnement e-mail ou Lambda"]
    E --> G["Règle EventBridge → SNS → Slack"]
    C --> H["Job planifié :<br/>compare l'AMI en service<br/>à l'AMI recommandée"]
    F --> I["Notification<br/>(peut être ratée)"]
    G --> I
    H --> J["Écart mesuré<br/>(ne peut pas être raté)"]

1. Le topic SNS public des AMI EKS

AWS publie chaque nouvelle AMI sur un topic SNS (Simple Notification Service) ouvert à tous :

arn:aws:sns:us-east-1:187976770252:amazon-eks-ami-updates

On s'y abonne par courriel ou par Lambda. C'est le canal le plus direct.

2. AWS Health branché sur EventBridge

AWS Health émet un événement AWS_EKS_PLANNED_LIFECYCLE_EVENT à l'approche de la fin de support d'une version. C'est ce qui produit le courriel que les équipes reçoivent.

En production, on ne s'appuie pas sur un courriel lu par une personne. On pose une règle EventBridge (le bus d'événements d'AWS) sur la source aws.health, qui pousse vers SNS puis vers un canal d'équipe.

3. Le paramètre SSM : la comparaison plutôt que la notification

AWS publie l'AMI recommandée à un chemin déterministe dans SSM Parameter Store :

aws ssm get-parameter --name \
  /aws/service/eks/optimized-ami/1.35/amazon-linux-2023/x86_64/standard/recommended/image_id

C'est le canal le plus utile des quatre, parce qu'il ne notifie pas : il compare. Un job planifié lit l'AMI réellement en service (aws eks describe-nodegroup, champ releaseVersion), la confronte à la recommandée, et échoue si l'écart dépasse un seuil.

Une notification se rate. Un contrôle qui compare ne se rate pas.

4. describe-nodegroup, qui le dit déjà

EKS marque lui-même les node groups en retard. L'information est disponible sans rien installer, et elle est presque toujours ignorée faute d'être demandée.


Comment appliquer la mise à jour

Sur un managed node group, c'est un appel : UpdateNodegroupVersion. AWS procède par remplacement progressif — il isole un nœud (cordon), en évacue les pods (drain), le détruit, en crée un neuf sur la nouvelle AMI, puis recommence.

Deux prérequis, sans lesquels la production tombe

Des replicas supérieurs à 1 sur tout ce qui doit rester joignable. Un pod unique est indisponible pendant son déplacement, quel que soit le reste.

Un PodDisruptionBudget (PDB), l'objet Kubernetes qui déclare « ne descends jamais sous N pods disponibles ». Sans lui, le drain évacue tout d'un coup.

Le piège inverse, plus fréquent que le premier

Un PDB trop strict bloque le drain indéfiniment. Un minAvailable: 1 posé sur un Deployment à un seul réplica interdit à ce pod de partir : la mise à jour reste coincée des heures, sans message explicite.

Le PDB n'est pas une protection qu'on ajoute au maximum. C'est un contrat entre ce que l'application tolère et ce que la plateforme a le droit de faire.

Le rythme

update_config.max_unavailable contrôle combien de nœuds peuvent être remplacés en parallèle. Ce dépôt le fixe à 1 sur les deux node groups.


Les deux stratégies de fond

Épingler et bumper par merge request

On écrit release_version dans le code. Un outil de veille propose la nouvelle version, la mise à jour devient une revue de code, et le plan Terraform montre le remplacement à venir avant qu'il arrive.

Contrôle total et traçable. Demande une discipline : sans elle, la version épinglée devient une version oubliée, ce qui est pire que pas d'épinglage du tout.

Faire mourir les nœuds de vieillesse

Karpenter, l'autoscaler qui remplace les managed node groups, accepte un expireAfter : au bout de N jours, un nœud est vidé et remplacé, sur la dernière AMI disponible. Le patching devient continu et ne demande plus de décision.

C'est la tendance actuelle, et elle repose sur un principe simple : un nœud est immuable et jetable. On ne le patche pas, on le remplace.

EKS Auto Mode pousse la même logique plus loin, AWS gérant lui-même le renouvellement. Bottlerocket, un système minimal dédié aux conteneurs, réduit la surface à patcher et rend les mises à jour atomiques avec retour arrière.


Ce qu'on ne fait jamais

Pas de yum update sur un nœud. La correction disparaît au prochain remplacement, et entre-temps le parc n'est plus homogène. Cette dérive est plus coûteuse que le retard qu'elle prétend corriger.

Pas de SSH. Si un accès est réellement nécessaire, c'est SSM Session Manager : tracé dans CloudTrail, aucun port ouvert, aucune clé à gérer.

Dans ce dépôt, aucun des deux chemins n'est ouvert : il n'y a ni bloc remote_access ni key_name dans le launch template, et le rôle des nœuds ne porte pas AmazonSSMManagedInstanceCore. Les nœuds sont des boîtes noires, ce qui est le bon défaut.


Pourquoi rien de tout cela n'est en place ici

Ce cluster est détruit et recréé à chaque session de travail, pour ne pas être facturé la nuit. Chaque montage repart du code, et le code demande la dernière AMI.

Le renouvellement des workers est donc un effet de bord du teardown quotidien, pas un contrôle. Les nœuds sont toujours jeunes, et personne ne l'a décidé.

Il n'y a par conséquent aucune version worker à surveiller : rien n'est épinglé, donc il n'existe pas de valeur à comparer. Fabriquer ici un job de détection produirait un contrôle qui ne mesure rien.

Un contrôle sur les workers suppose un épinglage, et l'épinglage suppose un cluster permanent.

La limite, qu'il faut énoncer dans la même phrase

Cette situation ne démontre aucune maîtrise du patching. Elle démontre qu'une contrainte de coût a produit, par accident, le comportement qu'un outil comme Karpenter produit à dessein.

Le jour où ce cluster tournerait en continu, les cinq points ci-dessous deviendraient nécessaires, et rien dans le dépôt actuel ne les prépare :

  1. Épingler release_version sur les node groups.
  2. Comparer l'AMI en service à l'AMI recommandée publiée dans SSM.
  3. S'abonner au topic SNS des AMI EKS.
  4. Brancher AWS Health sur EventBridge vers un canal d'équipe.
  5. Poser les PodDisruptionBudget avant la première mise à jour.

Ce qui est surveillé, en revanche, c'est la version du plan de contrôle : elle est épinglée dans une variable Terraform, donc lisible sans cluster. Le suivi automatique de cette variable est instruit dans l'issue #204.


Sources

  • terraform/modules/eks/main.tf — les deux node groups, leur update_config, le launch template et le rôle des nœuds
  • Version du cluster — la montée du plan de contrôle, les API dépréciées et le CNI comme facteur limitant
  • Issue #186 — montée depuis la 1.32, fin de support standard et surcoût
  • Issue #204 — détecter une version périmée dans le code, sans cluster
  • https://endoflife.date/api/amazon-eks.json — dates de fin de support par version