---
id: e62d78ef5850c982dbddc9d3ff9134ae
author: Lemon Mint
title: 'gvx: Rularea containerelor Linux, Docker și Kubernetes într-un singur proces neprivilegiat'
description: Prezentare tehnică a gvx, un container runtime și un SDK Go cross-platform, cu securitate întărită, construit pe kernel-ul user-space gVisor, care rulează în siguranță containere Linux, Docker-in-Docker și clustere Kubernetes multi-nod cu HA, într-un singur proces fără privilegii, pe Windows, macOS și Linux.
language: ro
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
---

## Introducere: containere securizate fără root sau daemoni pe gazdă

Rularea containerelor Linux, a comenzii `docker build` sau a Kubernetes pe o mașină de dezvoltare, un runner CI sau un nod cloud multi-tenant impune, de regulă, un compromis incomod în materie de securitate:

- Pe **Linux**, runtime-urile OCI standard (`runc`, `crun`, `runsc`) necesită fie privilegii `root`, fie expunerea `/var/run/docker.sock` al gazdei, fie `--privileged` (`CAP_SYS_ADMIN`), fie namespace-uri de utilizator (`unshare(CLONE_NEWUSER)`), care extind suprafața de atac a kernel-ului gazdei.
- Pe **Windows** și **macOS**, motoarele de containere (`Docker Desktop`, `Podman Machine`, `Lima`, `OrbStack`) pornesc un kernel complet de mașină virtuală Linux în WSL2, Hyper-V sau `Virtualization.framework` și rulează un daemon persistent în fundal în interiorul acestei VM.

