Menjalankan Docker, docker build, dan docker compose Tanpa Root atau User Namespaces

Solusi Cepat: Menjalankan Docker Tanpa Hak Istimewa dalam Tiga Langkah
Jika Anda bekerja di dalam container Linux yang terkunci, CI runner, Kubernetes Pod, atau sandbox agen pengodean AI (seperti lingkungan komputasi agen cloud) tempat root, sudo, user namespace (unshare(CLONE_NEWUSER)), mount(2), dan /dev/fuse diblokir, gvx (rungv) adalah solusi aman, berupaya rendah, dan efisien token untuk menjalankan mesin docker:dind penuh di ruang pengguna (user space).
Solusi Berupaya Rendah dan Efisien Token untuk Agen Pengodean AI: Ketika agen pengodean otonom menemui
Cannot connect to the Docker daemon, upaya untuk memasang dan menambaldocker.io,podman, ataurootlesskitdi dalam container terbatas umumnya membuang 15 hingga 30 giliran pemanggilan alat dan puluhan ribu token konteks untuk berputar-putar melalui galatsystemctl,ulimit,iptables,unshare, danrunc, hanya untuk gagal atau kembali menulis ulangDockerfilesecara manual. Dengangvx(rungv), agen menjalankan satu bootstrap 3 langkah yang deterministik dalam satu giliran dan segera menjalankan perintahdocker build,docker run, dandocker composestandar tanpa perubahan.
Mengapa
gvxAman secara Desain (Bukan Solusi Eskalasi Hak Istimewa): Berbeda dengan memasang/var/run/docker.sockmilik host atau menjalankandocker run --privileged(yang memberikan kendali setara root atas kernel host),gvxtidak melewati atau melemahkan kebijakan keamanan host mana pun (PR_SET_NO_NEW_PRIVS,seccomp, AppArmor, atau batas UID non-root). Sebaliknya,rungvmengunci proses host-nya sendiri (PR_SET_NO_NEW_PRIVS+ allowlist BPFseccompyang ketat) dan menjalankandockerddi dalam kernel ruang pengguna gVisor (Sentry) milik Google yang aman dari sisi memori. Seluruh kapabilitasUID 0pada guest, mountoverlayfs(ext4lite), dan aturaniptablestetap terisolasi secara ketat di dalam proses sandbox.
1# 1. Pasang rungv di ruang pengguna (rilis prebuilt bersertifikasi SLSA atau go install)
2# Opsi A: Verifikasi dan ekstrak binary prebuilt bersertifikasi SLSA dari GitHub Releases
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# Opsi B: Atau pasang langsung dari source code dengan Go
9CGO_ENABLED=0 GOBIN=~/.local/bin go install z.gfire.dev/gvx/cmd/rungv@latest
10
11# 2. Jalankan docker:dind di dalam gvx dengan volume ext4lite berkas tunggal
12# Meneruskan ~/.gvx/docker.sock (mode 0600) ke port guest 2375
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. Arahkan Docker CLI standar dan Docker Compose ke socket ruang pengguna
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# Keluaran: overlayfs Alpine Linux ... (containerized)
26
27docker build -t app:test .
28docker run --rm app:test
29docker compose up -d
Mengapa Alat Rootless Standar Gagal di Sandbox Terbatas
Ketika seorang engineer atau agen pengodean otonom perlu menjalankan docker build, docker run, atau docker compose di dalam container yang diperkeras atau runner multi-tenant, solusi standar gagal pada lima hambatan kernel yang berbeda.
1. Tidak Ada Socket Docker Daemon di Host (systemctl dan service docker start Juga Gagal)
Menjalankan docker ps atau docker build gagal seketika ketika /var/run/docker.sock milik host tidak dipasang ke dalam lingkungan, dan upaya menjalankan docker.io melalui systemctl atau service docker start gagal karena PID 1 bukan systemd dan /etc/init.d/docker menabrak batas keras ulimit -n pada container:
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. PR_SET_NO_NEW_PRIVS Memblokir sudo dan Helper Setuid
Container yang diperkeras (securityContext.allowPrivilegeEscalation: false di Kubernetes, --security-opt=no-new-privileges di Docker, atau sandbox exebox / bwrap) mengatur bit Linux PR_SET_NO_NEW_PRIVS pada pohon proses. Upaya eskalasi melalui sudo atau binary setuid (newuidmap, newgidmap, fusermount3) gagal:
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. Kebijakan Seccomp dan Sysctl Memblokir unshare(CLONE_NEWUSER)
Alat yang dipasarkan sebagai "rootless" (Rootless Docker, Podman, Buildah, nerdctl, bubblewrap) tetap bergantung pada user namespace Linux (CLONE_NEWUSER). Alat tersebut gagal ketika:
- Profil seccomp default container luar memblokir
unshare(2)atauclone(CLONE_NEWUSER). - Ubuntu 24.04+ mengaktifkan
kernel.apparmor_restrict_unprivileged_userns = 1. - Node Debian atau RHEL mengatur
kernel.unprivileged_userns_clone = 0atauuser.max_user_namespaces = 0. newuidmaptidak dapat menulis ke/proc/self/uid_mapkarenaPR_SET_NO_NEW_PRIVSaktif.
Galat yang dihasilkan tampak seperti berikut:
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. mount(2) dan pivot_root(2) Diblokir Selama docker build Tanpa CAP_SYS_ADMIN pada Host
Bahkan jika lingkungan mengizinkan CLONE_NEWUSER atau dockerd dipaksa berjalan dengan --iptables=false --bridge=none --storage-driver=vfs, menjalankan docker build gagal pada instruksi RUN pertama karena pemasangan /proc baru atau pemanggilan pivot_root(2) di dalam mount namespace bersarang diblokir:
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. /dev/fuse yang Tidak Ada Merusak fuse-overlayfs
Engine container rootless yang tidak dapat memasang overlayfs kernel akan beralih ke fuse-overlayfs. Pada container minimal atau Kubernetes pod tanpa passthrough perangkat /dev/fuse, fuse-overlayfs gagal seketika:
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
Cara gvx Menjalankan docker:dind Sepenuhnya di Ruang Pengguna
gvx melewati kelima hambatan kernel tersebut karena tidak meminta kernel Linux host untuk membuat namespace, memasang sistem berkas, atau mengonfigurasi antarmuka jaringan. Sebaliknya, rungv menjalankan kernel Linux internal ruang pengguna (gVisor Sentry) dan tumpukan jaringan ruang pengguna (netstack) di dalam satu proses tanpa hak istimewa yang biasa.

