Le scheduler k8s croyait disposer des 4 cœurs / 7,6 Gi entiers de pi2, alors que Gitea et Postgres (docker compose nu, hors k3s, #54) en consomment une part invisible. --kubelet-arg="system-reserved=cpu=2,memory=2Gi" sur l'agent pi2 uniquement (via kubelet_reserved_args, per-host dans inventory/hosts.yml, injecté dans extra_agent_args). Réservation informative seulement — pas d'--enforce-node-allocatable — donc ça réduit l'Allocatable annoncé, pas de nouvelle éviction.
⚠️ Incident réel en le déployant — pi1 (control-plane) est exposé au même bug
--kubelet-arg="k=v" (guillemets littéraux autour de key=value) ressort en \= littéral dans l'ExecStart que k3s-install.sh régénère. Kubelet refuse alors de démarrer :
Error: failed to parse kubelet flag: unknown flag: --container-log-max-files\
→ boucle de redémarrage jusqu'à NotReady. C'était déjà vrai pour les deux args pré-existants (container-log-max-files, container-log-max-size), pas seulement le mien — latent depuis des mois parce que k3s-agent sur pi2 n'avait pas redémarré depuis avril (jamais régénéré par la version actuelle de k3s-install.sh). Mon changement a déclenché le premier restart réel et l'a fait sortir.
pi1 (control-plane) porte exactement le même texte dans extra_server_args, dormant pour la même raison (son k3s.service n'a pas non plus redémarré récemment — vérifié en direct, son unit file est encore dans un ancien format sain). Sans cette PR, le prochain restart de pi1 — reboot, ou un futur run de ce playbook — casserait l'API server en control-plane de la même façon.
Le format sans guillemets (--kubelet-arg=k=v) traverse la génération intact.
Déployé et vérifié en direct sur pi2
pi2 a été NotReady ~3 min pendant le diagnostic + la correction — aucun pod évincé (tous les RESTARTS/AGE inchangés après coup, sous le pod-eviction-timeout par défaut de 5 min).
Correction appliquée à chaud (édition directe de l'unit file + daemon-reload + restart) le temps de stabiliser, PUIS le fix source ici pour que ce soit reproductible et pour couvrir pi1.
journalctl confirme la ligne kubelet finale sans backslash : --system-reserved=cpu=2,memory=2Gi, service active (running) stable.
kubectl describe node pi2 : Allocatable descendu de 4 cœurs/8 Gi → 2 cœurs/5,6 Gi, exactement la réservation demandée.
Hors périmètre
Je n'ai pas touché pi1 en direct (aucun restart, aucun risque pris sur le control-plane) — cette PR corrige la source pour que le prochain run/reboot de pi1 ne retombe pas dans le panneau, mais son unit file actuel reste dans l'ancien format sain tant que personne ne relance system_k3s.yml dessus.
## Le levier scheduler-aware, suite à #54
Le scheduler k8s croyait disposer des 4 cœurs / 7,6 Gi entiers de pi2, alors que Gitea et Postgres (docker compose nu, hors k3s, #54) en consomment une part invisible. `--kubelet-arg="system-reserved=cpu=2,memory=2Gi"` sur l'agent pi2 uniquement (via `kubelet_reserved_args`, per-host dans `inventory/hosts.yml`, injecté dans `extra_agent_args`). Réservation **informative seulement** — pas d'`--enforce-node-allocatable` — donc ça réduit l'Allocatable annoncé, pas de nouvelle éviction.
## ⚠️ Incident réel en le déployant — pi1 (control-plane) est exposé au même bug
`--kubelet-arg="k=v"` (guillemets **littéraux** autour de `key=value`) ressort en `\=` littéral dans l'`ExecStart` que `k3s-install.sh` régénère. Kubelet refuse alors de démarrer :
```
Error: failed to parse kubelet flag: unknown flag: --container-log-max-files\
```
→ boucle de redémarrage jusqu'à `NotReady`. C'était déjà vrai pour les **deux args pré-existants** (`container-log-max-files`, `container-log-max-size`), pas seulement le mien — latent depuis des mois parce que `k3s-agent` sur pi2 n'avait pas redémarré depuis avril (jamais régénéré par la version actuelle de `k3s-install.sh`). Mon changement a déclenché le premier restart réel et l'a fait sortir.
**pi1 (control-plane) porte exactement le même texte dans `extra_server_args`, dormant pour la même raison** (son `k3s.service` n'a pas non plus redémarré récemment — vérifié en direct, son unit file est encore dans un ancien format sain). Sans cette PR, le prochain restart de pi1 — reboot, ou un futur run de ce playbook — casserait l'API server en control-plane de la même façon.
Le format sans guillemets (`--kubelet-arg=k=v`) traverse la génération intact.
## Déployé et vérifié en direct sur pi2
- pi2 a été `NotReady` ~3 min pendant le diagnostic + la correction — **aucun pod évincé** (tous les `RESTARTS`/`AGE` inchangés après coup, sous le `pod-eviction-timeout` par défaut de 5 min).
- Correction appliquée à chaud (édition directe de l'unit file + `daemon-reload` + `restart`) le temps de stabiliser, PUIS le fix source ici pour que ce soit reproductible et pour couvrir pi1.
- `journalctl` confirme la ligne kubelet finale sans backslash : `--system-reserved=cpu=2,memory=2Gi`, service `active (running)` stable.
- `kubectl describe node pi2` : Allocatable descendu de **4 cœurs/8 Gi → 2 cœurs/5,6 Gi**, exactement la réservation demandée.
## Hors périmètre
Je n'ai pas touché pi1 en direct (aucun restart, aucun risque pris sur le control-plane) — cette PR corrige la source pour que le prochain run/reboot de pi1 ne retombe pas dans le panneau, mais son unit file actuel reste dans l'ancien format sain tant que personne ne relance `system_k3s.yml` dessus.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Le scheduler k8s croyait disposer des 4 cœurs / 7,6 Gi entiers de pi2,
alors que Gitea et Postgres (docker compose nu, hors k3s, PR factory#54)
en consomment une part invisible. `--kubelet-arg="system-reserved=cpu=2,
memory=2Gi"` sur l'agent pi2 corrige ça — réservation informative, pas
d'--enforce-node-allocatable, donc pas de nouvelle éviction.
En le déployant : incident réel. `--kubelet-arg="k=v"` (guillemets
littéraux autour de key=value) ressort en `\=` littéral dans l'ExecStart
que k3s-install.sh régénère — kubelet refuse de démarrer ("unknown flag:
--container-log-max-files\"), boucle de redémarrage jusqu'à NotReady.
C'était déjà le cas pour les DEUX args pré-existants (container-log-max-
files, container-log-max-size), latent depuis des mois parce que
k3s-agent n'avait pas redémarré depuis avril — jamais régénéré par la
version actuelle du script. Mon changement a déclenché le premier
restart réel et l'a fait sortir.
pi2 a été NotReady ~3 min pendant le diagnostic puis la correction en
direct (aucun pod évincé, sous le pod-eviction-timeout par défaut de
5 min — vérifié). Les DEUX occurrences pré-existantes sont corrigées ici
aussi (extra_server_args ET extra_agent_args), pas seulement la mienne :
pi1 (le control-plane) porte le MÊME bug dans sa source, dormant parce
que son k3s.service n'a pas non plus redémarré récemment. Sans cette
PR, le prochain restart de pi1 (reboot, ou un futur run de ce playbook)
aurait cassé l'API server de la même façon.
Le format sans guillemets (`--kubelet-arg=k=v`) traverse la génération
intact — vérifié par la correction en direct sur pi2 (journal confirme
`--system-reserved=cpu=2,memory=2Gi` sans backslash, service stable,
Allocatable descendu de 4 cœurs/8Gi à 2 cœurs/5,6Gi).
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.
Le levier scheduler-aware, suite à #54
Le scheduler k8s croyait disposer des 4 cœurs / 7,6 Gi entiers de pi2, alors que Gitea et Postgres (docker compose nu, hors k3s, #54) en consomment une part invisible.
--kubelet-arg="system-reserved=cpu=2,memory=2Gi"sur l'agent pi2 uniquement (viakubelet_reserved_args, per-host dansinventory/hosts.yml, injecté dansextra_agent_args). Réservation informative seulement — pas d'--enforce-node-allocatable— donc ça réduit l'Allocatable annoncé, pas de nouvelle éviction.⚠️ Incident réel en le déployant — pi1 (control-plane) est exposé au même bug
--kubelet-arg="k=v"(guillemets littéraux autour dekey=value) ressort en\=littéral dans l'ExecStartquek3s-install.shrégénère. Kubelet refuse alors de démarrer :→ boucle de redémarrage jusqu'à
NotReady. C'était déjà vrai pour les deux args pré-existants (container-log-max-files,container-log-max-size), pas seulement le mien — latent depuis des mois parce quek3s-agentsur pi2 n'avait pas redémarré depuis avril (jamais régénéré par la version actuelle dek3s-install.sh). Mon changement a déclenché le premier restart réel et l'a fait sortir.pi1 (control-plane) porte exactement le même texte dans
extra_server_args, dormant pour la même raison (sonk3s.servicen'a pas non plus redémarré récemment — vérifié en direct, son unit file est encore dans un ancien format sain). Sans cette PR, le prochain restart de pi1 — reboot, ou un futur run de ce playbook — casserait l'API server en control-plane de la même façon.Le format sans guillemets (
--kubelet-arg=k=v) traverse la génération intact.Déployé et vérifié en direct sur pi2
NotReady~3 min pendant le diagnostic + la correction — aucun pod évincé (tous lesRESTARTS/AGEinchangés après coup, sous lepod-eviction-timeoutpar défaut de 5 min).daemon-reload+restart) le temps de stabiliser, PUIS le fix source ici pour que ce soit reproductible et pour couvrir pi1.journalctlconfirme la ligne kubelet finale sans backslash :--system-reserved=cpu=2,memory=2Gi, serviceactive (running)stable.kubectl describe node pi2: Allocatable descendu de 4 cœurs/8 Gi → 2 cœurs/5,6 Gi, exactement la réservation demandée.Hors périmètre
Je n'ai pas touché pi1 en direct (aucun restart, aucun risque pris sur le control-plane) — cette PR corrige la source pour que le prochain run/reboot de pi1 ne retombe pas dans le panneau, mais son unit file actuel reste dans l'ancien format sain tant que personne ne relance
system_k3s.ymldessus.🤖 Generated with Claude Code
Le scheduler k8s croyait disposer des 4 cœurs / 7,6 Gi entiers de pi2, alors que Gitea et Postgres (docker compose nu, hors k3s, PR factory#54) en consomment une part invisible. `--kubelet-arg="system-reserved=cpu=2, memory=2Gi"` sur l'agent pi2 corrige ça — réservation informative, pas d'--enforce-node-allocatable, donc pas de nouvelle éviction. En le déployant : incident réel. `--kubelet-arg="k=v"` (guillemets littéraux autour de key=value) ressort en `\=` littéral dans l'ExecStart que k3s-install.sh régénère — kubelet refuse de démarrer ("unknown flag: --container-log-max-files\"), boucle de redémarrage jusqu'à NotReady. C'était déjà le cas pour les DEUX args pré-existants (container-log-max- files, container-log-max-size), latent depuis des mois parce que k3s-agent n'avait pas redémarré depuis avril — jamais régénéré par la version actuelle du script. Mon changement a déclenché le premier restart réel et l'a fait sortir. pi2 a été NotReady ~3 min pendant le diagnostic puis la correction en direct (aucun pod évincé, sous le pod-eviction-timeout par défaut de 5 min — vérifié). Les DEUX occurrences pré-existantes sont corrigées ici aussi (extra_server_args ET extra_agent_args), pas seulement la mienne : pi1 (le control-plane) porte le MÊME bug dans sa source, dormant parce que son k3s.service n'a pas non plus redémarré récemment. Sans cette PR, le prochain restart de pi1 (reboot, ou un futur run de ce playbook) aurait cassé l'API server de la même façon. Le format sans guillemets (`--kubelet-arg=k=v`) traverse la génération intact — vérifié par la correction en direct sur pi2 (journal confirme `--system-reserved=cpu=2,memory=2Gi` sans backslash, service stable, Allocatable descendu de 4 cœurs/8Gi à 2 cœurs/5,6Gi).