Files
ROMFASTSQL/proxmox/lxc102-docker/README.md
Claude Agent a6b26ba23d docs(lxc102): OOM cronic pe 4GB -> 12GB + refresh tabel resurse cluster
Alerta "OOM x2 on pvemini" (09:36) arata procese mici ucise (dbus-daemon,
oom_score_adj:200), dar mesajul kernel dadea containerul real:
oom_memcg=/lxc/102. OOM local containerului, nu presiune de host - pvemini
avea 24Gi disponibili si zram functional.

Baseline masurat cu ZERO sandbox-uri active: ~1.9GB (sbx 863M + claude 317M +
VS Code Remote 450M + docker/tailscale/portainer 205M). Un sandbox real mai
adauga ~1.9GB (containerd-shim) -> plafonul de 4GB era depasit sistematic.
Contoare cumulate: oom_kill 24, 9279 depasiri memory.high, memory.peak fix pe
limita, swap 510/512 epuizat.

Verificat explicit ca sbx NU are memory leak: RSS urca la ~863M la pornire si
se plafoneaza (esantionat la 10s timp de un minut).

Fix: pct set 102 --memory 12288 --swap 4096 (live, fara restart).

Tabelul de resurse din cluster/README.md era vechi (102 aparea ca "coolify
stopped", lipseau 110 si 171, RAM gresit peste tot) - regenerat din pvesh.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 10:23:10 +00:00

204 lines
8.5 KiB
Markdown

# LXC 102 - Docker + Portainer + Docker Sandboxes (sbx)
**Director:** `proxmox/lxc102-docker/`
**VMID:** 102
**IP intern:** 10.0.20.113 | **Tailscale:** 100.73.147.55
**Host Proxmox:** pvemini (10.0.20.201)
**Rol:** Host Docker general + Portainer + rulare agenți AI (opencode, Claude Code) izolați în Docker Sandboxes
---
## Informații Container
| Parametru | Valoare |
|-----------|---------|
| VMID | 102 |
| Hostname | docker.romfast.ro |
| IP intern | 10.0.20.113 |
| Host Proxmox | pvemini |
| Storage | local-zfs (30GB) |
| RAM | 12GB (swap 4GB) — ridicat de la 4GB/512MB pe 2026-07-31, vezi „Memorie" |
| CPU | 4 cores |
| OS | Debian 13 (trixie) |
| Features | `nesting=1,fuse=1` |
| onboot | da |
| Creat cu | community-scripts ProxmoxVE — Docker LXC |
Containerul are bind-mount pentru `/dev/kvm` (`lxc.mount.entry: /dev/kvm dev/kvm none bind,optional,create=file`)
**obligatoriu** pentru microVM-ul folosit de sbx.
## Componente
| Componentă | Versiune | Note |
|------------|----------|------|
| Docker Engine | 29.6.x | dockerd de sistem (root) |
| Portainer CE | latest | container `portainer`, porturi 9000 / 9443 |
| Docker Sandboxes (`sbx`) | 0.37.1 | pachet `docker-sbx`, daemon per-user |
> Atenție: LXC **100** este un container separat, tot numit `portainer`. Portainer-ul activ folosit rulează în LXC 102.
**User de lucru pentru sbx:** `work` (uid 1000). Daemonul `sandboxd` pornește automat per-user la prima comandă `sbx`.
---
## Comenzi uzuale
```bash
# Acces
ssh root@10.0.20.201 "pct exec 102 -- bash"
# Docker
ssh root@10.0.20.201 "pct exec 102 -- docker ps"
# sbx (întotdeauna ca user work, NU ca root)
ssh root@10.0.20.201 "pct exec 102 -- su - work -c 'sbx ls'"
ssh root@10.0.20.201 "pct exec 102 -- su - work -c 'sbx diagnose'"
# Creare sandbox + atașare (interactiv, din shell-ul lui work)
sbx create opencode /cale/proiect
sbx run --name <sandbox>
sbx tui # dashboard interactiv
sbx rm -f <sandbox>
# Daemon
sbx daemon status
sbx daemon stop
```
**Log daemon (prima oprire când ceva nu merge):**
`/home/work/.local/state/sandboxes/sandboxes/sandboxd/daemon.log`
---
## Cum funcționează sbx (relevant pentru depanare)
`sbx` **nu** folosește dockerd-ul de sistem. Are propriul containerd embedded, per-user, care pornește
fiecare sandbox într-un **microVM** (runtime `nerdbox`, shim `/usr/libexec/containerd-shim-nerdbox-v1`,
VMM în `/usr/libexec/lib/libsailor.so`). De aici rezultă trei dependențe de mediu care nu sunt evidente:
1. acces read/write la `/dev/kvm` pentru userul care rulează sbx;
2. `mkfs.ext4` (din `/usr/sbin`) în PATH — snapshotter-ul erofs formatează layer-ul rw;
3. un build al pachetului compatibil cu glibc-ul din container.
Erorile din TUI sunt mereu generice (`500 Internal Server Error: failed to run sandbox container`).
**Cauza reală e doar în `daemon.log`.**
---
## Depanare: "failed to run sandbox container" (rezolvat 2026-07-30)
La primul sandbox opencode, TUI-ul returna:
```
Failed to create sandbox: create local sandbox: create sandbox via POST /sandbox:
request failed: 500 Internal Server Error: failed to run sandbox container
```
`sbx diagnose` trecea toate cele 9 verificări — nu ajută la acest tip de eroare. Din `daemon.log` au rezultat
trei probleme suprapuse, care se manifestau una după alta:
| # | Eroare în daemon.log | Cauză | Fix |
|---|----------------------|-------|-----|
| 1 | `creating ephemeral volume for "/var/lib/docker": unknown volume driver: block` | VMM nefuncțional (vezi #3); driver-ul `block` e oferit de runtime-ul microVM | rezolvat de #3 |
| 2 | `mkfs.ext4 failed: exec: "mkfs.ext4": executable file not found in $PATH` | Debian nu pune `/usr/sbin` în PATH pentru useri non-root | adăugat `/usr/sbin` în PATH-ul lui `work` |
| 3 | `failed to create shim task: ttrpc: closed` + `libsailor.so: version GLIBC_2.43 not found` | era instalat build-ul **Ubuntu 26.04 (resolute)** pe Debian 13 (glibc 2.41) | reinstalat build-ul **noble** (glibc 2.39) |
În plus, userul `work` **nu era în grupul `kvm`**, deci shim-ul microVM nu putea deschide `/dev/kvm`.
### Fix aplicat
```bash
# 1. build-ul corect: repo-ul Docker pentru Debian NU publică docker-sbx, doar cel de Ubuntu.
# Pe Debian 13 (glibc 2.41) se folosește build-ul noble (glibc 2.39), NU resolute (cere glibc 2.43).
curl -fsSLO https://download.docker.com/linux/ubuntu/dists/noble/pool/stable/amd64/docker-sbx_0.37.1-1~ubuntu.24.04~noble_amd64.deb
apt-get install -y --allow-downgrades ./docker-sbx_0.37.1-1~ubuntu.24.04~noble_amd64.deb
# 2. acces la KVM (necesită re-login pentru user work)
usermod -aG kvm work
# 3. mkfs.ext4 în PATH — adăugat în /home/work/.profile
PATH="/usr/local/sbin:/usr/sbin:/sbin:$PATH"
```
Verificare finală: `sbx create opencode .` → sandbox `running`, iar în interior `docker version` returnează
29.6.1 (deci merge și varianta docker-in-docker a template-ului).
### De reținut pentru viitor
- **Pachetul nu se actualizează cu `apt upgrade`** — nu provine dintr-un repo configurat. La update, descarcă
manual varianta `~noble`. Dacă iei din greșeală `~resolute`, sandbox-urile se rup din nou identic.
- Dacă apare orice eroare 500 la creare: citește `daemon.log`, nu `sbx diagnose`.
- Verificări rapide de mediu:
```bash
su - work -c 'test -w /dev/kvm && echo KVM_OK; command -v mkfs.ext4; ldd /usr/libexec/lib/libsailor.so | grep "not found"'
```
Toate trei trebuie să fie OK / fără output la ultima.
- Există și un daemon `sbx` vechi rulând ca **root** (rămas de la instalarea inițială, binar șters, ~590MB RSS).
Poate fi oprit cu `sbx daemon stop` ca root. Recomandat: sbx se folosește **doar** din userul `work`.
- Sandbox-urile pot ieși în rețea doar prin proxy-ul sbx, către host-uri permise de politică (`sbx policy`).
---
## Memorie — OOM cronic pe 4GB (rezolvat 2026-07-31)
Alertă pe email „OOM x2 on pvemini", cu procese mici ucise (`dbus-daemon`,
`oom_score_adj:200`) — derutant, pentru că victimele nu sunt vinovatul. Mesajul kernel dă
containerul real: `oom_memcg=/lxc/102`. **OOM local containerului**, NU presiune de host —
pvemini avea 24 Gi disponibili și zram funcțional.
### Bugetul real (măsurat, cu ZERO sandbox-uri active)
| Proces | RSS |
|--------|-----|
| `sbx daemon start` | ~863 MB |
| `claude` | ~317 MB |
| VS Code Remote-SSH (5 forks) | ~450 MB |
| tailscaled + dockerd + containerd + portainer | ~205 MB |
| **Baseline** | **~1.9 GB** |
Cu limita veche de 4096 MB, pornirea unui sandbox real (`containerd-shim` observat la
**1.9 GB**) ducea totalul la ~3.8 GB → plafon atins → cascadă de OOM-kill. Contoare cumulate
la momentul incidentului: `oom_kill 24`, `max 9279` depășiri de `memory.high`,
`memory.peak` fix pe limită. Swap-ul de 512 MB era epuizat complet (510/512).
> **`sbx daemon` NU are memory leak.** RSS-ul urcă la ~863 MB în timpul pornirii și apoi se
> plafonează (verificat prin eșantionare la 10s timp de un minut). O citire de ~335 MB
> înseamnă doar că l-ai prins în mijlocul startup-ului, tipic după un kill.
### Fix aplicat
```bash
ssh root@10.0.20.201 "pct set 102 --memory 12288 --swap 4096" # live, fără restart
```
Limita cgroup **nu rezervă** memorie — containerul consumă doar cât folosește. Verificare:
```bash
pct exec 102 -- free -h # 12Gi total
cat /sys/fs/cgroup/lxc/102/memory.events # oom_kill nu mai crește
```
Contoarele din `memory.events` sunt cumulate de la pornirea containerului, deci valorile
vechi rămân afișate — ce contează e că nu mai cresc.
### De reținut
- LXC 102 **nu e „doar Docker"**: rulează sbx (sandbox-uri agenți AI) + VS Code Remote +
Claude, toate sub userul `work`. Dimensionează-l ca mediu de dezvoltare, nu ca host Docker.
- La orice OOM pe pvemini, citește **`oom_memcg=`** din mesajul kernel înainte de orice
altceva — host-ul are marjă, deci aproape sigur e un cgroup de container.
- Caz înrudit în aceeași zi, cu alt mecanism (swap fictiv fără backing pe host):
`../cluster/incidents/2026-07-31-lxc110-dns-tailscale-oom.md`
---
## Fișiere și căi importante
| Cale | Conținut |
|------|----------|
| `/home/work/.local/state/sandboxes/sandboxes/sandboxd/daemon.log` | log daemon sbx (sursa de adevăr la erori) |
| `/home/work/.local/state/sandboxes/sandboxes/sandboxd/sandboxd.sock` | socket daemon |
| `/usr/libexec/containerd-shim-nerdbox-v1` | shim microVM |
| `/usr/libexec/lib/libsailor.so` | bibliotecă VMM (sensibilă la versiunea de glibc) |
| `/home/work/.profile` | conține fix-ul de PATH pentru `mkfs.ext4` |