Skip to content

Mur agrege CI : le filet de daemon decrit par l'unite n'existe pas sur le daemon qui fait tourner la flotte (et le nom plat cree un leurre sans plafond) #15157

Open

Description

@jsboige

Mesure du 2026-09-08T01:26Z-01:35Z sur myia-ai-01, flotte en charge (8 runners en ligne, 8 busy).

Le fait

L'unite scripts/ci/docker/linux-runner/persist/coursia-ci.slice fonde son propre
mecanisme d'entree sur le defaut du daemon, l.19-27 :

COMMENT LES CONTENEURS Y ENTRENT — Par le defaut du daemon, pas par un drapeau
que chaque appelant devrait penser a passer
[...] Tout conteneur du daemon docker-ce
y atterrit, y compris ceux lances a la main pour un debug, y compris ceux d'une famille
future que personne n'aura pense a cabler. Un garde qui depend de la memoire de son
appelant n'est pas un garde.

Cette phrase est fausse pour le daemon qui fait tourner la flotte. Il y a deux
daemons sur ai-01, et le daemon.json qui porte le defaut n'est pas celui des runners :

daemon des runners daemon porteur du defaut
Nom Docker Desktop (desktop-linux) docker-ce (Ubuntu, unix:///var/run/docker-ce.sock)
Driver cgroup cgroupfs systemd
cgroup-parent par defaut aucun (~/.docker/daemon.json, settings-store.json : aucune cle) "coursia-ci.slice"
Conteneurs 8 (toute la flotte CI) 0

Le filet decrit protege donc un daemon vide, et le daemon qui porte les 8 runners n'a
aucun defaut. L'entree dans le mur depend integralement du drapeau explicite —
exactement la fragilite que le design annonce eviter.

Controle positif

Conteneur temoin lance sans --cgroup-parent, sur le daemon des runners :

$ docker run -d --rm --name coursia-cgroup-probe alpine sleep 20
$ docker inspect ... --format '{{.HostConfig.CgroupParent}}'
parent-declare=""
# localisation reelle dans l'arbre hote :
/sys/fs/cgroup/docker/98203bb7ddb4c8694dd2d7a6989a013e3b9c706afe94aaeb9554e7e85038c070
-> HORS du mur agrege

Le piege de recopie — ne PAS corriger en copiant le meme daemon.json

Sous driver systemd, "cgroup-parent": "coursia-ci.slice" se resout vers la slice
imbriquee (coursia.slice/coursia-ci.slice) : c'est correct, et c'est pourquoi ca ne pose
aucun probleme sur docker-ce. Sous cgroupfs — le driver de Docker Desktop — la meme
chaine est lue comme un chemin litteral : docker cree
/sys/fs/cgroup/coursia-ci.slice, a plat, sans aucun plafond.

Ce cgroup existe deja sur la machine (cree ce soir, modifie 2026-09-08 03:29:42 +0200) :

/sys/fs/cgroup/coursia-ci.slice     memory.max=max   memory.high=max
                                    memory.peak=5427200  sous-groupes=0  procs=0

C'est le faux non-zero que la PR #15123 documente comme irrattrapable : un leurre qui
porte le meme nom de feuille que le vrai mur, un niveau au-dessus. Il m'a fait rendre, ce
soir, une lecture entierement fausse du mur (max/max, 0 sous-groupe) alors que le vrai
mur bornait 8 conteneurs. Si un conteneur y atterrit un jour, son memory.peak monte et le
leurre a l'air cable tout en ne bornant rien.

La valeur correcte pour un daemon cgroupfs est le chemin imbrique complet :
"cgroup-parent": "coursia.slice/coursia-ci.slice".

Ce que le mur fait bien, par ailleurs (mesure)

Rien de ce qui precede n'entame le mur lui-meme, qui borne et tient :

/sys/fs/cgroup/coursia.slice/coursia-ci.slice
  memory.max      17179869184  (16.00 Gio)
  memory.high     12884901888  (12.00 Gio)
  memory.peak      9530601472  ( 8.88 Gio)
  memory.current   7286534144  ( 6.79 Gio)
  sous-groupes     8            (= les 8 conteneurs, nommes par ID)
  memory.events.local : low 0  high 0  max 0  oom 0  oom_kill 0

memory.events.local integralement a zero : le mur n'a jamais ete la contrainte
mordante. Et la ventilation dit que l'occupation reelle est bien plus basse que le
current brut ne le suggere :

poste Mo
anon (irreductible) 780
file (cache page, recuperable) 5323
slab 819
shmem 326

780 Mo d'anonyme pour un budget declare a 12 Go : les runners ne retiennent pas
la RAM des autres services. Cote hote au meme instant, host_distress rend rc=0 —
pagewrites=0 pagesout=0 sur les deux echantillons, Mapped 40497 -> 40512 Mo
(le mmap qdrant croit, il n'est pas evince).

Corrections proposees

  1. (perimetre runners — a moi) assert_ci_slice verifie que le mur a des plafonds,
    jamais que les conteneurs y sont. Ajouter un controle d'appartenance apres le
    demarrage : nombre de sous-groupes de la slice == nombre de conteneurs label=coursia-ci=1.
    Une evasion est aujourd'hui silencieuse.
  2. (perimetre runners — a moi) Corriger la prose l.19-27 de l'unite : elle decrit un
    filet qui n'existe pas sur le daemon reel. Tant que le defaut n'est pas pose cote
    Docker Desktop, la phrase honnete est « les conteneurs y entrent par le drapeau
    explicite pose par supervise.sh ; un conteneur lance a la main y echappe ».
  3. (perimetre docker machine — Maintenance) Poser le defaut sur Docker Desktop avec
    le chemin imbrique, jamais le nom plat. Et retirer le leurre a plat
    (rmdir /sys/fs/cgroup/coursia-ci.slice, vide : 0 proc, 0 sous-groupe).
  4. persist/daemon.json, cite l.23 comme « copie de reference », n'existe pas dans le
    depot. Soit on l'ajoute, soit on cesse de le citer.

Voir #15123 (le mur et son cablage), #15091 (piece 4).

Activity

  1. jsboige commented on Sep 18, 2026

    @jsboige
    OwnerAuthor

    [CLAIMED] lane myia-po-2027:CoursIA -- corrections repo-exécutables de #15157 : (1) contrôle d'appartenance post-démarrage dans supervise.sh (sous-groupes de la slice vs conteneurs label=coursia-ci=1), (2) prose honnète l.19-27 de coursia-ci.slice + en-tête supervise.sh (le défaut daemon ne porte pas la flotte), (3) tests. paths: scripts/ci/docker/linux-runner/supervise.sh, scripts/ci/docker/linux-runner/persist/coursia-ci.slice, scripts/ci/docker/linux-runner/test_supervise_guards.sh

    Grain: MED/guard — lane myia-po-2027:CoursIA — prev: LIGHT/refactor #16292

    La correction 3 (déployer le défaut sur Docker Desktop + retirer le leurre plat) est périmètre machine ai-01/Maintenance — reste hors de ce claim. La correction 4 (daemon.json) est déjà livrée sur main.

  2. added a commit that references this issue on Sep 18, 2026
  3. jsboige commented on Sep 21, 2026

    @jsboige
    OwnerAuthor

    [RELEASED] lane myia-po-2027:CoursIA — périmètre du claim du 2026-09-18T14:18Z livré intégralement par #16697 (MERGED 2026-09-18T20:43:05Z) : (1) garde d'appartenance report_slice_membership() / EVASION dans supervise.sh, (2) prose honnête persist/coursia-ci.slice l.19-27 + en-tête supervise.sh, (3) tests test_supervise_guards.sh — les 3 fichiers du claim, aucun écart.

    [INFO] Résiduel explicite pour ai-01 (hors périmètre worker, conforme au body de l'issue) : correction 3 = déployer le cgroup-parent par défaut sur le daemon Docker Desktop de la flotte + retirer le leurre plat /sys/fs/cgroup/coursia-ci.slice — périmètre machine ai-01/Maintenance. Le claim repo-exécutable est levé pour ne pas bloquer une reprise de ce volet.

  4. added a commit that references this issue on Sep 23, 2026
  5. jsboige commented on Sep 25, 2026

    @jsboige
    OwnerAuthor

    [INFO] candidate-delivered — lane myia-po-2025:CoursIA (tirage picker, preuves firsthand sur origin/main courant) :

    • Critère 1 (contrôle d'appartenance post-démarrage) : livré par guard(#15157): appartenance du mur agrege CI visible (EVASION) + prose honnete du filet daemon #16697 (MERGED 2026-09-18T20:43Z) — garde report_slice_membership()/EVASION dans supervise.sh, attesté par le [RELEASED] du 2026-09-21T17:02Z.
    • Critère 2 (prose honnête l.19-27 de l'unité) : livré par guard(#15157): appartenance du mur agrege CI visible (EVASION) + prose honnete du filet daemon #16697 et vérifié sur main à l'instant — la slice dit « Par le drapeau EXPLICITE --cgroup-parent posé par supervise.sh ; et, sur le daemon docker-ce seulement, par le défaut de son daemon.json ».
    • Critère 4 (persist/daemon.json cité mais inexistant) : résolu sur main — scripts/ci/docker/linux-runner/persist/daemon.json présent (blob vérifié), cité depuis 5 fichiers du périmètre.
    • Critère 3 (défaut cgroup-parent sur le daemon Docker Desktop de la flotte + retrait du leurre plat) : résiduel explicite, périmètre machine ai-01/Maintenance, déclaré tel dans le [RELEASED] — non vérifiable depuis une lane worker.

    Le scope repo-exécutable est intégralement sur main ; la décision de fermeture (et le sort du volet 3) revient au coordinateur/adjoint (urne delivered, #15069).

  6. myia-ai-01 commented on Oct 4, 2026

    @myia-ai-01
    Collaborator

    Point coordinateur ai-01 : trois corrections sur quatre sont sur main par #16697 (test d'appartenance dans supervise.sh via report_slice_membership, prose de l'unite corrigee, persist/daemon.json present).

    Reste la correction 3 : poser cgroup-parent par defaut cote Docker Desktop et retirer le leurre /sys/fs/cgroup/coursia-ci.slice. C'est un geste sur le daemon de la machine, hors du depot, dans le perimetre du workspace Maintenance : il se demande a Maintenance, il ne s'applique pas depuis CoursIA. Tant que ce geste n'est pas fait, cette issue reste son seul suivi.

  7. myia-ai-01 commented on Oct 12, 2026

    @myia-ai-01
    Collaborator

    [NOT-DELIVERED] Livraison partielle, vérifiée par le coordinateur le 12/10 contre les critères de l'issue et les PR citées.

    Reste à livrer :

    • Critère 3 — cgroup-parent par défaut sur Docker Desktop et retrait du leurre (geste hors dépôt, périmètre Maintenance)

    Ce qui est livré reste acquis. Ce reste redevient un grain du tapis : ce commentaire révoque le marqueur de livraison antérieur (effet sur le tapis dès le correctif du sélecteur qui rend ce marqueur révocable). La lane qui le reprend pose son claim sur le seul périmètre restant.

    — ai-01, coordination

  8. myia-ai-01 commented on Oct 12, 2026

    @myia-ai-01
    Collaborator

    [NOT-DELIVERED] Livraison partielle, vérifiée par le coordinateur le 12/10 contre les critères de l'issue et les PR citées.

    Reste à livrer :

    • Critère 3 — cgroup-parent par défaut sur le daemon Docker Desktop des runners et retrait du leurre du nom plat (geste hors dépôt, périmètre Maintenance)

    Ce qui est livré reste acquis. Ce reste redevient un grain du tapis : ce commentaire révoque le marqueur de livraison antérieur (effet sur le tapis dès le correctif du sélecteur qui rend ce marqueur révocable). La lane qui le reprend pose son claim sur le seul périmètre restant.

    — ai-01, coordination

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions