Architecture
vNode wraps each pod in a lightweight sandbox that acts as a minimal host environment. The workload sees a normal Linux environment. The host sees an unprivileged process. No hypervisor or guest kernel is involved, so containers run at native speed.
vNode achieves isolation through three kernel-level mechanisms: Linux user namespaces, FUSE-based filesystem virtualization, and targeted seccomp filtering. These prevent a process inside a vNode from accessing other tenants' files, processes, or hardware information. This protection holds even after a container escape.
Because vNode doesn't use virtualization technologies like KVM or Hyper-V, it adds no meaningful overhead. Workloads run at near-native speed.
vNode places a pod inside a sandbox managed by vnode-manager on the Kubernetes node.
Namespace layers
vNode adds a set of Linux namespace layers between the pod and the host node. A single vNode can be shared across multiple pods in the same namespace. This is useful when those pods belong to the same tenant, for example all pods inside a vCluster tenant cluster. Privileged workloads like Prometheus or Fluentd can only see pods inside their own vNode, not the host node or other tenants' workloads.
A pod can safely use features like hostPID, hostPaths, hostNetwork, and Docker-in-Docker inside a vNode. These features are scoped to the vNode rather than the host node, so they don't grant additional capabilities on the actual host.
vNode scopes user, network, process, and mount namespaces between the pod sandbox and host.
Isolation granularity
vNode supports two isolation modes.
Per-namespace mode (default): One vNode runs per namespace per node. Pods in the same namespace share a PID namespace inside the vNode. This is the right choice when namespace boundaries align with tenant boundaries, for example when using vCluster, where all pods in a namespace belong to the same tenant.
Per-pod mode: Every pod gets its own isolated vNode. Enable this by setting the VNODE_PER_POD=true environment variable on the DaemonSet. Use this when pods from different users or builds share a namespace, for example in CI/CD environments. The trade-off is higher per-node memory overhead.
Startup sequence
When the vNode DaemonSet starts on a node, it runs the following steps in order:
The vNode DaemonSet prepares the node before accepting sandboxed workloads.
- Preflight checks — verifies kernel version (6.1 or later), cgroup v2, and a running containerd daemon
- System preparation — remounts
/sysread-write and removes bind mounts that would interfere with vNode pods - Containerd configuration — registers the
vnodeandvnode-launcherruntime classes with containerd - AppArmor setup — loads the
vnode-defaultAppArmor profile and injects the FUSE mount rule into the fusermount3 profile - CNI setup — creates the
vnode-cnisymlink and writes the CNI configuration - Manager proxy — starts the vNode manager proxy, which is ready to accept workloads
Components
vNode runtime components coordinate sandbox launch and workload launch inside the vNode.
The vNode runtime consists of the following components.
vNode Manager
vnode-manager is the main binary. Like busybox, it's a multi-call binary that serves three roles:
- CNI plugin (
vnode-cni): Called by containerd to remount the network namespace into the vNode user namespace. It runs the vNode CNI after the host CNI finishes. - Containerd shim plugin (
containerd-shim-vnode-v2): Called by containerd to return the socket path of the vnode-manager. - Manager service (
vnode-manager): Coordinates the vNode runtime. Provides custom/procand/sysfilesystems via FUSE, intercepts syscalls via the seccomp filter, manages the vnode shim, and handles UID/GID mappings.
vNode Init
vnode-init runs as PID 1 inside each vNode. It reaps zombie containerd-shim processes, keeping the vNode clean even across containerd upgrades.
vNode RunC
vnode-runc is a fork of RunC that starts vNode containers:
containerd → vnode-manager → vnode-containerd-shim-runc-v2 → vnode-runc
Compared to upstream RunC, vnode-runc integrates the vNode manager directly, fixes Linux user namespace issues, and requires cgroup v2.
vNode Containerd Shim
vnode-containerd-shim-runc-v2 spins up new vNodes:
containerd → vnode-manager → vnode-containerd-shim-runc-v2 → vnode-runc
It handles ID-mapped mounts and sets up FUSE, seccomp, and the vNode manager API for each new vNode.
vNode Utils
vnode-utils handles supporting operations: network namespace setup within a user namespace, bind-path operations between the host and vNode, directory creation, and file copying into a vNode.