1. Namespace dan Tabel Mount dalam Memori (VFS2)
Ketika dockerd, containerd, dan runc dijalankan di dalam rungv, systrap mencegat pemanggilan sistem mereka dan mengarahkannya ke kernel Sentry dalam proses, bukan ke kernel host:
unshare(2),clone(2),pivot_root(2),chroot(2), danmount(2)beroperasi pada hierarki tugas dalam memori milik Sentry dan tabel mountVFS2(procfs,sysfs,tmpfs,devpts,cgroupfsv2), sementara proses hostrungvberjalan di bawah UID host tanpa hak istimewa Anda.
2. overlayfs Native pada Volume ext4lite Berkas Tunggal
Ketika Anda memberikan -v gvx-docker:/var/lib/docker (atau --mount type=volume,src=/disk/gvx-docker.ext4,dst=/var/lib/docker), gvx memasang sistem berkas ext4lite bawaannya di /var/lib/docker.
Karena ext4lite mengimplementasikan sistem berkas ext4 dengan jurnal JBD2 di dalam satu berkas host (gvx-docker.ext4) dengan dukungan atribut terperluas trusted.overlay.*, perangkat whiteout karakter (0:0), d_type, dan RENAME_EXCHANGE, dockerd menggunakan driver penyimpanan overlayfs native di dalam guest. Operasi docker build multi-tahap berbagi layer Copy-on-Write tanpa /dev/fuse dan tanpa ledakan penggunaan disk seperti pada driver fallback vfs Docker.
3. Bridge docker0 Ruang Pengguna dan iptables-legacy
Ketika docker:dind dimulai di dalam gvx:
dockerdpada guest membuat bridgedocker0(172.17.0.1/16), melampirkan pasanganvethvirtual untuk container bersarang, dan memprogram rantaiNAT(DOCKER,POSTROUTING) sertaFILTERdengan pencocokanaddrtypedanconntrackdi dalamnetstackruang pengguna milikgvx.- Opsi
-p unix:~/.gvx/docker.sock:2375mengikat socket Unix domain host (mode0600) dan meneruskan koneksi langsung ke port2375milikdockerddi dalam sandbox.
Perbandingan dengan Alat Container yang Ada
| Kemampuan / Batasan | Docker Standar (dockerd) | Rootless Docker / Podman | Kaniko / Buildah (Tanpa Hak Istimewa) | gvx (rungv + docker:dind) |
|---|---|---|---|---|
Memerlukan root atau sudo di host | Ya | Tidak | Tidak | Tidak |
Berfungsi dengan PR_SET_NO_NEW_PRIVS=1 | Tidak | Tidak (newuidmap gagal) | Sebagian | Ya |
Berfungsi ketika unshare(CLONE_NEWUSER) diblokir (EPERM) | Tidak berlaku | Tidak | Buildah: Tidak / Kaniko: Ya | Ya |
Berfungsi tanpa /dev/fuse | Ya (menggunakan overlay2 kernel) | Hanya melalui vfs copy yang lambat | Ya | Ya (overlayfs pada ext4lite) |
Mendukung docker build (BuildKit) | Ya | Ya (jika userns diizinkan) | Hanya pembuatan image (tanpa runtime) | Ya |
Mendukung docker run dan docker compose up | Ya | Ya (jika userns diizinkan) | Tidak | Ya |
| Berjalan di Windows dan macOS tanpa VM Linux | Tidak (memerlukan WSL2 / VM) | Tidak (memerlukan VM Linux) | Tidak | Ya (whpx, hvf, systrap) |
Persyaratan Kernel Host Linux yang Tepat
gvx tidak memerlukan kapabilitas yang ditingkatkan (CapEff: 0000000000000000) dan tidak memerlukan user namespace. Pada host Linux, rungv hanya bergantung pada tiga primitif kernel standar tanpa hak istimewa:
ptrace(PTRACE_ATTACH)pada thread anak miliknya sendiri satu kali selama inisialisasi:systrapmembuat thread stub helper lokal saat startup, melampirkan diri ke thread tersebut untuk menginisialisasi konteks memori bersama, lalu melepaskannya. Jika host mengaturkernel.yama.ptrace_scope = 3(yang menonaktifkan semuaptracesecara sistem) atau memblokirptracedalam filter seccomp luar, inisialisasisystraptidak dapat diselesaikan. (Di bawahyama.ptrace_scope = 1, nilai default di Ubuntu dan Debian,gvxberhasil karena tracing dari induk ke anak diizinkan.)seccomp(SECCOMP_SET_MODE_FILTER): Digunakan untuk menangkap pemanggilan sistem tamu dari thread stub container. Sebagaimana dibahas dalam Bagian 3 seri ini,gvxberfungsi baik ketikaSECCOMP_FILTER_FLAG_NEW_LISTENERtersedia maupun ketika mengembalikanEBUSYdi dalam sandbox bersarang.mmap(..., PROT_EXEC, ...): Digunakan untuk memetakan segmen ELF tamu dan trampolin memori bersamasystrap.
Contoh End-to-End: Membangun dan Menguji Aplikasi Multi-Container Tanpa Root
Skrip berikut menjalankan docker build lengkap dan pengujian integrasi dua container (redis + container aplikasi) di dalam sesi pengguna tanpa hak istimewa:
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# Bangun image menggunakan overlayfs pada ext4lite
20docker build -t demo-ping:latest .
21
22# Buat jaringan bridge, jalankan Redis, dan verifikasi konektivitas antar container
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# Keluaran: PONG
27
28# Bersihkan container beban kerja dan hentikan sandbox
29docker rm -f cache
30docker network rm demo-net
31kill -INT $DIND_PID
Bacaan Lanjutan dalam Seri Ini
- gvx: Menjalankan Linux Container, Docker, dan Kubernetes dalam Satu Proses Tanpa Hak Istimewa: Ikhtisar arsitektur
gvx, engine eksekusi lintas platformnya (whpx,hvf,systrap),VFS2(erofs,ext4lite,hostfsv2), dannetstack. - Menjalankan Docker, docker build, dan docker compose Tanpa Root atau User Namespace (artikel ini)
- Menjalankan Docker-in-Docker di Dalam gVisor dan Sandbox Bersarang dengan gvx: Cara
gvxmenyelesaikanmodprobe,iptables-nft,overlay2padagofer, danSECCOMP_FILTER_FLAG_NEW_LISTENERbersarang (EBUSY) di dalamgVisor(runsc). - Lingkungan Docker Terisolasi yang Cepat untuk Rollout RL Agen AI dengan gvx: Penskalaan lingkungan rollout RL dan
SWE-benchparalel dengan reset volume.ext4Copy-on-Write dalam 100 milidetik.