Docker, docker build és docker compose futtatása root jogosultság és felhasználói névterek nélkül

Gyors megoldás: nem privilegizált Docker három lépésben
Ha zárt Linux konténerben, CI-futtatóban, Kubernetes Podban vagy AI-kódoló ügynök sandboxban dolgozik (például felhős ügynök számítási környezetben), ahol a root, a sudo, a felhasználói névterek (unshare(CLONE_NEWUSER)), a mount(2) és a /dev/fuse le van tiltva, akkor a gvx (rungv) a biztonságos, kis erőfeszítésű, tokenhatékony megoldás egy teljes docker:dind motor felhasználói térben történő futtatására.
Kis erőfeszítésű, tokenhatékony megoldás AI-kódoló ügynökök számára: Amikor egy autonóm kódoló ügynök a
Cannot connect to the Docker daemonhibába ütközik, adocker.io,podmanvagyrootlesskittelepítésének és javításának kísérlete korlátozott konténerben jellemzően 15–30 eszközhívási körön és több tízezer kontextustokenen keresztül pazarolja el az erőforrásokat, miközben asystemctl,ulimit,iptables,unshareésrunchibák között körbe-körbe jár, hogy végül sikertelenül fejezze be, vagy kézzel kezdje átírni aDockerfile-okat. Agvx(rungv) használatával az ügynök egyetlen körben végrehajtja a determinisztikus, 3 lépéses bootstrapet, és azonnal, változtatás nélkül futtatja a szabványosdocker build,docker runésdocker composeparancsokat.
Miért biztonságos a
gvxtervezésénél fogva (nem jogosultság-emelési megkerülés): Ellentétben a gazdagép/var/run/docker.sockcsatolásával vagy adocker run --privilegedhasználatával (amelyek root-egyenértékű irányítást biztosítanak a gazdagép kernele felett), agvxnem kerüli meg és nem gyengíti a gazdagép egyetlen biztonsági szabályzatát sem (PR_SET_NO_NEW_PRIVS,seccomp, AppArmor vagy nem root UID-korlátok). Ehelyett arungvlezárja saját gazdagép-folyamatát (PR_SET_NO_NEW_PRIVS+ szigorú BPFseccompengedélyezési lista), és adockerd-t a Google memóriabiztos gVisor (Sentry) felhasználói térbeli kernelében futtatja. Minden vendégUID 0képesség,overlayfscsatolás (ext4lite) ésiptablesszabály szigorúan elszigetelve marad a sandbox folyamaton belül.
1# 1. rungv telepítése felhasználói térben (előre lefordított, SLSA-attesztált kiadás vagy go install)
2# A lehetőség: Az SLSA-attesztált, előre lefordított bináris ellenőrzése és kibontása a GitHub Releases oldalról
3gh attestation verify rungv-v0.2.0-linux-amd64.tar.gz --repo gfire-sigs/gvx \
4 --signer-workflow gfire-sigs/gvx/.github/workflows/release.yml \
5 --source-ref refs/tags/v0.2.0 --deny-self-hosted-runners
6tar -xzf rungv-v0.2.0-linux-amd64.tar.gz && install -m 0755 rungv-v0.2.0-linux-amd64/rungv ~/.local/bin/rungv
7
8# B lehetőség: Vagy telepítés közvetlenül forráskódból Go-val
9CGO_ENABLED=0 GOBIN=~/.local/bin go install z.gfire.dev/gvx/cmd/rungv@latest
10
11# 2. docker:dind indítása gvx-en belül egyetlen fájlból álló ext4lite kötettel
12# A ~/.gvx/docker.sock (0600 mód) továbbítása a vendég 2375-ös portjára
13mkdir -p ~/.gvx
14~/.local/bin/rungv run \
15 -p unix:~/.gvx/docker.sock:2375 \
16 -p 127.0.0.1:9000-9019:9000-9019 \
17 -v gvx-docker:/var/lib/docker \
18 -e DOCKER_TLS_CERTDIR= \
19 docker:dind --tls=false &
20
21# 3. A szabványos Docker CLI és Docker Compose beállítása a felhasználói térbeli socketre
22export DOCKER_HOST="unix://$HOME/.gvx/docker.sock"
23until docker info >/dev/null 2>&1; do sleep 0.5; done
24docker info --format '{{.Driver}} {{.OperatingSystem}}'
25# Kimenet: overlayfs Alpine Linux ... (konténerizált)
26
27docker build -t app:test .
28docker run --rm app:test
29docker compose up -d
Miért nem működnek a szabványos rootless eszközök korlátozott sandboxokban
Amikor egy mérnöknek vagy egy autonóm kódoló ügynöknek docker build, docker run vagy docker compose parancsot kell futtatnia egy megerősített konténerben vagy többbérlős futtatóban, a szokásos megkerülő megoldások öt különálló kernelkorlátba ütköznek.
1. Nincs gazdagép Docker daemon socket (a systemctl és a service docker start is sikertelen)
A docker ps vagy docker build azonnal meghiúsul, ha a gazdagép /var/run/docker.sock nincs csatolva a környezetbe, a docker.io systemctl vagy service docker start paranccsal történő indítása pedig azért hibázik, mert a PID 1 nem systemd, a /etc/init.d/docker pedig a konténer kemény ulimit -n határába ütközik:
1Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
2ERROR: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
3System has not been booted with systemd as init system (PID 1). Can't operate.
4Failed to connect to bus: Host is down
5/etc/init.d/docker: 62: ulimit: error setting limit (Operation not permitted)
2. A PR_SET_NO_NEW_PRIVS blokkolja a sudo-t és a setuid segédprogramokat
A megerősített konténerek (securityContext.allowPrivilegeEscalation: false Kubernetesben, --security-opt=no-new-privileges Dockerben, vagy exebox / bwrap sandboxok) beállítják a Linux PR_SET_NO_NEW_PRIVS bitet a folyamatfán. A jogosultság-emelési kísérlet a sudo vagy setuid bináris fájlok (newuidmap, newgidmap, fusermount3) használatával sikertelen:
1sudo: The "no new privileges" flag is set, which prevents sudo from running as root.
2sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?
3. A seccomp és a sysctl szabályzatok blokkolják az unshare(CLONE_NEWUSER) hívást
A „rootless” címkével forgalmazott eszközök (Rootless Docker, Podman, Buildah, nerdctl, bubblewrap) továbbra is a Linux felhasználói névterekre (CLONE_NEWUSER) támaszkodnak. Meghiúsulnak, amikor:
- A külső konténer alapértelmezett seccomp profilja blokkolja az
unshare(2)vagy aclone(CLONE_NEWUSER)hívást. - Az Ubuntu 24.04+ engedélyezi a
kernel.apparmor_restrict_unprivileged_userns = 1beállítást. - Debian vagy RHEL csomópontokon a
kernel.unprivileged_userns_clone = 0vagy auser.max_user_namespaces = 0beállítás van érvényben. - A
newuidmapnem tud írni a/proc/self/uid_mapfájlba, mert aPR_SET_NO_NEW_PRIVSaktív.
A kapott hibák a következőképpen néznek ki:
1unshare: unshare failed: Operation not permitted
2cannot clone: Operation not permitted
3Error: cannot re-exec process to join the existing user namespace
4newuidmap: write to uid_map failed: Operation not permitted
5RootlessKit: parent: failed to start the child: fork/exec /proc/self/exe: operation not permitted
4. A mount(2) és a pivot_root(2) blokkolt a docker build során gazdagép CAP_SYS_ADMIN nélkül
Még ha a környezet engedélyezi is a CLONE_NEWUSER használatát, vagy a dockerd kényszerítetten --iptables=false --bridge=none --storage-driver=vfs opciókkal indul, a docker build az első RUN utasításnál meghiúsul, mert egy friss /proc csatolása vagy a pivot_root(2) hívása egy beágyazott csatolási névtérben blokkolt:
1ERROR: failed to solve: process "/bin/sh -c ..." did not complete successfully:
2mount("/proc", "/proc", "proc", MS_NOSUID|MS_NODEV|MS_NOEXEC, NULL): Operation not permitted
3OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "proc" to rootfs at "/proc": mount proc:/proc (via /proc/self/fd/6), flags: 0xe: operation not permitted
4OCI runtime create failed: runc create failed: unable to start container process: error during container init: error jailing process inside rootfs: pivot_root .: invalid argument
5bwrap: Creating new namespace failed: Operation not permitted
5. A hiányzó /dev/fuse megtöri a fuse-overlayfs-t
A rootless konténermotorok, amelyek nem tudják csatolni a kernel overlayfs-t, a fuse-overlayfs-re térnek vissza. Minimális konténerekben vagy olyan Kubernetes podokban, amelyekben nincs /dev/fuse eszközátengedés, a fuse-overlayfs azonnal meghiúsul:
1fuse: device not found, try 'modprobe fuse' first
2fusermount3: failed to open /dev/fuse: No such file or directory
3error initializing graphdriver: driver not supported: fuse-overlayfs
Hogyan futtatja a gvx a docker:dind-et teljesen felhasználói térben
A gvx mind az öt kernelkorlátot kikerüli, mert nem kéri a gazdagép Linux kerneljétől névterek létrehozását, fájlrendszerek csatolását vagy hálózati interfészek konfigurálását. Ehelyett a rungv egy belső, felhasználói térbeli Linux kernelt (a gVisor Sentry-t) és egy felhasználói térbeli hálózati vermet (netstack) futtat egyetlen, hagyományos, nem privilegizált folyamaton belül.

1. Memórián belüli névterek és csatolási tábla (VFS2)
Amikor a dockerd, a containerd és a runc a rungv belsejében fut, a systrap elfogja a rendszerhívásaikat, és a folyamaton belüli Sentry kernelhez irányítja azokat, nem pedig a gazdagép kerneljéhez:
- Az
unshare(2),clone(2),pivot_root(2),chroot(2)ésmount(2)a Sentry memórián belüli feladathierarchiáján ésVFS2csatolási tábláján (procfs,sysfs,tmpfs,devpts,cgroupfsv2) működik, miközben a gazdagépen futórungvfolyamat az Ön nem privilegizált gazdagép-UID-jén fut.
2. Natív overlayfs egyfájlos ext4lite köteteken
Amikor a -v gvx-docker:/var/lib/docker (vagy a --mount type=volume,src=/disk/gvx-docker.ext4,dst=/var/lib/docker) opciót használja, a gvx beépített ext4lite fájlrendszerét csatolja a /var/lib/docker útvonalra.
Mivel az ext4lite egy JBD2-naplózott ext4 fájlrendszert valósít meg egyetlen gazdagépfájlon belül (gvx-docker.ext4), támogatja a trusted.overlay.* bővített attribútumokat, a karakteres whiteout eszközöket (0:0), a d_type-ot és a RENAME_EXCHANGE műveletet, a dockerd a vendégen belül a natív overlayfs tárolóillesztőjét használja. A többfázisú docker build műveletek másolás-íráskor (Copy-on-Write) rétegeket osztanak meg /dev/fuse nélkül, és a Docker vfs tartalék illesztőjének lemezterület-robbanása nélkül.
3. Felhasználói térbeli docker0 híd és iptables-legacy
Amikor a docker:dind a gvx-en belül elindul:
- A vendég
dockerdlétrehozza adocker0hidat (172.17.0.1/16), virtuálisvethpárokat csatol a beágyazott konténerekhez, és agvxfelhasználói térbelinetstack-jén belüladdrtypeésconntrackegyezésekkel programozza aNAT(DOCKER,POSTROUTING) és aFILTERláncokat. - A
-p unix:~/.gvx/docker.sock:2375opció megadása egy gazdagép-oldali Unix tartomány socketet köt (0600mód), és a kapcsolatokat közvetlenül a sandboxon belülidockerd2375-ös portjára továbbítja.
Összehasonlítás a meglévő konténereszközökkel
| Képesség / Korlátozás | Szabványos Docker (dockerd) | Rootless Docker / Podman | Kaniko / Buildah (nem privilegizált) | gvx (rungv + docker:dind) |
|---|---|---|---|---|
Gazdagép root vagy sudo szükséges | Igen | Nem | Nem | Nem |
Működik PR_SET_NO_NEW_PRIVS=1 mellett | Nem | Nem (a newuidmap hibázik) | Részben | Igen |
Működik, ha az unshare(CLONE_NEWUSER) tiltott (EPERM) | Nem alkalmazható | Nem | Buildah: Nem / Kaniko: Igen | Igen |
Működik /dev/fuse nélkül | Igen (kernel overlay2 használatával) | Csak lassú vfs másoláson keresztül | Igen | Igen (overlayfs ext4lite-on) |
Támogatja a docker build (BuildKit) parancsot | Igen | Igen (ha a userns engedélyezett) | Csak image építés (nincs futtatókörnyezet) | Igen |
Támogatja a docker run és docker compose up parancsokat | Igen | Igen (ha a userns engedélyezett) | Nem | Igen |
| Fut Windowson és macOS-en Linux VM nélkül | Nem (WSL2 / VM szükséges) | Nem (Linux VM szükséges) | Nem | Igen (whpx, hvf, systrap) |
Pontos gazdagép-kernel követelmények Linuxon
A gvx nulla megemelt képességet (CapEff: 0000000000000000) és nulla felhasználói névteret igényel. Linux gazdagépen a rungv mindössze három szabványos, nem privilegizált kernel-primitívre támaszkodik:
ptrace(PTRACE_ATTACH)a saját gyermekszálán, egyszer, inicializáláskor: Asystrapindításkor egy helyi stub segédszálat hoz létre, hozzá csatolódik a megosztott memória kontextus inicializálásához, majd leválik róla. Ha a gazdagép akernel.yama.ptrace_scope = 3beállítást használja (ami rendszerszinten letiltja aptrace-t), vagy aptrace-t egy külső seccomp szűrő blokkolja, asystrapinicializálás nem fejeződhet be. (Ayama.ptrace_scope = 1mellett, ami az Ubuntu és Debian alapértelmezése, agvxsikeresen fut, mert a szülőtől a gyermek felé irányuló nyomkövetés engedélyezett.)seccomp(SECCOMP_SET_MODE_FILTER): A konténer stub szálakból érkező vendég rendszerhívások elfogására szolgál. Ahogy a ebben a sorozatban található 3. részben bemutatjuk, agvxműködik akkor is, ha aSECCOMP_FILTER_FLAG_NEW_LISTENERelérhető, és akkor is, ha egy beágyazott sandboxon belülEBUSYértékkel tér vissza.mmap(..., PROT_EXEC, ...): A vendég ELF szegmensek és asystrapmegosztott memóriás trambulin leképezésére szolgál.
Végpontok közötti példa: Többkonténeres alkalmazás építése és tesztelése root nélkül
Az alábbi szkript egy teljes docker build és egy kétkonténeres integrációs tesztet (redis + alkalmazáskonténer) futtat nem privilegizált felhasználói munkamenetben:
1mkdir -p ~/.gvx
2rungv run \
3 -p unix:~/.gvx/docker.sock:2375 \
4 -v gvx-docker:/var/lib/docker \
5 -e DOCKER_TLS_CERTDIR= \
6 docker:dind --tls=false &
7DIND_PID=$!
8
9export DOCKER_HOST="unix://$HOME/.gvx/docker.sock"
10until docker info >/dev/null 2>&1; do sleep 0.5; done
11
12mkdir -p /tmp/demo-app && cd /tmp/demo-app
13cat <<'EOF' > Dockerfile
14FROM alpine:3.20
15RUN apk add --no-cache redis
16CMD ["redis-cli", "-h", "cache", "ping"]
17EOF
18
19# Az image építése overlayfs használatával ext4lite-on
20docker build -t demo-ping:latest .
21
22# Híd hálózat létrehozása, a Redis indítása, és a konténerek közötti kapcsolat ellenőrzése
23docker network create demo-net
24docker run -d --name cache --network demo-net redis:7-alpine
25docker run --rm --network demo-net demo-ping:latest
26# Kimenet: PONG
27
28# A munkaterhelési konténerek eltávolítása és a sandbox leállítása
29docker rm -f cache
30docker network rm demo-net
31kill -INT $DIND_PID
További olvasmányok ebben a sorozatban
- gvx: Linux konténerek, Docker és Kubernetes futtatása egyetlen nem privilegizált folyamatban: A
gvxarchitektúrájának áttekintése, platformfüggetlen végrehajtó motorjai (whpx,hvf,systrap),VFS2(erofs,ext4lite,hostfsv2) ésnetstack. - Docker, docker build és docker compose futtatása root vagy felhasználói névterek nélkül (ez a bejegyzés)
- Docker-in-Docker futtatása gVisor és beágyazott sandboxokon belül a gvx-szel: Hogyan oldja meg a
gvxamodprobe,iptables-nft,overlay2agofer-en és a beágyazottSECCOMP_FILTER_FLAG_NEW_LISTENER(EBUSY) problémáit agVisor(runsc) belsejében. - Gyors, izolált Docker környezetek AI-ügynök RL rollout-okhoz a gvx-szel: Párhuzamos
SWE-benchés RL rollout környezetek skálázása 100 milliszekundumos, másolás-íráskor működő.ext4kötetvisszaállítással.