---
id: e62d78ef5850c982dbddc9d3ff9134ae
author: Lemon Mint
title: 'gvx: Menjalankan Linux Containers, Docker, dan Kubernetes dalam Satu Unprivileged Process'
description: Ikhtisar teknis gvx, sebuah runtime kontainer dan Go SDK lintas platform yang diperkuat keamanannya, dibangun di atas kernel ruang pengguna gVisor yang secara aman menjalankan kontainer Linux, Docker-in-Docker, dan Kubernetes HA multi-node dalam satu proses tanpa hak istimewa (unprivileged) di Windows, macOS, dan Linux.
language: id
date: 2026-11-06T12:02:56.008516536Z
path: /blog/posts/gvx-cross-platform-linux-containers-z48916d01
go_package: z.gfire.dev/gvx
go_repourl: https://github.com/gfire-sigs/gvx.git
category: lowlevel
---

## Pendahuluan: Kontainer Berkeamanan Tinggi Tanpa Root atau Host Daemon

Menjalankan kontainer Linux, `docker build`, atau Kubernetes di dalam mesin pengembangan, runner CI, atau node cloud multi-tenant biasanya memaksa adanya kompromi keamanan (trade-off) yang tidak nyaman:

- Pada **Linux**, runtime OCI standar (`runc`, `crun`, `runsc`) memerlukan salah satu dari hak istimewa `root`, pengungkapan `/var/run/docker.sock` pada host, `--privileged` (`CAP_SYS_ADMIN`), atau user namespace (`unshare(CLONE_NEWUSER)`) yang memperluas permukaan serangan kernel host.
- Pada **Windows** dan **macOS**, mesin kontainer (`Docker Desktop`, `Podman Machine`, `Lima`, `OrbStack`) menjalankan kernel mesin virtual Linux lengkap di dalam WSL2, Hyper-V, atau `Virtualization.framework` dan menjalankan daemon latar belakang yang persisten di dalam VM tersebut.

