---
id: 40e9d44f33fa847eb498f09bac5bf144
author: Lemon Mint
title: Kök Yetkisi veya Kullanıcı Ad Alanları Olmadan Docker, docker build ve docker compose Çalıştırma
description: Root, sudo, unshare(CLONE_NEWUSER), mount(2) ve /dev/fuse engellendiğinde, tam bir Docker Engine'in (dockerd, BuildKit, overlayfs ve docker compose dahil) yalıtılmış bir gVisor kullanıcı alanı sandbox ortamında, ayrıcalıksız bir kullanıcı olarak güvenli biçimde nasıl çalıştırılacağı.
language: tr
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
---

## 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](https://github.com/gfire-sigs/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**.

> **`gvx` Neden Tasarım Gereği Güvenlidir (Ayrıcalık Yükseltme Geçici Çözümü Değildir)**: Ana makinenin `/var/run/docker.sock` soketini bağlamanın ya da `docker run --privileged` komutunu çalıştırmanın (bunlar ana makine çekirdeği üzerinde root eşdeğeri denetim sağlar) aksine, `gvx` herhangi 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 yerine `rungv`, kendi ana makine sürecini kilitler (`PR_SET_NO_NEW_PRIVS` + katı BPF `seccomp` izin listesi) ve `dockerd`'yi Google'ın bellek güvenli **gVisor (`Sentry`)** kullanıcı alanı çekirdeğinin içinde çalıştırır. Tüm konuk `UID 0` yetenekleri, `overlayfs` bağlamaları (`ext4lite`) ve `iptables` kuralları sandbox sürecinin içinde sıkı biçimde yalıtılmış kalır.

```sh
# 1. rungv'yi kullanıcı alanına kurun (önceden derlenmiş, SLSA ile doğrulanmış sürüm veya go install)
# Seçenek A: GitHub Releases üzerinden SLSA ile doğrulanmış önceden derlenmiş ikili dosyayı doğrulayın ve çıkarın
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

# Seçenek B: Veya Go ile doğrudan kaynak koddan kurun
CGO_ENABLED=0 GOBIN=~/.local/bin go install z.gfire.dev/gvx/cmd/rungv@latest

# 2. docker:dind'i tek dosyalık bir ext4lite birimiyle gvx içinde başlatın
#    ~/.gvx/docker.sock (mod 0600) soketini konuk 2375 portuna iletir
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. Standart Docker CLI ve Docker Compose'u kullanıcı alanı soketine yönlendirin
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}}'
# Çıktı: overlayfs Alpine Linux ... (konteynerleştirilmiş)

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

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

```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. 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)` veya `clone(CLONE_NEWUSER)` çağrısını engellerse.
- Ubuntu 24.04 ve üzeri `kernel.apparmor_restrict_unprivileged_userns = 1` ayarını etkinleştirirse.
- Debian veya RHEL düğümleri `kernel.unprivileged_userns_clone = 0` veya `user.max_user_namespaces = 0` ayarlarını uygularsa.
- `PR_SET_NO_NEW_PRIVS` etkin olduğu için `newuidmap`, `/proc/self/uid_map` dosyasına yazamazsa.

Ortaya çıkan hatalar şu şekildedir:

```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. 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:

```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. 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:

```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
```

---

## `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.

![gvx ile ayrıcalıksız Docker-in-Docker çalıştırma](/assets/images/gvx/gvx-unprivileged-dind.png)

### 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)` ve `mount(2)`, `rungv` ana makine süreci sizin ayrıcalıksız ana makine UID'nizde çalışırken Sentry'nin bellek içi görev hiyerarşisi ve `VFS2` bağlama tablosu (`procfs`, `sysfs`, `tmpfs`, `devpts`, `cgroupfs` v2) ü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`, `docker0` köprüsünü (`172.17.0.1/16`) oluşturur, iç içe konteynerler için sanal `veth` çiftlerini ekler ve `NAT` (`DOCKER`, `POSTROUTING`) ile `FILTER` zincirlerini, `gvx`'in kullanıcı alanı `netstack` yığını içinde `addrtype` ve `conntrack` eşleşmeleriyle programlar.
- `-p unix:~/.gvx/docker.sock:2375` parametresini geçmek, ana makinede bir Unix alan soketi (mod `0600`) bağlar ve bağlantıları doğrudan sandbox içindeki `dockerd`'nin `2375` portuna 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:

1. **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 makine `kernel.yama.ptrace_scope = 3` ayarını yaparsa (bu, sistem genelinde tüm `ptrace` işlemlerini devre dışı bırakır) veya dış seccomp filtresinde `ptrace` çağrısını engellerse, `systrap` başlatması tamamlanamaz. (Ubuntu ve Debian'da varsayılan olan `yama.ptrace_scope = 1` ayarında ebeveynden alt sürece izlemeye izin verildiği için `gvx` başarılı olur.)
2. **`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](/blog/posts/docker-in-docker-inside-gvisor-with-gvx-z48916d03) ele alındığı gibi, `gvx`, `SECCOMP_FILTER_FLAG_NEW_LISTENER` kullanılabilir olduğunda da, iç içe bir sandbox içinde `EBUSY` döndürdüğünde de çalışır.
3. **`mmap(..., PROT_EXEC, ...)`**: Konuk ELF segmentlerini ve `systrap` paylaşı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:

```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

# İmajı ext4lite üzerindeki overlayfs kullanarak derleyin
docker build -t demo-ping:latest .

# Bir köprü ağı oluşturun, Redis'i başlatın ve konteynerler arasındaki bağlantıyı doğrulayın
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
# Çıktı: PONG

# İş yükü konteynerlerini temizleyin ve sandbox'ı durdurun
docker rm -f cache
docker network rm demo-net
kill -INT $DIND_PID
```

---

## Bu Serideki Diğer Okumalar

1. **[gvx: Tek Bir Ayrıcalıksız Süreçte Linux Konteynerlerini, Docker'ı ve Kubernetes'i Çalıştırma](/blog/posts/gvx-cross-platform-linux-containers-z48916d01)**: `gvx`'in mimari genel bakışı, çapraz platform yürütme motorları (`whpx`, `hvf`, `systrap`), `VFS2` (`erofs`, `ext4lite`, `hostfs` v2) ve `netstack`.
2. **[Docker, docker build ve docker compose'u Root veya Kullanıcı Ad Alanı Olmadan Çalıştırma](/blog/posts/run-docker-without-root-or-userns-gvx-z48916d02)** (bu yazı)
3. **[gvx ile gVisor ve İç İçe Sandbox'lar İçinde Docker-in-Docker Çalıştırma](/blog/posts/docker-in-docker-inside-gvisor-with-gvx-z48916d03)**: `gvx`'in `modprobe`, `iptables-nft`, `gofer` üzerinde `overlay2` ve `gVisor` (`runsc`) içinde iç içe `SECCOMP_FILTER_FLAG_NEW_LISTENER` (`EBUSY`) sorunlarını nasıl çözdüğü.
4. **[gvx ile AI Ajanı RL Rollout'ları için Hızlı İzole Docker Ortamları](/blog/posts/fast-docker-environments-for-agent-rl-rollouts-z48916d04)**: 100 milisaniyelik Copy-on-Write `.ext4` birim sıfırlamalarıyla paralel `SWE-bench` ve RL rollout ortamlarının ölçeklendirilmesi.
