Un nuxt generate (CMS) lancé par le runner CI de pi1 a consommé 3,5 Go de RSS : RAM de pi1 épuisée (0 swap), load15 > 150, kernel en thrash sur la SD sans OOM-kill → traefik, svclb et l'apiserver k3s affamés → tout *.arcodange.lab injoignable, Gitea compris (pourtant parfaitement sain sur pi2). Les contrôleurs à leader-election ont crashé en cascade (step-issuer : 87 restarts cumulés, csi-attacher : 45…) — l'incident était chronique.
Changements
container.options: "--memory=3g --memory-swap=3g --cpus=2 --pids-limit=512" : plafonds durs cgroup sur chaque container de job (ils sont lancés via le socket Docker de l'hôte, c'est le seul garde-fou possible).
capacity: 2 → 1 : un seul job à la fois par runner ; deux builds lourds simultanés ne tiennent pas sur un Pi 8 Go qui porte aussi le control-plane.
Déjà appliqué en live
Playbook rejoué le 2026-07-24 sur pi1 et pi3 (ok=11 failed=0 ×2) : les deux runners sont ré-enregistrés (declare successfully), config vérifiée dans les containers (capacity: 1 + options présentes). Au passage, le runner de pi3 — qui était down — est remis en service.
Effet de bord assumé
Le build CMS qui demandait 3,5 Go échouera désormais en OOM du cgroup au lieu de coucher pi1 → à tuner côté cms (heap Node / concurrence de prerender / build hors lab).
## Incident 2026-07-23 (~22h58 → 00h00)
Un `nuxt generate` (CMS) lancé par le runner CI de pi1 a consommé 3,5 Go de RSS : RAM de pi1 épuisée (0 swap), load15 > 150, kernel en thrash sur la SD **sans OOM-kill** → traefik, svclb et l'apiserver k3s affamés → **tout `*.arcodange.lab` injoignable, Gitea compris** (pourtant parfaitement sain sur pi2). Les contrôleurs à leader-election ont crashé en cascade (step-issuer : 87 restarts cumulés, csi-attacher : 45…) — l'incident était chronique.
## Changements
- `container.options: "--memory=3g --memory-swap=3g --cpus=2 --pids-limit=512"` : plafonds durs cgroup sur chaque container de job (ils sont lancés via le socket Docker de l'hôte, c'est le seul garde-fou possible).
- `capacity: 2 → 1` : un seul job à la fois par runner ; deux builds lourds simultanés ne tiennent pas sur un Pi 8 Go qui porte aussi le control-plane.
## Déjà appliqué en live
Playbook rejoué le 2026-07-24 sur pi1 **et** pi3 (`ok=11 failed=0` ×2) : les deux runners sont ré-enregistrés (`declare successfully`), config vérifiée dans les containers (`capacity: 1` + options présentes). Au passage, **le runner de pi3 — qui était down — est remis en service**.
## Effet de bord assumé
Le build CMS qui demandait 3,5 Go échouera désormais en OOM du cgroup au lieu de coucher pi1 → à tuner côté `cms` (heap Node / concurrence de prerender / build hors lab).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Incident 2026-07-23: an uncapped nuxt generate (3.5G RSS) on pi1 starved the
k3s control-plane and traefik (load >150, no swap, no OOM-kill) — every
*.arcodange.lab endpoint went dark, Gitea included, while Gitea itself was
healthy on pi2. Job containers are spawned via the host docker socket, so
cgroup caps on the job container are the only guardrail.
Applied live on pi1+pi3 via 03_cicd.yml on 2026-07-24 (both runners
re-registered; pi3's runner was down and is back in service).
Co-Authored-By: Claude Fable 5 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Incident 2026-07-23 (~22h58 → 00h00)
Un
nuxt generate(CMS) lancé par le runner CI de pi1 a consommé 3,5 Go de RSS : RAM de pi1 épuisée (0 swap), load15 > 150, kernel en thrash sur la SD sans OOM-kill → traefik, svclb et l'apiserver k3s affamés → tout*.arcodange.labinjoignable, Gitea compris (pourtant parfaitement sain sur pi2). Les contrôleurs à leader-election ont crashé en cascade (step-issuer : 87 restarts cumulés, csi-attacher : 45…) — l'incident était chronique.Changements
container.options: "--memory=3g --memory-swap=3g --cpus=2 --pids-limit=512": plafonds durs cgroup sur chaque container de job (ils sont lancés via le socket Docker de l'hôte, c'est le seul garde-fou possible).capacity: 2 → 1: un seul job à la fois par runner ; deux builds lourds simultanés ne tiennent pas sur un Pi 8 Go qui porte aussi le control-plane.Déjà appliqué en live
Playbook rejoué le 2026-07-24 sur pi1 et pi3 (
ok=11 failed=0×2) : les deux runners sont ré-enregistrés (declare successfully), config vérifiée dans les containers (capacity: 1+ options présentes). Au passage, le runner de pi3 — qui était down — est remis en service.Effet de bord assumé
Le build CMS qui demandait 3,5 Go échouera désormais en OOM du cgroup au lieu de coucher pi1 → à tuner côté
cms(heap Node / concurrence de prerender / build hors lab).🤖 Generated with Claude Code