**[gvx](https://github.com/gfire-sigs/gvx)** (CLI `rungv` dan SDK Go `z.gfire.dev/gvx/pkg/gvx`) menyediakan **alternatif yang aman dan tanpa hak istimewa**. Dibangun sebagai fork yang dapat dilacak dari upstream **gVisor** milik Google, yaitu kernel Linux ruang pengguna (`Sentry`) dan tumpukan jaringan ruang pengguna (`netstack`), `gvx` menjalankan binari ELF64 `linux/amd64` dan `linux/arm64` yang tidak dimodifikasi serta kontainer OCI secara langsung di dalam **satu proses host tanpa hak istimewa yang mengunci dirinya sendiri** pada Windows, macOS, dan Linux.

> **Jaminan Keamanan (Pertahanan Mendalam Tiga Lapis)**: `gvx` tidak pernah melemahkan batas keamanan OS host, tidak pernah memasang driver kernel, dan tidak pernah memerlukan `root`, `sudo`, `--privileged` pada host, atau `CLONE_NEWUSER`. Sebelum mengeksekusi satu instruksi tamu pun, `gvx` mengunci proses host-nya sendiri menggunakan Windows Restricted Tokens dan Job Objects, macOS Seatbelt (`deny default`), atau Linux `PR_SET_NO_NEW_PRIVS` + BPF `seccomp`. Semua system call tamu, hak istimewa `UID 0` virtual, mount (`VFS2`), dan tabel jaringan (`netstack`) dibatasi secara ketat di dalam kernel Go `Sentry` yang aman terhadap memori.

| Runtime                    | Host OS                                               |        Cold Start | Memory Footprint | Admin atau `sudo` Diperlukan | Background VM Daemon | Direct OCI Image Run |
| :------------------------- | :---------------------------------------------------- | ----------------: | ---------------: | :--------------------------- | :------------------- | :------------------- |
| **`gvx` (`whpx` / `hvf`)** | Windows (`amd64`, `arm64`) dan macOS (`arm64`)        |          `~20 ms` |        `~30 MiB` | Tidak                        | Tidak                | Ya                   |
| **`gvx` (`systrap`)**      | Windows (`amd64`, `arm64`) dan Linux (`amd64`, `arm64`) |    `~25 hingga 65 ms` |        `~31 MiB` | Tidak                        | Tidak                | Ya                   |
| **WSL2 / Docker Desktop**  | Windows dan macOS                                     |  `800 hingga 2500 ms` |      `> 512 MiB` | Ya (Pengaturan Awal)         | Ya                   | Memerlukan Daemon    |
| **QEMU (Full System)**     | Windows dan macOS                                     | `1500 hingga 4000 ms` |      `> 256 MiB` | Tidak                        | Tidak                | Memerlukan Disk Image |

Tidak ada kernel VM Linux yang di-boot di Windows atau macOS. Tidak ada daemon latar belakang yang berjalan di host. Tidak ada hak istimewa `root`, `sudo`, user namespace (`CLONE_NEWUSER`), `mount(2)`, driver `TUN`/`TAP`, atau `CAP_NET_ADMIN` yang diperlukan pada OS host. Di dalam proses tanpa hak istimewa tersebut, `gvx` menjalankan **Docker-in-Docker (`docker:dind`)**, `docker build`, `docker compose`, dan **Kubernetes High-Availability multi-node (`k3s` dengan `etcd` tertanam dan CNI `Calico`)**.

---

## Siklus Hidup Kontainer dan Penguncian Host Tiga Lapis

Setiap sandbox `gvx` berjalan di dalam satu proses host tanpa hak istimewa dan menerapkan siklus hidup tiga fase: pra-membuka semua deskriptor file dan soket host yang diperlukan, mengunci proses OS host melalui `pkg/hostlockdown`, dan memasuki loop eksekusi `Sentry` di dalam proses.

![Siklus Hidup Kontainer gvx dan Penguncian Mandiri Host](/assets/images/gvx/gvx-lifecycle-lockdown.png)

Sebelum menyerahkan kendali ke instruksi tamu pertama, `gvx` pra-membuka deskriptor layer image `.erofs` yang di-cache, deskriptor file volume `.ext4`, handle `*os.Root` untuk `/workspace`, dan soket jaringan host, kemudian memanggil `hostlockdown.Apply()`:

1. **Windows NT (`lockdown_windows.go`)**: Memanggil `AdjustTokenPrivileges` dengan `SE_PRIVILEGE_REMOVED` untuk menghapus hak istimewa secara langsung (in-place), mengikat token impersonasi terbatas `DISABLE_MAX_PRIVILEGE` pada integritas Low (`S-1-16-4096`), menetapkan proses ke Job Object anonim dengan `JOB_OBJECT_LIMIT_ACTIVE_PROCESS = 1` (memblokir pembuatan proses anak), dan mengaktifkan `DisallowWin32kSystemCalls = 1` melalui `SetProcessMitigationPolicy`.
2. **macOS XNU (`lockdown_darwin.go`)**: Menetapkan `RLIMIT_NPROC = 0` dan menerapkan profil Seatbelt (`sandbox_init_with_parameters`) yang dimulai dari `(version 1)(deny default)` dan memblokir `process-fork`, `process-exec*`, serta semua pembukaan file host baru.
3. **Linux (`lockdown_linux.go` + `pkg/gvx/syscallfilter_linux.go`)**: Menetapkan `PR_SET_NO_NEW_PRIVS` dan memasang allowlist BPF `seccomp` milik Sentry di seluruh thread (`SECCOMP_FILTER_FLAG_TSYNC`) dengan aturan `EPERM` eksplisit untuk `execve`, `execveat`, `clone`, `openat`, dan `socket`.

---

## Intersepsi System Call Lintas Platform dan Paging 4 KB (`pkg/sentry/platform`)

Binari ELF64 Linux mengasumsikan granularitas halaman memori 4 KB (`0x1000`) untuk pemetaan segmen `mmap(MAP_FIXED)`. Namun, `VirtualAlloc` dan `MapViewOfFile3` pada Windows menerapkan alignment 64 KB (`0x10000`), dan Apple Silicon macOS (`darwin/arm64`) menggunakan halaman host 16 KB (`0x4000`). Selain itu, setiap OS memerlukan mekanisme yang berbeda untuk mencegat instruksi Linux `SYSCALL` (`amd64`) dan `SVC #0` (`arm64`) tanpa mem-boot VM Linux.

`gvx` memecahkan kedua masalah tersebut di empat backend eksekusi yang mengimplementasikan `pkg/sentry/platform.Context`:

![Mekanisme Intersepsi Syscall Platform gvx dan Paging 4KB](/assets/images/gvx/gvx-platform-syscalls.png)

### 1. Mesin Perangkat Keras Windows: `platform/whpx` (`WinHvPlatform.dll`)

Pada `windows/amd64` dan `windows/arm64`, `platform/whpx` membuat partisi hypervisor ringan melalui `WHvCreatePartition` tanpa mem-boot kernel OS tamu:

- **Decoupler Paging 64 KB-ke-4 KB**: `whpx` mendaftarkan setiap arena 64 MiB dari `pgalloc.MemoryFile` ke partisi satu kali melalui `WHvMapGpaRange`. Pemanggilan `MapFile` dan `Unmap` berikutnya hanya memodifikasi tabel halaman tamu di dalam partisi, sehingga menerapkan izin `R/W/X` 4 KB yang tepat meskipun Windows menggunakan granularitas alokasi 64 KB.
- **Pertukaran Register Tanpa API melalui `CommPage`**:
  - Pada `amd64`, `SYSCALL` Ring-3 tamu masuk ke stub `MSR_LSTAR` Ring-0 di dalam partisi (`stubgen_x86.go`), yang menyimpan GPR system call jalur cepat (`RAX, RDI, RSI, RDX, R10, R8, R9, RIP, RSP`) ke dalam `CommPage` 4 KB yang dibagikan, lalu mengeksekusi `HLT` untuk keluar dari `WHvRunVirtualProcessor`.
  - Pada `arm64`, `SVC #0` EL0 tamu masuk ke vektor EL1 (`stubgen_a64.go`), menyimpan `X0..X8, SP_EL0, ELR_EL1, PSTATE` ke dalam `CommPage`, dan memuat dari GPA tanpa backing nol untuk memicu memory exit kembali ke Sentry.

### 2. Mesin Perangkat Keras macOS: `platform/hvf` (`Hypervisor.framework`)

Pada Apple Silicon (`darwin/arm64`), `platform/hvf` menjalankan thread kontainer di dalam vCPU `Hypervisor.framework` (`hv_vm_create`, `hv_vcpu_run`):

- **Translasi MMU Dua Tahap 4 KB di atas 16 KB**: Stage-2 (`hv_vm_map`) memetakan potongan memory-file 1 GiB ke ruang Intermediate Physical Address (IPA) satu kali pada granularitas halaman host 16 KB dengan `HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC`. Di dalam vCPU, stub EL1 `bluepill` (`bluepill_arm64.go`) mengonfigurasi `TCR_EL1.TG0 = 0b00` (granule 4 KB) di `TTBR0_EL1` dan mengisi entri tabel halaman Stage-1 4 KB dengan izin `R-X` atau `RW-` (`UXN=1`) yang tepat. Karena MMU ARM64 menerapkan irisan izin Stage-1 dan Stage-2, perangkat keras menjebak fault izin tepat pada batas 4 KB.
- **Trap System Call**: `SVC #0` EL0 tamu men-trap ke `VBAR_EL1` EL1, menyimpan register ke `CommPage` 4 KB yang dibagikan, dan mengeksekusi `HVC #0` untuk kembali dari `hv_vcpu_run` ke thread Go Sentry.

### 3. Fallback Mode Pengguna Windows: `platform/systrap` (`winsystrap`)

Ketika virtualisasi perangkat keras tidak tersedia (misalnya di dalam VM cloud bersarang), `winsystrap` menjalankan kode tamu dalam mode pengguna pada `windows/amd64` dan `windows/arm64`:

- **Isolasi `CR3` / `TTBR0_EL1` Perangkat Keras**: Thread tamu berjalan di dalam subproses stub terisolasi yang di-boot dari executable 1 KB yang dihasilkan (`stubimage_xplat.go`) dan dibatasi oleh token Low-Integrity serta Job Object.
- **Patching Binari di Tempat & IPC `winSysmsg`**: Pada `amd64`, patcher (`patcher_amd64_xplat.go`) mengganti instruksi `syscall` (`0f 05`) 2-byte dengan lompatan `jmp rel32` 5-byte (atau jebakan breakpoint `CC 90` ketika jendela 5-byte tidak tersedia) menuju fast-path island. Pada `arm64`, `svc #0` di-patch dengan cabang `B` ke slot island. Island menyimpan register ke halaman `winSysmsg` yang dibagikan dan disinkronkan dengan Sentry melalui `WaitOnAddress` dan `WakeByAddressSingle`, sementara trap yang tidak di-patch dan page fault berhenti pada Windows Debug Object (`WaitForDebugEventEx`).

### 4. Mesin Mode Pengguna Linux: `platform/systrap`

Pada `linux/amd64` dan `linux/arm64`, `systrap` menjalankan thread tamu (`sysmsg`) yang men-trap system call tamu melalui `SECCOMP_RET_TRAP` (`SIGSYS`) dan melakukan binary-patch pada situs `syscall` ke dalam trampoline memori bersama (`sysmsg`) yang disinkronkan melalui `SYS_FUTEX`, sementara thread stub `syscallThread` (`syscall_thread.go`) mengeksekusi operasi address-space (`mmap`, `munmap`, `clone`) melalui `SECCOMP_RET_USER_NOTIF` (`_RUN_SECCOMP_LOOP`). Ketika `gvx` berjalan di dalam sandbox `gVisor` (`runsc`) luar tempat slot `SECCOMP_FILTER_FLAG_NEW_LISTENER` tunggal mengembalikan `EBUSY`, `gvx` secara otomatis beralih `syscallThread` ke loop futex memori bersama (`_RUN_SYSCALL_LOOP`), sebagaimana dijelaskan secara rinci dalam [Bagian 3 dari seri ini](/blog/posts/docker-in-docker-inside-gvisor-with-gvx-z48916d03).

---

## Cara `gvx` Memetakan System Call Linux Tamu ke Subsistem Virtual dan Handle Host

Setelah mesin platform men-trap instruksi `SYSCALL` (`amd64`) atau `SVC #0` (`arm64`) tamu dan menuliskan register tamu ke halaman bersama 4 KB (`CommPage`, `sysmsg`, atau `winSysmsg`), kontrol kembali ke goroutine task Go `Sentry` (`pkg/sentry/kernel/task_syscall.go`). Alih-alih meneruskan system call Linux ke kernel OS host yang mendasarinya, `Task.doSyscall()` menyimpan status register asli (`SyscallSaveOrig()`), mengevaluasi filter BPF `seccomp` dan henti `ptrace` di dalam tamu jika ada, lalu mengirimkan nomor system call melalui `linux.AMD64` atau `linux.ARM64` (`pkg/sentry/syscalls/linux/linux64.go`, mencakup sekitar 370 system call Linux) ke dalam empat domain internal:

![Bagaimana gvx Memetakan Syscall Linux Tamu ke Subsistem dan OS Host](/assets/images/gvx/gvx-syscall-mapping.png)

| Domain Syscall | System Call Linux Tamu Representatif | Subsistem Internal `gvx` (`pkg/sentry`) | Interaksi Batas OS Host (Setelah `hostlockdown`) |
| :--- | :--- | :--- | :--- |
| **A. Proses, Namespace, Mount & Sinkronisasi** | `clone`, `execve`, `unshare`, `setns`, `mount`, `umount2`, `pivot_root`, `setuid`, `capset`, `futex`, `epoll_wait`, `pipe2` | `kernel.Task`, kredensial virtual, tabel futex, dan `VFS2` dalam memori (`procfs`, `sysfs`, `cgroupfs` v2, `tmpfs`, `overlayfs`) | **Nol system call host** (100% state Go dalam memori; sepenuhnya tidak terlihat oleh OS host) |
| **B. Memori Virtual (`MM`)** | `mmap`, `munmap`, `mremap`, `mprotect`, `brk`, `madvise`, `memfd_create` | `mm.MemoryManager` (pohon VMA 4 KB) dan `pgalloc.MemoryFile` | Pembaruan tabel halaman 4 KB dua arah melalui `WHvMapGpaRange`, `hv_vm_map` + `TTBR0_EL1`, atau `mmap`/`mprotect` stub |
| **C. File & Penyimpanan (`VFS2`)** | `openat`, `pread64`, `pwrite64`, `getdents64`, `statx`, `renameat2`, `setxattr`, `mknod`, `inotify_add_watch` | Router tabel mount `vfs.VirtualFilesystem` (`fsimpl/erofs`, `fsimpl/ext4lite`, `fsimpl/hostfs` v2) | `pread`/`pwrite` dua arah pada 1 FD `.erofs` yang di-pin atau 1 FD `.ext4`, atau penelusuran relatif terbatas pada `*os.Root` |
| **D. Jaringan & Netfilter** | `socket`, `bind`, `listen`, `connect`, `sendmsg`, `recvmsg`, `netlink`, `setsockopt(IPT_SO_SET_REPLACE)` | `pkg/tcpip` ruang pengguna (`lo`, `eth0`, `docker0`, `veth`, `vxlan`, `wireguard`, `ipset`, `iptables-legacy`) | Lalu lintas intra-sandbox menggunakan **nol system call host**; lalu lintas eksternal dipetakan ke `net.Dial`/`net.Listen` (`-net=nat`) atau 1 soket UDP (`-net=wg`) |

Ketika handler mengembalikan `(rval, ctrl, err)`, `Task.doSyscallInvoke()` mengonversi error apa pun menjadi `errno` Linux negatif (`-ExtractErrno(err, sysno)`), menuliskan nilai kembali ke halaman register bersama (`RAX` pada `amd64`, `X0` pada `arm64`), dan melanjutkan eksekusi tamu.

---

## Penyimpanan (`VFS2`) dan Jaringan Ruang Pengguna Dua Jalur (`netstack`)

Semua operasi file dan jaringan tamu dilayani di dalam Go `Sentry` melalui tiga filesystem `VFS2` dan dua jalur `pkg/netbackend`:

![Mesin Penyimpanan VFS2 gvx dan Netstack Dua Jalur](/assets/images/gvx/gvx-storage-netstack.png)

| Mesin Penyimpanan      | Peran Mount di `gvx`                              | Sumber Daya Host Pendukung             | Panggilan Host `openat` / `NtCreateFile` saat Runtime | Pemindaian Per-File Windows Defender (`WdFilter.sys`) |
| :--------------------- | :----------------------------------------------- | :------------------------------------- | ----------------------------------------------------: | ----------------------------------------------------: |
| **`fsimpl/erofs`**     | Lapisan bawah image OCI hanya-baca               | Satu file `<sha256>.erofs` per layer   |                                                  `0` |                                                   `0` |
| **`fsimpl/ext4lite`**  | Volume bernama (`-v name:/path`)                 | Satu file `<name>.ext4` per volume     |                                                  `0` |                                                   `0` |
| **`fsimpl/hostfs` v2** | Workspace host (`-workspace`, `-v /host:/guest`) | Direktori host `*os.Root` yang di-pin  |                         `O(depth)` per open yang tidak di-cache |                                    `1` per penutupan file host |

### Mengapa `ext4lite` Penting untuk Docker, Basis Data, dan Package Manager

Mengekstrak atau menulis puluhan ribu file kontainer langsung ke NTFS Windows atau APFS macOS memicu pemindaian minifilter antivirus (`WdFilter.sys`), tabrakan sensitivitas huruf besar-kecil, dan hilangnya atribut extended POSIX.

`pkg/sentry/fsimpl/ext4lite` mengimplementasikan filesystem `ext4` murni Go di dalam satu file host yang telah dibuka sebelumnya (`%LOCALAPPDATA%\gvx\cache\volumes\<name>.ext4` pada Windows, `~/Library/Caches/gvx/volumes/<name>.ext4` pada macOS, atau `~/.cache/gvx/volumes/<name>.ext4` pada Linux) dengan:

- **Blok 4 KiB dan grup blok dinamis 16 MiB (`meta_bg`)**: Tumbuh secara dinamis tanpa hambatan alokasi file sparse (`fallocate` pada Linux, `fcntl(F_PREALLOCATE)` pada macOS, `FileAllocationInfo` pada Windows) dan memadatkan grup trailing yang tidak terpakai saat unmount bersih.
- **Jurnal mode terurut JBD2 (inode 8)**: Commit transaksi atomik dengan checksum CRC-32 dan blok revoke, serta pemulihan `fsckLite`.
- **Dukungan upper-layer `overlayfs`**: Mengimplementasikan atribut extended `trusted.overlay.*` dan `security.capability`, whiteout perangkat karakter (`0:0`), pelaporan entri direktori `d_type`, dan `RENAME_EXCHANGE`.

---

## Beban Kerja Praktis: Docker Engine, Kubernetes (`k3s` + `Calico`), dan SDK Go

### Instalasi `rungv`: Rilis Prebuilt Ter-attest SLSA atau `go install`

Anda dapat mengunduh arsip `rungv` prebuilt untuk `linux/amd64`, `linux/arm64`, `darwin/arm64`, `windows/amd64`, atau `windows/arm64` dari [GitHub Releases](https://github.com/gfire-sigs/gvx/releases) (masing-masing dibangun oleh pipeline rilis SLSA dengan bundle provenance Sigstore dan `SHA256SUMS`), atau menginstal langsung dari sumber dengan `go install`:

```sh
# Opsi A: Unduh rilis prebuilt dan verifikasi provenance build SLSA
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
shasum -a 256 -c SHA256SUMS --ignore-missing
tar -xzf rungv-v0.2.0-linux-amd64.tar.gz

# Opsi B: Instal langsung melalui Go (Linux / Windows)
CGO_ENABLED=0 go install z.gfire.dev/gvx/cmd/rungv@latest
```

> Pada macOS (`darwin/arm64`), arsip rilis prebuilt sudah ditandatangani dengan entitlement `com.apple.security.hypervisor` (`xattr -d com.apple.quarantine rungv` menghapus karantina browser). Jika Anda membangun secara lokal dengan `go install` atau `go build` pada macOS, tandatangani binari dengan `codesign --sign - --entitlements entitlements.plist --force $(which rungv)`.

### 1. Menjalankan Docker Engine Tanpa Hak Istimewa (`docker:dind`)

Mengikuti [`docs/docker-engine.md`](https://github.com/gfire-sigs/gvx/blob/main/docs/docker-engine.md), Anda dapat menjalankan kontainer `docker:dind` yang tidak dimodifikasi di dalam `rungv` pada Windows, macOS, atau Linux dan mengendalikannya dengan CLI `docker` host Anda:

```sh
# 1. Buat direktori host untuk soket Unix yang diteruskan
mkdir -p ~/.gvx

# 2. Jalankan docker:dind di dalam sandbox gvx dengan volume ext4lite
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
```

Di terminal kedua, arahkan CLI `docker` host Anda ke soket sandbox:

```sh
docker context create gvx --docker host=unix://$HOME/.gvx/docker.sock
docker context use gvx

docker info --format '{{.Driver}} {{.OperatingSystem}}'
# Keluaran: overlayfs Alpine Linux ... (containerized)

docker build -t myapp ./app
docker compose up -d
```

### 2. Menjalankan Kubernetes (`k3s` + `Calico`) di Sandbox Tanpa Hak Istimewa

Karena `gvx` mengimplementasikan `/dev/kmsg`, `cgroup` v2 (OOM killer `memory.max` dan throttling bandwidth `cpu.max`), `/proc/diskstats`, perangkat netlink `wireguard` dan `vxlan`, `ipset`, serta `iptables-legacy` (`addrtype`, `conntrack`, `statistic`, `recent`), image `rancher/k3s` yang tidak dimodifikasi mencapai `Ready` di dalam satu proses `rungv`:

```sh
mkdir -p ~/.gvx/k3s

rungv run \
  -e IPTABLES_MODE=legacy \
  -p 127.0.0.1:6443:6443 \
  -p 127.0.0.1:30000-30019:30000-30019 \
  -v k3s:/var/lib/rancher \
  --mount type=bind,src=$HOME/.gvx/k3s,dst=/output \
  rancher/k3s:v1.31.4-k3s1 server \
  --disable=traefik,servicelb \
  --write-kubeconfig=/output/kubeconfig.yaml \
  --write-kubeconfig-mode=644
```

Anda juga dapat menggabungkan beberapa node `gvx` melalui WireGuard (`flannel-backend=wireguard-native` atau mesh `wg0`) dengan high availability `etcd` tertanam, atau menjalankan **Calico** (`calico-vxlan.yaml` dengan `FELIX_IPTABLESBACKEND=Legacy`) untuk menegakkan Kubernetes `NetworkPolicy` sepenuhnya di dalam ruang pengguna.

### 3. Menyematkan Kontainer Linux di Go melalui `z.gfire.dev/gvx/pkg/gvx`

Aplikasi Go dapat menyematkan kontainer Linux secara langsung tanpa daemon kontainer eksternal:

```go
package main

import (
	"context"
	"fmt"
	"os"

	"z.gfire.dev/gvx/pkg/gvx"
)

func main() {
	ctx := context.Background()
	sb, err := gvx.New(ctx, gvx.Config{
		Platform:      gvx.PlatformAuto,
		NetworkMode:   gvx.NetModeNAT,
		OCIImage:      "alpine:3.20",
		WorkspacePath: "./repo",
		Argv:          []string{"/usr/bin/git", "status"},
		Stdout:        os.Stdout,
		Stderr:        os.Stderr,
	})
	if err != nil {
		fmt.Fprintf(os.Stderr, "init sandbox: %v\n", err)
		os.Exit(1)
	}
	defer sb.Close()

	exitCode, err := sb.Run(ctx)
	if err != nil {
		fmt.Fprintf(os.Stderr, "run sandbox: %v\n", err)
		os.Exit(1)
	}
	os.Exit(exitCode)
}
```

---

## Bacaan Lanjutan dalam Seri Ini

1. **[gvx: Menjalankan Kontainer Linux, Docker, dan Kubernetes dalam Satu Proses Tanpa Hak Istimewa](/blog/posts/gvx-cross-platform-linux-containers-z48916d01)** (postingan ini)
2. **[Menjalankan Docker, docker build, dan docker compose Tanpa Root atau User Namespace](/blog/posts/run-docker-without-root-or-userns-gvx-z48916d02)**: Cara melakukan bootstrap `docker:dind` di dalam sandbox yang terkunci ketat, tempat `sudo`, `unshare(CLONE_NEWUSER)`, `mount(2)`, dan `/dev/fuse` diblokir.
3. **[Menjalankan Docker-in-Docker di Dalam gVisor dan Sandbox Bersarang dengan gvx](/blog/posts/docker-in-docker-inside-gvisor-with-gvx-z48916d03)**: Mengapa `apt-get install docker.io` dan `runsc` bersarang gagal di dalam `gVisor` melintasi lima penghalang kernel, dan bagaimana `gvx` menjalankan `docker:dind` bersarang menggunakan loop futex memori bersama.
4. **[Lingkungan Docker Terisolasi yang Cepat untuk Rollout RL Agen AI dengan gvx](/blog/posts/fast-docker-environments-for-agent-rl-rollouts-z48916d04)**: Menskalakan `SWE-bench` dan rollout reinforcement learning agen dengan ratusan instans `docker:dind` tanpa hak istimewa yang berjalan paralel, serta reset volume `.ext4` copy-on-write dalam 100 milidetik.
