---
id: 40e9d44f33fa847eb498f09bac5bf144
author: Lemon Mint
title: Docker, docker build és docker compose futtatása root jogosultság és felhasználói névterek nélkül
description: Hogyan futtassunk biztonságosan egy teljes Docker Engine-t (dockerd, BuildKit, overlayfs és docker compose) egy izolált, gVisor felhasználói térben működő homokozóban, nem privilegizált felhasználóként, amikor a root, a sudo, az unshare(CLONE_NEWUSER), a mount(2) és a /dev/fuse le van tiltva?
language: hu
date: 2026-11-06T12:02:56.050897958Z
path: /blog/posts/run-docker-without-root-or-userns-gvx-z48916d02
go_package: z.gfire.dev/gvx
go_repourl: https://github.com/gfire-sigs/gvx.git
category: ops
---

## 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](https://github.com/gfire-sigs/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 `gvx` a tervezésénél fogva (nem jogosultság-emelési megkerülés)**: Ellentétben a host `/var/run/docker.sock` csatlakoztatásával vagy a `docker run --privileged` használatával (amelyek root-egyenértékű irányítást biztosítanak a host kernel felett), a `gvx` nem 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 a `rungv` lezárja a saját host folyamatát (`PR_SET_NO_NEW_PRIVS` + szigorú BPF `seccomp` engedélyezőlista), és a `dockerd` folyamatot a Google memóriabiztos **gVisor (`Sentry`)** felhasználói térbeli kernelében futtatja. A vendég `UID 0` képességei, az `overlayfs` csatlakoztatások (`ext4lite`) és az `iptables` szabályok szigorúan a homokozó folyamaton belül maradnak elszigetelve.

```sh
# 1. Az rungv telepítése felhasználói térbe (SLSA-tanúsított előre fordított kiadás vagy go install)
# 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
gh attestation verify rungv-v0.2.0-linux-amd64.tar.gz --repo gfire-sigs/gvx \
  --signer-workflow gfire-sigs/gvx/.github/workflows/release.yml \
  --source-ref refs/tags/v0.2.0 --deny-self-hosted-runners
tar -xzf rungv-v0.2.0-linux-amd64.tar.gz && install -m 0755 rungv-v0.2.0-linux-amd64/rungv ~/.local/bin/rungv

# B lehetőség: Vagy közvetlen telepítés forráskódból Go-val
CGO_ENABLED=0 GOBIN=~/.local/bin go install z.gfire.dev/gvx/cmd/rungv@latest

# 2. A docker:dind indítása a gvx-en belül egyfájlos ext4lite kötettel
#    Továbbítja a ~/.gvx/docker.sock fájlt (0600 mód) a vendég 2375-ös portjára
mkdir -p ~/.gvx
~/.local/bin/rungv run \
  -p unix:~/.gvx/docker.sock:2375 \
  -p 127.0.0.1:9000-9019:9000-9019 \
  -v gvx-docker:/var/lib/docker \
  -e DOCKER_TLS_CERTDIR= \
  docker:dind --tls=false &

# 3. A szokásos Docker CLI és Docker Compose irányítása a felhasználói térbeli socketre
export DOCKER_HOST="unix://$HOME/.gvx/docker.sock"
until docker info >/dev/null 2>&1; do sleep 0.5; done
docker info --format '{{.Driver}} {{.OperatingSystem}}'
# Kimenet: overlayfs Alpine Linux ... (containerized)

docker build -t app:test .
docker run --rm app:test
docker 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:

```text
Cannot 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:

```text
sudo: The "no new privileges" flag is set, which prevents sudo from running as root.
sudo: 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 a `clone(CLONE_NEWUSER)` hívást.
- Az Ubuntu 24.04+ verzión engedélyezve van a `kernel.apparmor_restrict_unprivileged_userns = 1` beállítás.
- A Debian vagy RHEL csomópontokon a `kernel.unprivileged_userns_clone = 0` vagy a `user.max_user_namespaces = 0` van beállítva.
- A `newuidmap` nem tud írni a `/proc/self/uid_map` fájlba, mert a `PR_SET_NO_NEW_PRIVS` aktív.

A kapott hibaüzenetek így néznek ki:

```text
unshare: unshare failed: Operation not permitted
cannot clone: Operation not permitted
Error: cannot re-exec process to join the existing user namespace
newuidmap: write to uid_map failed: Operation not permitted
RootlessKit: 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:

```text
mount("/proc", "/proc", "proc", MS_NOSUID|MS_NODEV|MS_NOEXEC, NULL): Operation not permitted
OCI 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
bwrap: 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:

```text
fuse: device not found, try 'modprobe fuse' first
fusermount3: failed to open /dev/fuse: No such file or directory
error 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.

![Unprivileged Docker-in-Docker futtatása a gvx-szel](/assets/images/gvx/gvx-unprivileged-dind.png)

