gVisor - Abstractions
Because gVisor is essentially an entire operating system kernel written in Go (called the Sentry), it has to reimplement all standard Linux kernel concepts from scratch. To do this while adhering to container standards (like the OCI runtime spec), gVisor layers its abstractions into two categories: Workload Isolation Abstractions (managing containers/pods) and Kernel Execution Abstractions (managing processes/threads).
Workload Isolation Abstractions
These boundaries dictate how applications are containerized and walled off from the host operating system.
The Sandbox
- What it is in gVisor: The outermost boundary of isolation. A Sandbox represents a single instance of the Sentry process running on the host machine. It encapsulates its own dedicated, sandboxed memory space, virtualized network stack (Netstack), and set of namespaces. Multiple containers (e.g., a Kubernetes Pod containing an application and a sidecar) run inside a single Sandbox, sharing this single Sentry instance.
- Linux Kernel Equivalent: A Virtual Machine (VM) boundary / Hypervisor context. While gVisor is technically a process-level sandbox rather than a true hypervisor, conceptually it acts like a lightweight VM kernel boundary. In standard Linux container runtimes (
runc), there is no "Sandbox" abstraction; instead, containers rely directly on a combination of host-level Namespaces and Cgroups to achieve isolation.
Code: runsc/sandbox/sandbox.go
Container
- What it is in gVisor: A logical grouping of processes inside a Sandbox that shares a specific mount namespace and root filesystem config. A container inside gVisor is tied to a dedicated Gofer process on the host machine, which securely proxies file operations from that specific container's root filesystem.
- Linux Kernel Equivalent: A set of Namespaces (specifically Mount, UTS, and IPC) constrained by a Cgroup. Just like in standard Linux, a container in gVisor isn't a single kernel object—it is a collection of tasks configured to view the same filesystem tree and system identifiers.
Code: runsc/container/container.go
Kernel Execution Abstractions
These are the internal Go structures inside the Sentry that emulate how Linux handles threads, processes, and resources.
[ gVisor Sandbox (Sentry) ]
│
[ struct ThreadGroup ] <───> (Equivalent to a Linux Process)
│
┌─────────────┴─────────────┐
▼ ▼
[ struct Task ] [ struct Task ] <───> (Equivalent to Linux Threads)
Task
- What it is in gVisor: The foundational unit of execution within the Sentry. Represented in gVisor's internal Go code as
kernel.Task, it tracks the execution state of a single execution context. It holds registers, CPU architecture states, signal masks, and memory mappings. - Linux Kernel Equivalent:
struct task_struct. In Linux, everything that executes is atask_struct. Whether it is a single-threaded process or one of many threads inside a multi-threaded application, the Linux kernel scheduler treats each as an individualtask_struct. gVisor'skernel.Taskmirrors this exact design.
Code: pkg/sentry/kernel/task.go
ThreadGroup
- What it is in gVisor: A collection of
Taskobjects that share the same resources, such as memory space (virtual memory mappings), signal handlers, and a shared Thread Group ID (TGID). - Linux Kernel Equivalent: A Process. In Linux, a "process" is technically just a group of
task_structobjects that share memory and signal tables, bound together under the same Thread Group Leader. When you issue aclone()syscall in Linux with flags likeCLONE_VMandCLONE_SIGHAND, you add a thread to a process. In gVisor, this translates to adding aTaskto aThreadGroup.
Code: pkg/sentry/kernel/thread_group.go
MemoryManager (MM)
- What it is in gVisor: The component inside the Sentry that emulates virtual memory allocation, page tables, memory mappings (
mmap), and memory protections (mprotect) for a specificThreadGroup. - Linux Kernel Equivalent:
struct mm_struct. In the Linux kernel, themm_structinsidetask_structdefines the memory footprint of a process. When threads share memory, theirtask_struct->mmpointers point to the exact samemm_struct. gVisor mimics this by pointing multipleTaskstructures to a singleMemoryManager.
FDTable (File Descriptor Table)
- What it is in gVisor: An internal table mapped to a
ThreadGroupthat tracks integer values (file descriptors) and translates them into virtual file objects (vfs.FileDescription) managed inside the Sentry. - Linux Kernel Equivalent:
struct files_struct/fdtable. In Linux, this is the table that maps your open files (like FD0,1,2) to the kernel's underlyingstruct fileobjects.
Quick Reference Summary
To visualize how these concepts translate, use this mapping table:
| gVisor Concept | Linux Kernel Equivalent | Scope / Responsibility |
|---|---|---|
| Sandbox | No direct equivalent (Closest to a VM boundary) | The boundary of the Sentry kernel instance. |
| Container | Host Namespaces + Cgroups | A filesystem and resource boundary inside the Sentry. |
| ThreadGroup | Process (task_struct leader) |
A collection of threads sharing memory and signals. |
| Task | Thread (struct task_struct) |
The atomic unit of execution and scheduling. |
| MemoryManager | struct mm_struct |
Manages virtual memory mappings (mmap) for a process. |
| FDTable | struct files_struct |
Tracks integer File Descriptors for a process. |