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

Hızlı Çözüm: Üç Adımda Ayrıcalıksız Docker'ı Güvenli Biçimde Çalıştırma
Kilitli bir Linux konteynerinde, CI çalıştırıcısında, Kubernetes Pod'unda veya root, sudo, kullanıcı ad alanları (unshare(CLONE_NEWUSER)), mount(2) ve /dev/fuse erişiminin engellendiği bir AI ajanı sandbox'ında çalışıyorsanız, gvx (rungv), tam bir docker:dind motorunu kullanıcı alanında çalıştırmak için güvenli, derinlemesine savunma (defense-in-depth) çözümüdür.
gvxNeden Tasarım Gereği Güvenlidir (Ayrıcalık Yükseltme Geçici Çözümü Değildir): Ana makinenin/var/run/docker.socksoketini bağlamanın ya dadocker run --privilegedkomutunu çalıştırmanın (bunlar ana makine çekirdeği üzerinde root eşdeğeri denetim sağlar) aksine,gvxherhangi bir ana makine güvenlik politikasını (PR_SET_NO_NEW_PRIVS,seccomp, AppArmor veya root olmayan UID sınırları) atlamaz ya da zayıflatmaz. 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ğinin içinde çalıştırır. Tüm konukUID 0yetenekleri,overlayfsbağlamaları (ext4lite) veiptableskuralları sandbox sürecinin içinde sıkı biçimde yalıtılmış kalır.
1# 1. rungv'yi kullanıcı alanına kurun (önceden derlenmiş, SLSA ile doğrulanmış sürüm veya go install)
2# Seçenek A: GitHub Releases üzerinden SLSA ile doğrulanmış önceden derlenmiş ikili dosyayı doğrulayın ve çıkarı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. docker:dind'i tek dosyalık bir ext4lite birimiyle gvx içinde başlatın
12# ~/.gvx/docker.sock (mod 0600) soketini konuk 2375 portuna 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 ... (konteynerleştirilmiş)
26
27docker build -t app:test .
28docker run --rm app:test
29docker compose up -d
Kısıtlı Sandbox'larda Standart Rootless Araçları Neden Başarısız Olur
Bir mühendis veya otonom kodlama ajanı, sertleştirilmiş bir konteyner ya da çok kiracılı bir çalıştırıcı içinde docker build, docker run veya docker compose komutlarını çalıştırmak istediğinde, standart geçici çözümler beş ayrı çekirdek engelinde başarısız olur.
1. Ana Makine Docker Daemon Soketi Yok
Ana makinenin /var/run/docker.sock soketi ortama bağlanmadığında docker ps veya docker build komutları hemen başarısız olur:
1Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
2. PR_SET_NO_NEW_PRIVS, sudo ve Setuid Yardımcı Programları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) aracılığıyla 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) Çağrısını 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ı engellerse. - Ubuntu 24.04 ve üzeri
kernel.apparmor_restrict_unprivileged_userns = 1ayarını etkinleştirirse. - Debian veya RHEL düğümleri
kernel.unprivileged_userns_clone = 0veyauser.max_user_namespaces = 0ayarlarını uygularsa. PR_SET_NO_NEW_PRIVSetkin olduğu içinnewuidmap,/proc/self/uid_mapdosyasına yazamazsa.
Ortaya çıkan hatalar şu şekildedir:
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. Ana Makine CAP_SYS_ADMIN Olmadan mount(2) Engellenir
Bir ortam CLONE_NEWUSER kullanımına izin verse bile, dış konteyner /proc alt ağaçlarını maskelemişse (/proc/acpi, /proc/kcore, /proc/keys) veya seccomp içinde mount(2) çağrısını bırakmışsa, iç içe bir mount ad alanında yeni bir /proc bağlamak başarısız olur:
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. Eksik /dev/fuse, fuse-overlayfs Çalışmasını Bozar
Çekirdek overlayfs bağlayamayan rootless konteyner motorları fuse-overlayfs kullanmaya geri döner. /dev/fuse aygıt geçişi olmayan minimal konteynerlerde veya Kubernetes pod'larında fuse-overlayfs hemen 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 çekirdeğinden ad alanları oluşturmasını, dosya sistemlerini 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, sıradan ayrıcalıksız tek bir 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 bu süreçlerin sistem çağrılarını yakalar ve bunları ana makine çekirdeğine değil, süreç içi Sentry çekirdeğine yönlendirir:
unshare(2),clone(2),pivot_root(2),chroot(2)vemount(2),rungvana makine süreci sizin ayrıcalıksız ana makine UID'nizde çalışırken Sentry'nin bellek içi görev hiyerarşisi veVFS2bağlama tablosu (procfs,sysfs,tmpfs,devpts,cgroupfsv2) üzerinde işlem yapar.
2. Tek Dosyalık ext4lite Birimleri Üzerinde Yerel overlayfs
-v gvx-docker:/var/lib/docker (veya --mount type=volume,src=/disk/gvx-docker.ext4,dst=/var/lib/docker) parametresini geçtiğ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ş öznitelikleri, karakter whiteout aygıtlarını (0:0), d_type ve RENAME_EXCHANGE desteğini içerir. Bu nedenle dockerd, konuk sistemde 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ına neden 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 ekler veNAT(DOCKER,POSTROUTING) ileFILTERzincirlerini,gvx'in kullanıcı alanınetstackyığını içindeaddrtypeveconntrackeşleşmeleriyle programlar. -p unix:~/.gvx/docker.sock:2375parametresini geçmek, ana makinede bir 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 makine root veya sudo gerektirir mi | Evet | Hayır | Hayır | Hayır |
PR_SET_NO_NEW_PRIVS=1 ile çalışır mı | Hayır | Hayır (newuidmap başarısız) | Kısmen | Evet |
unshare(CLONE_NEWUSER) engellendiğinde (EPERM) çalışır mı | Geçerli değil | Hayır | Buildah: Hayır / Kaniko: Evet | Evet |
/dev/fuse olmadan çalışır mı | Evet (çekirdek overlay2 kullanır) | Yalnızca yavaş vfs kopyası ile | Evet | Evet (ext4lite üzerinde overlayfs) |
docker build (BuildKit) destekler mi | Evet | Evet (userns izin verilirse) | Yalnızca imaj oluşturma (çalışma zamanı yok) | Evet |
docker run ve docker compose up destekler mi | Evet | Evet (userns izin verilirse) | Hayır | Evet |
| Linux VM olmadan Windows ve macOS üzerinde çalışır mı | 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 ilkeline dayanır:
- Başlatma sırasında kendi alt iş parçacığında bir kez
ptrace(PTRACE_ATTACH):systrap, başlangıçta yerel bir stub yardımcı iş parçacığı oluşturur, paylaşılan bellek bağlamını başlatmak için buna bağlanır ve ardından ayrılır. Ana makinekernel.yama.ptrace_scope = 3ayarını yaparsa (bu, sistem genelinde tümptraceişlemlerini devre dışı bırakır) veya dış seccomp filtresindeptraceçağrısını engellerse,systrapbaşlatması tamamlanamaz. (Ubuntu ve Debian'da varsayılan olanyama.ptrace_scope = 1ayarında ebeveynden alt sürece 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 da, iç içe bir sandbox içindeEBUSYdöndürdüğünde de çalışır.mmap(..., PROT_EXEC, ...): Konuk ELF segmentlerini vesystrappaylaşılan bellek trambolinini eşlemek için kullanılır.
Uçtan Uca Örnek: Root Olmadan Çok Konteynerli Bir Uygulamayı Derleme ve Test Etme
Aşağıdaki betik, ayrıcalıksız bir kullanıcı oturumu içinde 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# İmajı ext4lite üzerindeki overlayfs kullanarak derleyin
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 Bir Ayrıcalıksız Süreçte Linux Konteynerlerini, Docker'ı ve Kubernetes'i Ç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'u Root veya Kullanıcı Ad Alanı Olmadan Çalıştırma (bu yazı)
- gvx ile gVisor ve İç İçe Sandbox'lar İçinde 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ı için Hızlı İzole Docker Ortamları: 100 milisaniyelik Copy-on-Write
.ext4birim sıfırlamalarıyla paralelSWE-benchve RL rollout ortamlarının ölçeklendirilmesi.