**[gvx](https://github.com/gfire-sigs/gvx)** (CLI-ul `rungv` și SDK-ul Go `z.gfire.dev/gvx/pkg/gvx`) oferă o **alternativă sigură, fără privilegii**. Construit ca un fork, ce poate fi urmărit în amonte, al kernel-ului Linux în user-space `Sentry` și al stivei de rețea în user-space `netstack` ale proiectului gVisor al Google, `gvx` execută binare `linux/amd64` și `linux/arm64` ELF64 nemodificate, precum și containere OCI, direct în interiorul **unui singur proces gazdă neprivilegiat, cu auto-blocare**, pe Windows, macOS și Linux.

> **Garanție de securitate (apărare în profunzime cu trei inele)**: `gvx` nu slăbește niciodată granițele de securitate ale sistemului de operare gazdă, nu instalează niciodată drivere de kernel și nu necesită niciodată `root`, `sudo`, `--privileged` pe gazdă sau `CLONE_NEWUSER`. Înainte de a executa vreo instrucțiune a oaspetelui, `gvx` își blochează propriul proces gazdă folosind Windows Restricted Tokens și Job Objects, macOS Seatbelt (`deny default`) sau Linux `PR_SET_NO_NEW_PRIVS` + BPF `seccomp`. Toate apelurile de sistem ale oaspetelui, privilegiile virtuale `UID 0`, montările (`VFS2`) și tabelele de rețea (`netstack`) sunt strict confinate în interiorul kernel-ului Go `Sentry`, sigur din punct de vedere al memoriei.

| Runtime                    | Sistem de operare gazdă                               |   Pornire la rece | Amprentă de memorie | Necesită admin sau `sudo` | Daemon VM în fundal | Rulare directă a imaginii OCI |
| :------------------------- | :---------------------------------------------------- | ----------------: | ------------------: | :------------------------ | :------------------ | :---------------------------- |
| **`gvx` (`whpx` / `hvf`)** | Windows (`amd64`, `arm64`) și macOS (`arm64`)         |          `~20 ms` |           `~30 MiB` | Nu                        | Nu                  | Da                            |
| **`gvx` (`systrap`)**      | Windows (`amd64`, `arm64`) și Linux (`amd64`, `arm64`) |   `~25 până la 65 ms` |           `~31 MiB` | Nu                        | Nu                  | Da                            |
| **WSL2 / Docker Desktop**  | Windows și macOS                                      | `800 până la 2500 ms` |         `> 512 MiB` | Da (configurare inițială) | Da                  | Necesită daemon               |
| **QEMU (sistem complet)**  | Windows și macOS                                      | `1500 până la 4000 ms` |        `> 256 MiB` | Nu                        | Nu                  | Necesită imagine de disc      |

Pe Windows sau macOS nu pornește niciun kernel de mașină virtuală Linux. Pe gazdă nu rulează niciun daemon în fundal. Pe sistemul de operare gazdă nu sunt necesare privilegii `root`, `sudo`, namespace-uri de utilizator (`CLONE_NEWUSER`), `mount(2)`, drivere `TUN`/`TAP` sau `CAP_NET_ADMIN`. În interiorul acestui proces neprivilegiat, `gvx` rulează **Docker-in-Docker (`docker:dind`)**, `docker build`, `docker compose` și **Kubernetes de înaltă disponibilitate, multi-nod (`k3s` cu `etcd` încorporat și CNI `Calico`)**.

---

## Ciclul de viață al containerului și izolarea gazdei în trei inele

Fiecare sandbox `gvx` rulează într-un singur proces gazdă neprivilegiat și aplică un ciclu de viață în trei faze: deschiderea anticipată a tuturor descriptorilor de fișiere și a socket-urilor gazdei necesare, blocarea procesului sistemului de operare gazdă prin `pkg/hostlockdown` și intrarea în bucla de execuție `Sentry` din proces.

![Ciclul de viață al containerului gvx și auto-blocarea gazdei](/assets/images/gvx/gvx-lifecycle-lockdown.png)

Înainte de a transfera controlul către prima instrucțiune a oaspetelui, `gvx` deschide anticipat descriptorii de fișiere ai straturilor de imagine `.erofs` din cache, descriptorii de fișiere ai volumelor `.ext4`, handle-ul `*os.Root` pentru `/workspace` și socket-urile de rețea ale gazdei, după care invocă `hostlockdown.Apply()`:

1. **Windows NT (`lockdown_windows.go`)**: Apelează `AdjustTokenPrivileges` cu `SE_PRIVILEGE_REMOVED` pentru a elimina privilegiile în loc, leagă un token de impersonare restricționat `DISABLE_MAX_PRIVILEGE` la integritate Low (`S-1-16-4096`), atribuie procesul unui Job Object anonim cu `JOB_OBJECT_LIMIT_ACTIVE_PROCESS = 1` (care blochează crearea oricărui proces copil) și activează `DisallowWin32kSystemCalls = 1` prin `SetProcessMitigationPolicy`.
2. **macOS XNU (`lockdown_darwin.go`)**: Setează `RLIMIT_NPROC = 0` și aplică un profil Seatbelt (`sandbox_init_with_parameters`) pornind de la `(version 1)(deny default)`, care blochează `process-fork`, `process-exec*` și toate deschiderile de fișiere noi ale gazdei.
3. **Linux (`lockdown_linux.go` + `pkg/gvx/syscallfilter_linux.go`)**: Setează `PR_SET_NO_NEW_PRIVS` și instalează lista de permisiuni BPF `seccomp` a Sentry pe toate firele de execuție (`SECCOMP_FILTER_FLAG_TSYNC`), cu reguli `EPERM` explicite pentru `execve`, `execveat`, `clone`, `openat` și `socket`.

---

## Interceptarea apelurilor de sistem multiplatformă și paginarea de 4 KB (`pkg/sentry/platform`)

Binarele Linux ELF64 presupun o granularitate a paginilor de memorie de 4 KB (`0x1000`) pentru mapările segmentelor `mmap(MAP_FIXED)`. Totuși, `VirtualAlloc` și `MapViewOfFile3` din Windows impun alinierea la 64 KB (`0x10000`), iar macOS pe Apple Silicon (`darwin/arm64`) folosește pagini gazdă de 16 KB (`0x4000`). În plus, fiecare sistem de operare necesită un alt mecanism pentru a intercepta instrucțiunile Linux `SYSCALL` (`amd64`) și `SVC #0` (`arm64`), fără a porni o mașină virtuală Linux.

`gvx` rezolvă ambele probleme prin patru backend-uri de execuție care implementează `pkg/sentry/platform.Context`:

![Mecanismele gvx de interceptare a apelurilor de sistem și de paginare de 4 KB](/assets/images/gvx/gvx-platform-syscalls.png)

### 1. Motorul hardware Windows: `platform/whpx` (`WinHvPlatform.dll`)

Pe `windows/amd64` și `windows/arm64`, `platform/whpx` creează o partiție hipervizor ușoară prin `WHvCreatePartition`, fără a porni kernelul unui sistem de operare oaspete:

- **Decuplorul de paginare 64 KB-4 KB**: `whpx` înregistrează fiecare arenă de 64 MiB din `pgalloc.MemoryFile` la partiție o singură dată, prin `WHvMapGpaRange`. Apelurile ulterioare `MapFile` și `Unmap` modifică doar tabelele de pagini ale oaspetelui din interiorul partiției, aplicând permisiuni `R/W/X` exacte de 4 KB, în ciuda granularității de alocare de 64 KB a Windows.
- **Schimb de registre fără API prin `CommPage`**:
  - Pe `amd64`, un `SYSCALL` din Ring-3 al oaspetelui intră într-un stub `MSR_LSTAR` din Ring-0, aflat în interiorul partiției (`stubgen_x86.go`), care salvează în `CommPage`, o pagină partajată de 4 KB, registrele GPR ale apelului de sistem rapid (`RAX, RDI, RSI, RDX, R10, R8, R9, RIP, RSP`) și execută `HLT` pentru a ieși din `WHvRunVirtualProcessor`.
  - Pe `arm64`, un `SVC #0` din EL0 al oaspetelui intră în vectorii EL1 (`stubgen_a64.go`), salvează `X0..X8, SP_EL0, ELR_EL1, PSTATE` în `CommPage` și citește de la GPA zero, neasociat, pentru a declanșa o ieșire de memorie către Sentry.

### 2. Motorul hardware macOS: `platform/hvf` (`Hypervisor.framework`)

Pe Apple Silicon (`darwin/arm64`), `platform/hvf` rulează firele containerelor în vCPU-urile `Hypervisor.framework` (`hv_vm_create`, `hv_vcpu_run`):

- **Traducere MMU în două etape, de la pagini de 4 KB peste pagini de 16 KB**: Stage-2 (`hv_vm_map`) mapează, o singură dată, bucăți de fișier de memorie de 1 GiB în spațiul de adrese fizice intermediare (IPA), la granularitatea paginilor gazdă de 16 KB, cu `HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC`. În interiorul vCPU-ului, stub-ul EL1 `bluepill` (`bluepill_arm64.go`) configurează `TCR_EL1.TG0 = 0b00` (granulă de 4 KB) în `TTBR0_EL1` și populează intrările tabelelor de pagini Stage-1 de 4 KB cu permisiuni exacte `R-X` sau `RW-` (`UXN=1`). Deoarece MMU-ul ARM64 impune intersecția permisiunilor Stage-1 și Stage-2, hardware-ul interceptează erorile de permisiune la limitele exacte de 4 KB.
- **Interceptarea apelurilor de sistem**: Un `SVC #0` din EL0 al oaspetelui este interceptat de `VBAR_EL1` din EL1, salvează registrele în `CommPage`, o pagină partajată de 4 KB, și execută `HVC #0` pentru a reveni din `hv_vcpu_run` către firul Go al Sentry.

### 3. Rezerva în mod utilizator pentru Windows: `platform/systrap` (`winsystrap`)

Atunci când virtualizarea hardware nu este disponibilă (de exemplu, în VM-uri cloud imbricate), `winsystrap` rulează codul oaspetelui în mod utilizator pe `windows/amd64` și `windows/arm64`:

- **Izolarea hardware prin `CR3` / `TTBR0_EL1`**: Firele oaspetelui rulează în subprocese stub izolate, pornite dintr-un executabil generat de 1 KB (`stubimage_xplat.go`), confinate de un token cu integritate Low și de un Job Object.
- **Patch binar pe loc și IPC `winSysmsg`**: Pe `amd64`, patcher-ul (`patcher_amd64_xplat.go`) înlocuiește instrucțiunile `syscall` (`0f 05`) de 2 octeți cu salturi `jmp rel32` de 5 octeți (sau cu capcane de breakpoint `CC 90`, atunci când nu este disponibilă o fereastră de 5 octeți), care duc către o insulă cu cale rapidă. Pe `arm64`, `svc #0` este patch-uit cu o ramură `B` către un slot din insulă. Insula salvează registrele în pagina partajată `winSysmsg` și se sincronizează cu Sentry prin `WaitOnAddress` și `WakeByAddressSingle`, în timp ce capcanele nepatch-uite și erorile de pagină se opresc pe un Windows Debug Object (`WaitForDebugEventEx`).

### 4. Motorul Linux în mod utilizator: `platform/systrap`

Pe `linux/amd64` și `linux/arm64`, `systrap` rulează fire ale oaspetelui (`sysmsg`) care interceptează apelurile de sistem ale oaspetelui prin `SECCOMP_RET_TRAP` (`SIGSYS`) și patch-uiesc binar punctele `syscall` într-un trampolin de memorie partajată (`sysmsg`), sincronizat prin `SYS_FUTEX`. În paralel, un `syscallThread` stub (`syscall_thread.go`) execută operațiile asupra spațiului de adrese (`mmap`, `munmap`, `clone`) prin `SECCOMP_RET_USER_NOTIF` (`_RUN_SECCOMP_LOOP`). Atunci când `gvx` rulează în interiorul unui sandbox `gVisor` extern (`runsc`), unde unicul slot `SECCOMP_FILTER_FLAG_NEW_LISTENER` returnează `EBUSY`, `gvx` trece automat `syscallThread` pe o buclă futex cu memorie partajată (`_RUN_SYSCALL_LOOP`), după cum este detaliat în [Partea 3 a acestei serii](/blog/posts/docker-in-docker-inside-gvisor-with-gvx-z48916d03).

---

## Cum mapează `gvx` apelurile de sistem Linux ale oaspetelui către subsisteme virtuale și handle-uri ale gazdei

Odată ce un motor de platformă interceptează un `SYSCALL` (`amd64`) sau o instrucțiune `SVC #0` (`arm64`) a oaspetelui și scrie registrele oaspetelui în pagina partajată de 4 KB (`CommPage`, `sysmsg` sau `winSysmsg`), controlul revine la goroutina task-ului Go `Sentry` (`pkg/sentry/kernel/task_syscall.go`). În loc să redirecționeze apelurile de sistem Linux către kernel-ul sistemului de operare gazdă, `Task.doSyscall()` salvează starea originală a registrelor (`SyscallSaveOrig()`), evaluează eventualele filtre BPF `seccomp` din oaspete și opririle `ptrace`, apoi distribuie numărul apelului de sistem prin `linux.AMD64` sau `linux.ARM64` (`pkg/sentry/syscalls/linux/linux64.go`, care acoperă ~370 de apeluri de sistem Linux) în patru domenii interne:

![Cum mapează gvx apelurile de sistem Linux ale oaspetelui către subsisteme și sistemul de operare gazdă](/assets/images/gvx/gvx-syscall-mapping.png)

| Domeniu de apeluri de sistem | Apeluri de sistem Linux reprezentative ale oaspetelui | Subsistem intern `gvx` (`pkg/sentry`) | Interacțiunea cu granița sistemului de operare gazdă (după `hostlockdown`) |
| :--- | :--- | :--- | :--- |
| **A. Procese, namespace-uri, montări și sincronizare** | `clone`, `execve`, `unshare`, `setns`, `mount`, `umount2`, `pivot_root`, `setuid`, `capset`, `futex`, `epoll_wait`, `pipe2` | `kernel.Task`, acreditări virtuale, tabela futex și `VFS2` în memorie (`procfs`, `sysfs`, `cgroupfs` v2, `tmpfs`, `overlayfs`) | **Zero apeluri de sistem ale gazdei** (100% stare Go în memorie; complet invizibil pentru sistemul de operare gazdă) |
| **B. Memorie virtuală (`MM`)** | `mmap`, `munmap`, `mremap`, `mprotect`, `brk`, `madvise`, `memfd_create` | `mm.MemoryManager` (arbore VMA de 4 KB) și `pgalloc.MemoryFile` | Actualizări bidirecționale ale tabelelor de pagini de 4 KB prin `WHvMapGpaRange`, `hv_vm_map` + `TTBR0_EL1` sau prin `mmap`/`mprotect` ale stub-ului |
| **C. Fișiere și stocare (`VFS2`)** | `openat`, `pread64`, `pwrite64`, `getdents64`, `statx`, `renameat2`, `setxattr`, `mknod`, `inotify_add_watch` | Routerul tabelei de montări `vfs.VirtualFilesystem` (`fsimpl/erofs`, `fsimpl/ext4lite`, `fsimpl/hostfs` v2) | `pread`/`pwrite` bidirecționale pe 1 FD `.erofs` fixat sau pe 1 FD `.ext4`, sau parcurgeri relative limitate pe `*os.Root` |
| **D. Rețea și Netfilter** | `socket`, `bind`, `listen`, `connect`, `sendmsg`, `recvmsg`, `netlink`, `setsockopt(IPT_SO_SET_REPLACE)` | `pkg/tcpip` în user-space (`lo`, `eth0`, `docker0`, `veth`, `vxlan`, `wireguard`, `ipset`, `iptables-legacy`) | Traficul din interiorul sandbox-ului folosește **zero apeluri de sistem ale gazdei**; traficul extern se mapează pe `net.Dial`/`net.Listen` (`-net=nat`) sau pe 1 socket UDP (`-net=wg`) |

Atunci când handler-ul returnează `(rval, ctrl, err)`, `Task.doSyscallInvoke()` convertește orice eroare într-un `errno` Linux negativ (`-ExtractErrno(err, sysno)`), scrie valoarea de return înapoi în pagina partajată a registrelor (`RAX` pe `amd64`, `X0` pe `arm64`) și reia execuția oaspetelui.

---

## Stocarea (`VFS2`) și rețeaua în user-space cu dublă cale (`netstack`)

Toate operațiile de fișiere și de rețea ale oaspetelui sunt deservite în interiorul Go `Sentry`, prin trei sisteme de fișiere `VFS2` și două piste `pkg/netbackend`:

![Motoarele de stocare VFS2 și netstack cu dublă cale ale gvx](/assets/images/gvx/gvx-storage-netstack.png)

| Motor de stocare       | Rolul montării în `gvx`                          | Resursa de bază a gazdei               | Apeluri `openat` / `NtCreateFile` ale gazdei la rulare | Scanări per fișier ale `WdFilter.sys` (Windows Defender) |
| :--------------------- | :----------------------------------------------- | :------------------------------------- | -----------------------------------------------------: | -------------------------------------------------------: |
| **`fsimpl/erofs`**     | Straturi inferioare de imagine OCI, doar citire  | Un singur fișier `<sha256>.erofs` per strat | `0` | `0` |
| **`fsimpl/ext4lite`**  | Volume numite (`-v name:/path`)                  | Un singur fișier `<name>.ext4` per volum | `0` | `0` |
| **`fsimpl/hostfs` v2** | Spațiul de lucru al gazdei (`-workspace`, `-v /host:/guest`) | Director de gazdă fixat `*os.Root` | `O(depth)` per deschidere necacheată | `1` per închidere de fișier al gazdei |

### De ce contează `ext4lite` pentru Docker, baze de date și managerii de pachete

Extragerea sau scrierea a zeci de mii de fișiere de container direct pe NTFS (Windows) sau APFS (macOS) declanșează scanări ale filtrelor antivirus (`WdFilter.sys`), coliziuni de sensibilitate la majuscule și lipsa atributelor extinse POSIX.

`pkg/sentry/fsimpl/ext4lite` implementează un sistem de fișiere `ext4` pur Go în interiorul unui singur fișier al gazdei deschis anticipat (`%LOCALAPPDATA%\gvx\cache\volumes\<name>.ext4` pe Windows, `~/Library/Caches/gvx/volumes/<name>.ext4` pe macOS sau `~/.cache/gvx/volumes/<name>.ext4` pe Linux), cu:

- **Blocuri de 4 KiB și grupuri de blocuri dinamice de 16 MiB (`meta_bg`)**: Crește dinamic, fără blocaje de alocare a fișierelor sparse (`fallocate` pe Linux, `fcntl(F_PREALLOCATE)` pe macOS, `FileAllocationInfo` pe Windows) și compactează grupurile finale neutilizate la demontarea curată.
- **Jurnal JBD2 în modul ordonat (inode 8)**: Confirmări atomice ale tranzacțiilor cu sume de control CRC-32 și blocuri de revocare, plus recuperare `fsckLite`.
- **Suport pentru stratul superior `overlayfs`**: Implementează atributele extinse `trusted.overlay.*` și `security.capability`, whiteout-uri de dispozitive caracter (`0:0`), raportarea intrărilor de director `d_type` și `RENAME_EXCHANGE`.

---

## Sarcini practice: Docker Engine, Kubernetes (`k3s` + `Calico`) și SDK-ul Go

### Instalarea `rungv`: versiuni precompilate atestate SLSA sau `go install`

Puteți descărca o arhivă `rungv` precompilată pentru `linux/amd64`, `linux/arm64`, `darwin/arm64`, `windows/amd64` sau `windows/arm64` de la [GitHub Releases](https://github.com/gfire-sigs/gvx/releases) (fiecare construită de pipeline-ul de lansare SLSA, cu un pachet de proveniență Sigstore și `SHA256SUMS`), sau o puteți instala direct din sursă, cu `go install`:

```sh
# Opțiunea A: Descarcă o versiune precompilată și verifică proveniența construcției 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

# Opțiunea B: Instalează direct prin Go (Linux / Windows)
CGO_ENABLED=0 go install z.gfire.dev/gvx/cmd/rungv@latest
```

> Pe macOS (`darwin/arm64`), arhiva precompilată este deja semnată cu drepturile `com.apple.security.hypervisor` (`xattr -d com.apple.quarantine rungv` elimină carantina browserului). Dacă construiți local cu `go install` sau `go build` pe macOS, semnați binarul cu `codesign --sign - --entitlements entitlements.plist --force $(which rungv)`.

### 1. Rularea unui Docker Engine neprivilegiat (`docker:dind`)

Urmând [`docs/docker-engine.md`](https://github.com/gfire-sigs/gvx/blob/main/docs/docker-engine.md), puteți rula un container `docker:dind` nemodificat în `rungv` pe Windows, macOS sau Linux și îl puteți controla cu CLI-ul `docker` al gazdei:

```sh
# 1. Creează directorul gazdei pentru socket-ul Unix redirecționat
mkdir -p ~/.gvx

# 2. Pornește docker:dind într-un sandbox gvx cu un volum 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
```

Într-un al doilea terminal, indicați CLI-ul `docker` al gazdei către socket-ul sandbox-ului:

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

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

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

### 2. Rularea Kubernetes (`k3s` + `Calico`) în sandbox-uri neprivilegiate

Deoarece `gvx` implementează `/dev/kmsg`, `cgroup` v2 (`memory.max` cu OOM killer și `cpu.max` cu limitarea lățimii de bandă), `/proc/diskstats`, dispozitivele netlink `wireguard` și `vxlan`, `ipset` și `iptables-legacy` (`addrtype`, `conntrack`, `statistic`, `recent`), o imagine `rancher/k3s` nemodificată ajunge în starea `Ready` în interiorul unui singur proces `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
```

Puteți, de asemenea, să uniți mai multe noduri `gvx` prin WireGuard (`flannel-backend=wireguard-native` sau o rețea mesh `wg0`), cu disponibilitate ridicată `etcd` încorporat, sau să rulați **Calico** (`calico-vxlan.yaml` cu `FELIX_IPTABLESBACKEND=Legacy`) pentru a aplica `NetworkPolicy` Kubernetes complet în user-space.

### 3. Încorporarea containerelor Linux în Go prin `z.gfire.dev/gvx/pkg/gvx`

Aplicațiile Go pot încorpora containere Linux direct, fără un daemon extern de containere:

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

---

## Lecturi suplimentare din această serie

1. **[gvx: Rularea containerelor Linux, Docker și Kubernetes într-un singur proces neprivilegiat](/blog/posts/gvx-cross-platform-linux-containers-z48916d01)** (această postare)
2. **[Rularea Docker, docker build și docker compose fără root sau namespace-uri de utilizator](/blog/posts/run-docker-without-root-or-userns-gvx-z48916d02)**: Cum se pornește `docker:dind` în sandbox-uri restricționate, unde `sudo`, `unshare(CLONE_NEWUSER)`, `mount(2)` și `/dev/fuse` sunt blocate.
3. **[Rularea Docker-in-Docker în gVisor și în sandbox-uri imbricate cu gvx](/blog/posts/docker-in-docker-inside-gvisor-with-gvx-z48916d03)**: De ce `apt-get install docker.io` și `runsc` imbricat eșuează în interiorul `gVisor` din cauza a cinci bariere ale kernel-ului și cum rulează `gvx` un `docker:dind` imbricat, folosind o buclă futex cu memorie partajată.
4. **[Medii Docker izolate și rapide pentru rollout-urile RL ale agenților AI cu gvx](/blog/posts/fast-docker-environments-for-agent-rl-rollouts-z48916d04)**: Scalarea rollout-urilor `SWE-bench` și ale învățării prin întărire a agenților cu sute de instanțe `docker:dind` neprivilegiate, în paralel, și resetări de volume `.ext4` copy-on-write de 100 de milisecunde.
