# How the Virtualization Framework Integrates with Container for Linux VM Management in Apple Container

> Learn how Apple's Virtualization framework manages Linux VMs within Apple Container. Discover how VZVirtualMachineManager and vmnet enable seamless VM integration and networking.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: internals
- Published: 2026-06-14

---

**The Virtualization framework powers Apple Container by providing the VZVirtualMachineManager to create and manage Linux VMs, while NonisolatedInterfaceStrategy bridges VM networking to the host via vmnet.**

Apple Container leverages Apple's native Virtualization framework to run each container inside a lightweight Linux virtual machine. This integration allows the container runtime to manage VM lifecycle, networking, and filesystem mounts through native APIs. Understanding how the Virtualization framework integrates with container for Linux VM management reveals the architecture behind Apple's secure, isolated container environment.

## VM Creation via VZVirtualMachineManager

When a client requests a container bootstrap, the **RuntimeService** instantiates **VZVirtualMachineManager** from the Virtualization framework to construct the VM. This manager handles the Linux kernel binary, root filesystem, and Rosetta translation settings.

In [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift) (lines 165‑167), the service initializes the manager:

```swift
let vmm = VZVirtualMachineManager(
    kernel: kernel,
    initialFilesystem: bundle.initialFilesystem.asMount,
    rosetta: config.rosetta,
    logger: self.log
)

```

The parameters supplied to `VZVirtualMachineManager` include:

- **kernel**: The Linux kernel binary provided by the container bundle.
- **initialFilesystem**: The root filesystem mount (often `virtiofs` or `tmpfs`) that becomes the VM's `/`.
- **rosetta**: A boolean enabling Rosetta translation for x86_64 code on Apple Silicon.
- **logger**: The logging infrastructure for VM operations.

After instantiation, the service wraps the manager in a **LinuxContainer** (lines 53‑56):

```swift
let container = try LinuxContainer(
    id,
    rootfs: bundle.containerRootfs.asMount,
    vmm: vmm,
    logger: self.log
) { czConfig in
    // configure container (CPU, memory, mounts, etc.)
}

```

The Virtualization framework supplies the complete VM lifecycle through `VZVirtualMachineManager`, including start, stop, and snapshot operations, while `LinuxContainer` interacts with the underlying `VZVirtualMachine` objects.

## Network Integration with NonisolatedInterfaceStrategy

Containers requesting *non‑isolated* network access (shared with the host) utilize the **NonisolatedInterfaceStrategy** to bridge the VM's virtual NIC to the host network stack. This strategy combines the Virtualization framework with the **`vmnet`** kernel extension.

In [`Sources/Services/RuntimeLinux/Server/NonisolatedInterfaceStrategy.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/NonisolatedInterfaceStrategy.swift) (lines 23‑55), the `toInterface` method deserializes the vmnet network reference and constructs a NAT interface:

```swift
public func toInterface(
    attachment: Attachment,
    interfaceIndex: Int,
    additionalData: XPCMessage?
) throws -> Interface {
    // Deserialize the vmnet network reference received from the network plugin
    var status: vmnet_return_t = .VMNET_SUCCESS
    guard let networkRef = vmnet_network_create_with_serialization(
        additionalData.underlying, &status) else {
        throw ContainerizationError(...)
    }
    // Build a NATNetworkInterface that the VM will see
    return NATNetworkInterface(
        ipv4Address: attachment.ipv4Address,
        ipv4Gateway: ipv4Gateway,
        reference: networkRef,
        macAddress: attachment.macAddress,
        mtu: attachment.mtu ?? 1280
    )
}

```

The integration process involves:

- **Importing** `Virtualization` for VM networking APIs.
- **Deserializing** the network reference via `vmnet_network_create_with_serialization`.
- **Exposing** a `NATNetworkInterface` that attaches to the VM, providing access to the host‑managed network.

The Virtualization framework works with **vmnet** to present a virtual NIC inside the Linux VM, backed by the host‑side network created by the `container-network-vmnet` plugin.

## Filesystem Caching for Virtualized Storage

When using **virtiofs** for root filesystem or data shares, the container code defaults the cache mode to `.on` to avoid a known Linux filesystem bug that manifests under virtualization.

In [`Sources/ContainerResource/Container/Filesystem.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Container/Filesystem.swift) (lines 88‑90), the code specifies:

```swift
// Defaulting to CachedMode = .on (i.e., cached mode) to fix Linux FS issue when using Virtualization

```

This default ensures stable I/O performance when the Virtualization framework handles filesystem passthrough. The `Filesystem` initializer applies this setting automatically when constructing virtiofs mounts for the VM.

## End‑to‑End Integration Flow

The complete integration between the Virtualization framework and container runtime follows this sequence:

1. **Bootstrap Request**: Client sends an XPC request to `RuntimeService.bootstrap`.
2. **VM Construction**: Service creates `VZVirtualMachineManager` with the container's kernel and initial filesystem.
3. **Container Wrapper**: `LinuxContainer` encapsulates the VM configuration and Virtualization objects.
4. **Network Setup**: For non‑isolated networks, `NonisolatedInterfaceStrategy` creates a `NATNetworkInterface` backed by a `vmnet` reference.
5. **VM Startup**: The Virtualization framework starts the VM, mounts the root filesystem, attaches network interfaces, and executes the init process.
6. **Lifecycle Management**: Throughout the container's lifetime, the service uses Virtualization APIs (`container.stop()`, `container.dialVsock()`) to control the VM.

## Summary

- **VZVirtualMachineManager** from the Virtualization framework creates and manages the Linux VM hosting each container.
- **NonisolatedInterfaceStrategy** bridges VM networking to the host via `vmnet_network_create_with_serialization` and `NATNetworkInterface`.
- The framework requires **cached virtiofs mode** (`.on`) to avoid Linux filesystem bugs under virtualization.
- **RuntimeService** orchestrates the integration, wiring VM lifecycle, networking, and filesystems together.

## Frequently Asked Questions

### How does the Virtualization framework integrate with container for Linux VM management?

The Virtualization framework provides the **VZVirtualMachineManager** class that Apple Container uses to create, configure, and manage Linux VMs. This manager handles the kernel, initial filesystem, and Rosetta settings, while the framework's networking APIs enable bridge connections to the host via vmnet.

### What role does vmnet play in Apple Container networking?

The **vmnet** kernel extension provides the underlying network interface that the Virtualization framework exposes inside the Linux VM. When a container requests non‑isolated networking, `NonisolatedInterfaceStrategy` deserializes the vmnet reference using `vmnet_network_create_with_serialization` and attaches it as a `NATNetworkInterface` to the VM.

### Why does Apple Container default virtiofs to cached mode?

The codebase defaults **virtiofs cache mode to `.on`** in [`Filesystem.swift`](https://github.com/apple/container/blob/main/Filesystem.swift) to avoid a known Linux filesystem bug that occurs when using virtualization. This ensures data consistency and prevents I/O errors during container operations.

### Where is the Linux kernel specified when creating the VM?

The Linux kernel binary is passed as the **kernel** parameter to `VZVirtualMachineManager` during initialization in [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift) (lines 165‑167). The kernel is provided by the container bundle and loaded by the Virtualization framework when the VM starts.