How to Enable Nested Virtualization in Containers with the --virtualization Flag
The --virtualization flag enables hardware-assisted nested virtualization for container machines by propagating a Boolean value from the CLI through the runtime to the Linux VM configuration.
The apple/container repository provides a native container runtime for macOS that supports running Linux containers inside lightweight virtual machines. When you need to run virtualized workloads inside these containers—such as KVM guests or nested containers—the --virtualization flag exposes the host's virtualization extensions to the container machine. This feature requires specific hardware and software support, which the runtime validates before booting the VM.
How the --virtualization Flag Works
The flag operates through a five-layer propagation chain that moves the configuration from user input down to the kernel-level VM settings.
CLI Flag Definition
The flag is defined in the management subgroup of the CLI flag hierarchy in Sources/Services/ContainerAPIService/Client/Flags.swift:
public struct Management: ParsableArguments {
…
@Flag(name: .long,
help: "Enable nested virtualization (requires Apple Silicon M3+ and macOS 15+ and kernel with CONFIG_KVM=y)")
public var virtualization: Bool
…
}
This structure captures the Boolean value at lines 94‑96.
Command-Level Wiring
In Sources/ContainerCommands/Machine/MachineCreate.swift, the MachineCreate command reads the flag and performs a capability check before inserting the value into the boot configuration dictionary:
if virtualization {
try MachineCapabilities.requireNestedVirtualizationSupported()
}
let bootConfig = try defaultConfig.with(
[
// …
"virtualization": virtualization ? "true" : nil,
// …
].compactMapValues { $0 }
)
The validation occurs at lines 67‑73, ensuring the host supports nested virtualization before proceeding.
Boot-Time Configuration
The MachineConfig struct in Sources/ContainerPersistence/MachineConfig.swift stores the raw boot parameters. It parses the dictionary value into a Boolean property:
public let virtualization: Bool
…
let virtualization = try kwargs["virtualization"].map { try Self.parseBool($0, for: "virtualization") }
…
return try .init(
// …
virtualization: virtualization ?? self.virtualization,
// …
)
This implementation appears at lines 55‑64.
Container Runtime Configuration
When instantiating the container, the runtime builds a ContainerConfiguration object. In Sources/ContainerResource/Container/ContainerConfiguration.swift, the field mirrors the machine's boot-time value:
public var virtualization: Bool = false
…
virtualization = try container.decodeIfPresent(Bool.self, forKey: .virtualization) ?? false
The property definition and decoding logic are found at lines 49‑51.
Runtime Service Propagation
Finally, RuntimeService in Sources/Services/RuntimeLinux/Server/RuntimeService.swift copies the flag into the low-level runtime configuration:
czConfig.virtualization = config.virtualization
This assignment at lines 994‑995 enables the Linux VM to expose KVM to guest workloads when the host kernel supports it.
Prerequisites and Compatibility
Enabling nested virtualization requires strict hardware and software alignment:
- Hardware: Apple Silicon M3 or newer
- Operating System: macOS 15 or newer
- Kernel Configuration: Host kernel built with
CONFIG_KVM=y
If any prerequisite is missing, MachineCapabilities.requireNestedVirtualizationSupported() aborts the command early with an appropriate error.
Practical Usage Examples
Creating a Machine with Nested Virtualization
To create a container machine with virtualization enabled:
container machine create \
--name my-vm \
--virtualization \
--image alpine:latest
The flag sets virtualization = true in the boot config, which propagates through to the Linux runtime.
Verifying the Setting
Inspect the machine configuration to confirm the flag was applied:
container machine inspect my-vm --format json | jq .virtualization
The output returns true when the flag was supplied during creation.
Disabling Virtualization
Omit the flag to run without nested virtualization. The default value is false, meaning the container operates without exposing KVM to guest workloads.
Summary
- The
--virtualizationflag is a top-level option forcontainer machine createthat enables nested virtualization support. - The flag propagates through
Flags.swift,MachineCreate.swift,MachineConfig.swift,ContainerConfiguration.swift, and finallyRuntimeService.swift. - Prerequisites include Apple Silicon M3+, macOS 15+, and a kernel built with
CONFIG_KVM=y. - The runtime validates capabilities via
MachineCapabilities.requireNestedVirtualizationSupported()before booting. - When enabled, the Linux VM exposes hardware-assisted virtualization to container workloads.
Frequently Asked Questions
What hardware is required to use the --virtualization flag?
The flag requires Apple Silicon M3 or newer. The MachineCapabilities.requireNestedVirtualizationSupported() function verifies this hardware capability before the machine boots. Older Apple Silicon chips or Intel-based Macs do not support this feature.
Does the --virtualization flag work on macOS versions earlier than 15?
No. The flag requires macOS 15 or newer, as indicated in the CLI help text and enforced by the capability check in MachineCreate.swift. Attempting to use the flag on older macOS versions results in an error during the validation phase.
How does the flag propagate from the command line to the VM?
The propagation follows a strict chain: Flags.swift parses the CLI input, MachineCreate.swift validates and inserts it into the boot config, MachineConfig.swift stores it as a property, ContainerConfiguration.swift decodes it for the runtime, and RuntimeService.swift assigns it to the low-level VM configuration at lines 994‑995.
Can I disable virtualization after creating a machine?
No. Virtualization is a boot-time configuration set via MachineConfig during machine creation. To change the setting, you must recreate the machine without the --virtualization flag. The default value is false, so omitting the flag creates a machine without nested virtualization support.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →