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

Gyors megoldás: biztonságos, jogosultság nélküli Docker három lépésben
Ha egy korlátozott Linux-konténerben, CI-futtatóban, Kubernetes Podban vagy AI-ügynök homokozóban dolgozik, 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, mélyvédelmi megoldás egy teljes docker:dind motor felhasználói térben történő futtatásához.
Miért biztonságos a
gvxa tervezésénél fogva (nem jogosultság-emelési megkerülés): Ellentétben a host/var/run/docker.sockcsatlakoztatásával vagy adocker run --privilegedhasználatával (amelyek root-egyenértékű irányítást biztosítanak a host kernel felett), agvxnem kerüli meg és nem gyengíti egyik host biztonsági szabályzatot sem (PR_SET_NO_NEW_PRIVS,seccomp, AppArmor vagy a nem-root UID korlátozások). Ehelyett arungvlezárja a saját host folyamatát (PR_SET_NO_NEW_PRIVS+ szigorú BPFseccompengedélyezőlista), és adockerdfolyamatot a Google memóriabiztos gVisor (Sentry) felhasználói térbeli kernelében futtatja. A vendégUID 0képességei, azoverlayfscsatlakoztatások (ext4lite) és aziptablesszabályok szigorúan a homokozó folyamaton belül maradnak elszigetelve.
1# 1. Az rungv telepítése felhasználói térbe (SLSA-tanúsított előre fordított kiadás vagy go install)
2# A lehetőség: A SLSA-tanúsított, előre fordított bináris ellenőrzése és kicsomagolá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 közvetlen telepítés forráskódból Go-val
9CGO_ENABLED=0 GOBIN=~/.local/bin go install z.gfire.dev/gvx/cmd/rungv@latest
10
11# 2. A docker:dind indítása a gvx-en belül egyfájlos ext4lite kötettel
12# Továbbítja a ~/.gvx/docker.sock fájlt (0600 mód) 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 szokásos Docker CLI és Docker Compose irányí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 ... (containerized)
26
27docker build -t app:test .
28docker run --rm app:test
29docker compose up -d
Miért nem működnek a szokásos rootless eszközök korlátozott homokozókban
Amikor egy mérnöknek vagy egy autonóm kódoló ügynöknek egy megerősített konténerben vagy többbérlős futtatóban kell docker build, docker run vagy docker compose parancsot futtatnia, a szokásos megkerülő megoldások öt különálló kernel-akadálynál meghiúsulnak.
1. Nincs host Docker démon socket
A docker ps vagy a docker build azonnal meghiúsul, ha a host /var/run/docker.sock nincs csatlakoztatva a környezetbe:
1Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
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 homokozók) beállítják a Linux PR_SET_NO_NEW_PRIVS bitet a folyamatfán. A jogosultság-emelés sudo vagy setuid bináris fájlokon keresztül (newuidmap, newgidmap, fusermount3) meghiúsul:
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” 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+ verzión engedélyezve van a
kernel.apparmor_restrict_unprivileged_userns = 1beállítás. - A Debian vagy RHEL csomópontokon a
kernel.unprivileged_userns_clone = 0vagy auser.max_user_namespaces = 0van beállítva. - A
newuidmapnem tud írni a/proc/self/uid_mapfájlba, mert aPR_SET_NO_NEW_PRIVSaktív.
A kapott hibaüzenetek így 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) tiltott host CAP_SYS_ADMIN nélkül
Még ha a környezet engedélyezi is a CLONE_NEWUSER használatát, egy új /proc csatlakoztatása egy beágyazott csatlakoztatási névtérben meghiúsul, ha a külső konténer maszkolta a /proc alrendszereket (/proc/acpi, /proc/kcore, /proc/keys), vagy a seccomp eldobta a mount(2) hívást:
1mount("/proc", "/proc", "proc", MS_NOSUID|MS_NODEV|MS_NOEXEC, NULL): Operation not permitted
2OCI 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
3bwrap: Creating new namespace failed: Operation not permitted
5. A hiányzó /dev/fuse megtöri a fuse-overlayfs működését
A rootless konténermotorok, amelyek nem tudnak kernel overlayfs fájlrendszert csatlakoztatni, a fuse-overlayfs megoldásra térnek át. Minimális konténerekben vagy olyan Kubernetes podokban, amelyekben nincs /dev/fuse eszközátadá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 alkalmazást teljesen felhasználói térben
A gvx mind az öt kernel-akadályt megkerüli, mert nem kéri a host Linux kerneltől névterek létrehozását, fájlrendszerek csatlakoztatását vagy hálózati interfészek konfigurálását. Ehelyett a rungv egy belső, felhasználói térben futó 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 csatlakoztatási tábla (VFS2)
Amikor a dockerd, a containerd és a runc a rungv-n belül fut, a systrap elfogja a rendszerhívásaikat, és a folyamaton belüli Sentry kernelhez irányítja őket, nem pedig a host kernelhez:
- Az
unshare(2), aclone(2), apivot_root(2), achroot(2)és amount(2)a Sentry memórián belüli feladathierarchiáján ésVFS2csatlakoztatási tábláján (procfs,sysfs,tmpfs,devpts,cgroupfsv2) működik, miközben a hostrungvfolyamat az Ön nem privilegizált host UID-je alatt fut.
2. Natív overlayfs egyfájlos ext4lite kötetekon
Amikor a -v gvx-docker:/var/lib/docker (vagy a --mount type=volume,src=/disk/gvx-docker.ext4,dst=/var/lib/docker) paramétert adja meg, a gvx a beépített ext4lite fájlrendszert csatlakoztatja a /var/lib/docker útvonalra.
Mivel az ext4lite egy JBD2 naplózott ext4 fájlrendszert valósít meg egyetlen host fájlban (gvx-docker.ext4), és támogatja a trusted.overlay.* kiterjesztett attribútumokat, a karakteres whiteout eszközöket (0:0), a d_type mezőt és a RENAME_EXCHANGE műveletet, a dockerd a vendég oldalon a saját natív overlayfs tárolóillesztőjét használja. A többlépcsős docker build műveletek Copy-on-Write rétegeket osztanak meg a /dev/fuse nélkül, és 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 elindul a gvx-en belül:
- 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érbelinetstackrétegébenaddrtypeésconntrackillesztésekkel programozza aNAT(DOCKER,POSTROUTING) ésFILTERláncokat. - A
-p unix:~/.gvx/docker.sock:2375megadása egy host Unix domain socketet köt (0600mód), és a kapcsolatokat közvetlenül a homokozón belülidockerd2375portjára továbbítja.
Összehasonlítás a meglévő konténer-eszközökkel
| Képesség / korlátozás | Szabványos Docker (dockerd) | Rootless Docker / Podman | Kaniko / Buildah (jogosultság nélkül) | gvx (rungv + docker:dind) |
|---|---|---|---|---|
Host 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) | N/A | Nem | Buildah: Nem / Kaniko: Igen | Igen |
Működik /dev/fuse nélkül | Igen (kernel overlay2-t használ) | Csak lassú vfs másolással | Igen | Igen (overlayfs ext4lite-on) |
Támogatja a docker build (BuildKit) parancsot | Igen | Igen (ha a userns engedélyezett) | Csak image build (futtatás nélkül) | Igen |
Támogatja a docker run és a docker compose up parancsot | Igen | Igen (ha a userns engedélyezett) | Nem | Igen |
| Fut Windows és macOS rendszeren Linux VM nélkül | Nem (WSL2 / VM szükséges) | Nem (Linux VM szükséges) | Nem | Igen (whpx, hvf, systrap) |
Pontos host kernel követelmények Linuxon
A gvx nulla megemelt képességet (CapEff: 0000000000000000) és nulla felhasználói névteret igényel. Linux host esetén 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, csatlakozik hozzá a megosztott memóriakontextus inicializálásához, majd leválik róla. Ha a host beállítja akernel.yama.ptrace_scope = 3értéket (ami rendszerszinten letiltja aptracehívásokat), vagy egy külső seccomp szűrő blokkolja aptracehívást, asystrapinicializálása nem tud befejeződni. (Ayama.ptrace_scope = 1beállítás mellett, amely az Ubuntu és a Debian alapértelmezettje, agvxsikeresen fut, mert a szülő-gyermek nyomkövetés engedélyezett.)seccomp(SECCOMP_SET_MODE_FILTER): A konténer stub szálaiból érkező vendég rendszerhívások elfogására szolgál. Ahogy ennek a sorozatnak a 3. része ismerteti, agvxműködik akkor is, ha aSECCOMP_FILTER_FLAG_NEW_LISTENERelérhető, és akkor is, ha egy beágyazott homokozón belülEBUSYértéket ad vissza.mmap(..., PROT_EXEC, ...): A vendég ELF szegmensek és asystrapmegosztott memória trampolinjának leképezésére szolgál.
Végpontok közötti példa: több konténeres alkalmazás építése és tesztelése root nélkül
Az alábbi szkript egy teljes docker build műveletet és egy kétkonténeres integrációs tesztet (redis + alkalmazáskonténer) futtat egy 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 fájlrendszeren
20docker build -t demo-ping:latest .
21
22# Hídhá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ést végző konténerek törlése és a homokozó leállítása
29docker rm -f cache
30docker network rm demo-net
31kill -INT $DIND_PID
További olvasnivaló 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) ésnetstackkomponensei. - 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 gVisoron és beágyazott homokozókban a gvx segítségével: Hogyan oldja meg a
gvxamodprobe, aziptables-nft, azoverlay2agofer-en, valamint a beágyazottSECCOMP_FILTER_FLAG_NEW_LISTENER(EBUSY) problémáit agVisor(runsc) környezetben. - Gyors, izolált Docker-környezetek AI-ügynökök RL-kipróbálásaihoz a gvx segítségével: Párhuzamos
SWE-benchés RL-kipróbálási környezetek skálázása 100 milliszekundumos copy-on-write.ext4kötetvisszaállítással.