fix(cicd): cap act_runner jobs (3g/2cpu) and capacity 2→1 — a build can no longer take down pi1 #39

Merged
arcodange merged 1 commits from arcodange/runner-limits into main 2026-07-24 09:51:10 +02:00
Owner

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

## 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)
arcodange added 1 commit 2026-07-24 00:14:07 +02:00
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]>
arcodange merged commit 0612da184c into main 2026-07-24 09:51:10 +02:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: arcodange-org/factory#39