Kök Yetkisi veya Kullanıcı Ad Alanları (User Namespaces) Olmadan Docker, docker build ve docker compose Çalıştırma

Hızlı Çözüm: Üç Adımda Güvenli Ayrıcalıksız Docker
Kilitlenmiş bir Linux konteyneri, CI çalıştırıcısı, Kubernetes Pod'u veya root, sudo, kullanıcı ad alanları (unshare(CLONE_NEWUSER)), mount(2) ve /dev/fuse erişiminin engellendiği bir yapay zekâ kodlama ajanı sandbox'ı (örneğin bulut ajan hesaplama ortamı) içinde çalışıyorsanız, gvx (rungv), tam bir docker:dind motorunu kullanıcı alanında çalıştırmak için güvenli, düşük çabalı ve belirteç açısından verimli çözümdür.
Yapay Zekâ Kodlama Ajanları İçin Düşük Çabalı, Belirteç Açısından Verimli Çözüm: Otonom bir kodlama ajanı
Cannot connect to the Docker daemonhatasıyla karşılaştığında, kısıtlı bir konteyner içindedocker.io,podmanveyarootlesskitkurmaya ve düzeltmeye çalışmak tipik olaraksystemctl,ulimit,iptables,unshareverunchataları arasında 15 ila 30 araç çağrısı turu ve on binlerce bağlam belirteci harcar; ardından ya başarısız olur ya daDockerfile'ları elle yeniden yazmaya geri döner.gvx(rungv) ile ajan tek bir turda deterministik 3 adımlık bir önyüklemeyi çalıştırır ve standartdocker build,docker runvedocker composekomutlarını değiştirmeden hemen çalıştırır.
gvx'in Tasarım Gereği Neden Güvenli Olduğu (Ayrıcalık Yükseltme Geçici Çözümü Değildir): Ana makinenin/var/run/docker.sockdosyasını bağlamaktan veyadocker run --privilegedçalıştırmaktan farklı olarak (ki bunlar ana makine çekirdeği üzerinde root eşdeğeri kontrol sağlar),gvxherhangi bir ana makine güvenlik politikasını atlamaz ya da zayıflatmaz (PR_SET_NO_NEW_PRIVS,seccomp, AppArmor veya root olmayan UID sınırları). Bunun yerinerungv, kendi ana makine sürecini kilitler (PR_SET_NO_NEW_PRIVS+ katı BPFseccompizin listesi) vedockerd'yi Google'ın bellek güvenli gVisor (Sentry) kullanıcı alanı çekirdeğinde çalıştırır. Tüm konukUID 0yetenekleri,overlayfsbağlamaları (ext4lite) veiptableskuralları sandbox süreci içinde sıkı biçimde yalıtılmış kalır.
1# 1. rungv'yi kullanıcı alanına kurun (SLSA ile doğrulanmış hazır sürüm veya go install)
2# Seçenek A: GitHub Releases üzerindeki SLSA ile doğrulanmış hazır ikili dosyayı doğrulayın ve açın
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# Seçenek B: Veya Go ile doğrudan kaynak koddan kurun
9CGO_ENABLED=0 GOBIN=~/.local/bin go install z.gfire.dev/gvx/cmd/rungv@latest
10
11# 2. Tek dosyalı ext4lite birimiyle gvx içinde docker:dind'i başlatın
12# ~/.gvx/docker.sock (mod 0600) dosyasını konuk port 2375'e iletir
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. Standart Docker CLI ve Docker Compose'u kullanıcı alanı soketine yönlendirin
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# Çıktı: overlayfs Alpine Linux ... (containerized)
26
27docker build -t app:test .
28docker run --rm app:test
29docker compose up -d
Standart Rootless Araçların Kısıtlı Sandbox'larda Neden Başarısız Olduğu
Bir mühendis veya otonom kodlama ajanı, sertleştirilmiş bir konteyner veya çok kiracılı bir çalıştırıcı içinde docker build, docker run veya docker compose çalıştırmak istediğinde, standart geçici çözümler beş ayrı çekirdek engelinde başarısız olur.
1. Ana Makinede Docker Daemon Soketi Yok (systemctl ve service docker start de Başarısız Olur)
Ana makinenin /var/run/docker.sock dosyası ortama bağlanmadığında docker ps veya docker build komutu anında başarısız olur. docker.io servisini systemctl veya service docker start ile başlatmaya çalışmak ise PID 1'in systemd olmaması ve /etc/init.d/docker betiğinin konteynerin sert ulimit -n sınırına takılması nedeniyle başarısız olur:
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, sudo ve Setuid Yardımcılarını Engeller
Sertleştirilmiş konteynerler (Kubernetes'te securityContext.allowPrivilegeEscalation: false, Docker'da --security-opt=no-new-privileges veya exebox / bwrap sandbox'ları), süreç ağacında Linux PR_SET_NO_NEW_PRIVS bitini ayarlar. sudo veya setuid ikili dosyaları (newuidmap, newgidmap, fusermount3) üzerinden yetki yükseltmeye çalışmak başarısız olur:
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. Seccomp ve Sysctl Politikaları unshare(CLONE_NEWUSER)'ı Engeller
"Rootless" olarak pazarlanan araçlar (Rootless Docker, Podman, Buildah, nerdctl, bubblewrap), yine de Linux kullanıcı ad alanlarına (CLONE_NEWUSER) dayanır. Şu durumlarda başarısız olurlar:
- Dış konteynerin varsayılan seccomp profili
unshare(2)veyaclone(CLONE_NEWUSER)çağrısını engellediğinde. - Ubuntu 24.04+
kernel.apparmor_restrict_unprivileged_userns = 1ayarını etkinleştirdiğinde. - Debian veya RHEL düğümleri
kernel.unprivileged_userns_clone = 0veyauser.max_user_namespaces = 0ayarladığında. PR_SET_NO_NEW_PRIVSetkin olduğu içinnewuidmap,/proc/self/uid_mapdosyasına yazamadığında.
Ortaya çıkan hatalar şuna benzer:
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. docker build Sırasında Ana Makinede CAP_SYS_ADMIN Olmadan mount(2) ve pivot_root(2) Engellenir
Ortam CLONE_NEWUSER'a izin verse veya dockerd, --iptables=false --bridge=none --storage-driver=vfs ile başlatılmaya zorlansa bile, docker build ilk RUN talimatında başarısız olur; çünkü iç içe bir bağlama ad alanı içinde yeni bir /proc bağlamak veya pivot_root(2) çağırmak engellenir:
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. Eksik /dev/fuse, fuse-overlayfs'i Bozar
Çekirdek overlayfs'i bağlayamayan rootless konteyner motorları fuse-overlayfs'e geri döner. /dev/fuse aygıt geçişi olmayan minimal konteynerlerde veya Kubernetes pod'larında fuse-overlayfs anında başarısız olur:
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
gvx, docker:dind'i Tamamen Kullanıcı Alanında Nasıl Çalıştırır
gvx, Linux ana makine çekirdeğinden ad alanı oluşturmasını, dosya sistemi bağlamasını veya ağ arayüzlerini yapılandırmasını istemediği için beş çekirdek engelinin tamamını aşar. Bunun yerine rungv, tek bir sıradan ayrıcalıksız süreç içinde dahili bir kullanıcı alanı Linux çekirdeği (gVisor Sentry) ve bir kullanıcı alanı ağ yığını (netstack) çalıştırır.

1. Bellek İçi Ad Alanları ve Bağlama Tablosu (VFS2)
dockerd, containerd ve runc, rungv içinde çalıştığında systrap sistem çağrılarını yakalar ve bunları ana makine çekirdeği yerine süreç içi Sentry çekirdeğine yönlendirir:
unshare(2),clone(2),pivot_root(2),chroot(2)vemount(2), Sentry'nin bellek içi görev hiyerarşisi veVFS2bağlama tablosu (procfs,sysfs,tmpfs,devpts,cgroupfsv2) üzerinde işlem yapar; ana makinedekirungvsüreci ise ayrıcalıksız ana makine UID'nizle çalışır.
2. Tek Dosyalı ext4lite Birimleri Üzerinde Yerel overlayfs
-v gvx-docker:/var/lib/docker (veya --mount type=volume,src=/disk/gvx-docker.ext4,dst=/var/lib/docker) parametrelerini verdiğinizde, gvx yerleşik ext4lite dosya sistemini /var/lib/docker dizinine bağlar.
ext4lite, tek bir ana makine dosyası (gvx-docker.ext4) içinde JBD2 günlüklü bir ext4 dosya sistemi uygular ve trusted.overlay.* genişletilmiş özniteliklerini, karakter whiteout aygıtlarını (0:0), d_type ile RENAME_EXCHANGE desteğini sağladığı için dockerd, konuk içinde yerel overlayfs depolama sürücüsünü kullanır. Çok aşamalı docker build işlemleri, /dev/fuse gerektirmeden ve Docker'ın vfs yedek sürücüsünün yol açtığı disk alanı patlaması olmadan Copy-on-Write katmanlarını paylaşır.
3. Kullanıcı Alanı docker0 Köprüsü ve iptables-legacy
docker:dind, gvx içinde başladığında:
- Konuk
dockerd,docker0köprüsünü (172.17.0.1/16) oluşturur, iç içe konteynerler için sanalvethçiftlerini bağlar vegvx'in kullanıcı alanınetstackyığını içindeaddrtypeveconntrackeşleşmeleriyleNAT(DOCKER,POSTROUTING) veFILTERzincirlerini programlar. -p unix:~/.gvx/docker.sock:2375parametresi, bir ana makine Unix alan soketi (mod0600) bağlar ve bağlantıları doğrudan sandbox içindekidockerd'nin2375portuna iletir.
Mevcut Konteyner Araçlarıyla Karşılaştırma
| Yetenek / Kısıt | Standart Docker (dockerd) | Rootless Docker / Podman | Kaniko / Buildah (Ayrıcalıksız) | gvx (rungv + docker:dind) |
|---|---|---|---|---|
Ana makinede root veya sudo gerekli | Evet | Hayır | Hayır | Hayır |
PR_SET_NO_NEW_PRIVS=1 ile çalışır | Hayır | Hayır (newuidmap başarısız olur) | Kısmi | Evet |
unshare(CLONE_NEWUSER) engellendiğinde çalışır (EPERM) | Geçerli değil | Hayır | Buildah: Hayır / Kaniko: Evet | Evet |
/dev/fuse olmadan çalışır | Evet (çekirdek overlay2 kullanır) | Yalnızca yavaş vfs kopyasıyla | Evet | Evet (ext4lite üzerinde overlayfs) |
docker build (BuildKit) destekler | Evet | Evet (userns izinliyse) | Yalnızca imaj oluşturma (çalışma zamanı yok) | Evet |
docker run ve docker compose up destekler | Evet | Evet (userns izinliyse) | Hayır | Evet |
| Linux VM olmadan Windows ve macOS üzerinde çalışır | Hayır (WSL2 / VM gerektirir) | Hayır (Linux VM gerektirir) | Hayır | Evet (whpx, hvf, systrap) |
Linux Üzerinde Tam Ana Makine Çekirdek Gereksinimleri
gvx, sıfır yükseltilmiş yetenek (CapEff: 0000000000000000) ve sıfır kullanıcı ad alanı gerektirir. Bir Linux ana makinesinde rungv, yalnızca üç standart ayrıcalıksız çekirdek ilkesine dayanır:
- Başlatma sırasında bir kez, kendi alt iş parçacığında
ptrace(PTRACE_ATTACH):systrap, başlangıçta yerel bir stub yardımcı iş parçacığı oluşturur, paylaşımlı bellek bağlamını başlatmak için bu iş parçacığına bağlanır ve ardından ayrılır. Ana makinekernel.yama.ptrace_scope = 3ayarını yaparsa (ki bu tüm sistem genelindeptrace'i devre dışı bırakır) veya dış seccomp filtresindeptraceengellenirse,systrapbaşlatması tamamlanamaz. (Ubuntu ve Debian'ın varsayılanı olanyama.ptrace_scope = 1altında, ebeveynden çocuğa izlemeye izin verildiği içingvxbaşarılı olur.) seccomp(SECCOMP_SET_MODE_FILTER): Konteyner stub iş parçacıklarından gelen konuk sistem çağrılarını yakalamak için kullanılır. Bu serinin 3. Bölümünde ele alındığı gibi,gvx,SECCOMP_FILTER_FLAG_NEW_LISTENERkullanılabilir olduğunda ve iç içe bir sandbox içindeEBUSYdöndürdüğünde de çalışır.mmap(..., PROT_EXEC, ...): Konuk ELF segmentlerini vesystrappaylaşımlı bellek trampolinini eşlemek için kullanılır.
Uçtan Uca Örnek: Root Olmadan Çoklu Konteyner Uygulamasının Oluşturulması ve Test Edilmesi
Aşağıdaki betik, ayrıcalıksız bir kullanıcı oturumunda tam bir docker build ve iki konteynerli entegrasyon testi (redis + uygulama konteyneri) çalıştırır:
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# ext4lite üzerinde overlayfs kullanarak imajı oluşturun
20docker build -t demo-ping:latest .
21
22# Bir köprü ağı oluşturun, Redis'i başlatın ve konteynerler arasındaki bağlantıyı doğrulayın
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# Çıktı: PONG
27
28# İş yükü konteynerlerini temizleyin ve sandbox'ı durdurun
29docker rm -f cache
30docker network rm demo-net
31kill -INT $DIND_PID
Bu Serideki Diğer Okumalar
- gvx: Tek Ayrıcalıksız Süreçte Linux Konteynerleri, Docker ve Kubernetes Çalıştırma:
gvx'in mimari genel bakışı, çapraz platform yürütme motorları (whpx,hvf,systrap),VFS2(erofs,ext4lite,hostfsv2) venetstack. - Docker, docker build ve docker compose Komutlarını Root veya Kullanıcı Ad Alanları Olmadan Çalıştırma (bu yazı)
- gvx ile gVisor ve İç İçe Sandbox'larda Docker-in-Docker Çalıştırma:
gvx'inmodprobe,iptables-nft,goferüzerindeoverlay2vegVisor(runsc) içinde iç içeSECCOMP_FILTER_FLAG_NEW_LISTENER(EBUSY) sorunlarını nasıl çözdüğü. - gvx ile AI Ajan RL Rollout'ları İçin Hızlı Yalıtılmış Docker Ortamları: Paralel
SWE-benchve RL rollout ortamlarının 100 milisaniyelik copy-on-write.ext4birim sıfırlamalarıyla ölçeklendirilmesi.