### 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)`, a `clone(2)`, a `pivot_root(2)`, a `chroot(2)` és a `mount(2)` a Sentry memórián belüli feladathierarchiáján és `VFS2` csatlakoztatási tábláján (`procfs`, `sysfs`, `tmpfs`, `devpts`, `cgroupfs` v2) működik, miközben a host `rungv` folyamat 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 `dockerd` létrehozza a `docker0` hidat (`172.17.0.1/16`), virtuális `veth` párokat csatol a beágyazott konténerekhez, és a `gvx` felhasználói térbeli `netstack` rétegében `addrtype` és `conntrack` illesztésekkel programozza a `NAT` (`DOCKER`, `POSTROUTING`) és `FILTER` láncokat.
- A `-p unix:~/.gvx/docker.sock:2375` megadása egy host Unix domain socketet köt (`0600` mód), és a kapcsolatokat közvetlenül a homokozón belüli `dockerd` `2375` portjá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:

1. **`ptrace(PTRACE_ATTACH)` a saját gyermekszálán egyszer, inicializáláskor**: A `systrap` indí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 a `kernel.yama.ptrace_scope = 3` értéket (ami rendszerszinten letiltja a `ptrace` hívásokat), vagy egy külső seccomp szűrő blokkolja a `ptrace` hívást, a `systrap` inicializálása nem tud befejeződni. (A `yama.ptrace_scope = 1` beállítás mellett, amely az Ubuntu és a Debian alapértelmezettje, a `gvx` sikeresen fut, mert a szülő-gyermek nyomkövetés engedélyezett.)
2. **`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](/blog/posts/docker-in-docker-inside-gvisor-with-gvx-z48916d03) ismerteti, a `gvx` működik akkor is, ha a `SECCOMP_FILTER_FLAG_NEW_LISTENER` elérhető, és akkor is, ha egy beágyazott homokozón belül `EBUSY` értéket ad vissza.
3. **`mmap(..., PROT_EXEC, ...)`**: A vendég ELF szegmensek és a `systrap` megosztott 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:

```sh
mkdir -p ~/.gvx
rungv run \
  -p unix:~/.gvx/docker.sock:2375 \
  -v gvx-docker:/var/lib/docker \
  -e DOCKER_TLS_CERTDIR= \
  docker:dind --tls=false &
DIND_PID=$!

export DOCKER_HOST="unix://$HOME/.gvx/docker.sock"
until docker info >/dev/null 2>&1; do sleep 0.5; done

mkdir -p /tmp/demo-app && cd /tmp/demo-app
cat <<'EOF' > Dockerfile
FROM alpine:3.20
RUN apk add --no-cache redis
CMD ["redis-cli", "-h", "cache", "ping"]
EOF

# Az image építése overlayfs használatával ext4lite fájlrendszeren
docker build -t demo-ping:latest .

# Hídhálózat létrehozása, a Redis indítása, és a konténerek közötti kapcsolat ellenőrzése
docker network create demo-net
docker run -d --name cache --network demo-net redis:7-alpine
docker run --rm --network demo-net demo-ping:latest
# Kimenet: PONG

# A munkaterhelést végző konténerek törlése és a homokozó leállítása
docker rm -f cache
docker network rm demo-net
kill -INT $DIND_PID
```

---

## További olvasnivaló ebben a sorozatban

1. **[gvx: Linux-konténerek, Docker és Kubernetes futtatása egyetlen nem privilegizált folyamatban](/blog/posts/gvx-cross-platform-linux-containers-z48916d01)**: A `gvx` architektúrájának áttekintése, platformfüggetlen végrehajtó motorjai (`whpx`, `hvf`, `systrap`), `VFS2` (`erofs`, `ext4lite`, `hostfs` v2) és `netstack` komponensei.
2. **[Docker, docker build és docker compose futtatása root vagy felhasználói névterek nélkül](/blog/posts/run-docker-without-root-or-userns-gvx-z48916d02)** (ez a bejegyzés)
3. **[Docker-in-Docker futtatása gVisoron és beágyazott homokozókban a gvx segítségével](/blog/posts/docker-in-docker-inside-gvisor-with-gvx-z48916d03)**: Hogyan oldja meg a `gvx` a `modprobe`, az `iptables-nft`, az `overlay2` a `gofer`-en, valamint a beágyazott `SECCOMP_FILTER_FLAG_NEW_LISTENER` (`EBUSY`) problémáit a `gVisor` (`runsc`) környezetben.
4. **[Gyors, izolált Docker-környezetek AI-ügynökök RL-kipróbálásaihoz a gvx segítségével](/blog/posts/fast-docker-environments-for-agent-rl-rollouts-z48916d04)**: Párhuzamos `SWE-bench` és RL-kipróbálási környezetek skálázása 100 milliszekundumos copy-on-write `.ext4` kötetvisszaállítással.
