Container Nested Virtualization Requirements: How to Enable KVM in Apple Container Machines
Enabling nested virtualization in Apple Container machines requires three specific conditions: an M3 or newer Apple Silicon Mac, macOS 15 or later, and a custom Linux kernel compiled with CONFIG_KVM=y.
The apple/container project allows container machines to expose a virtual /dev/kvm device, enabling workloads like QEMU and Docker-in-Docker to run their own virtual machines. This capability is gated by strict hardware and software requirements that are enforced at runtime by the CLI. When all conditions are met, users can create fully isolated virtualization environments inside containers; when any condition is missing, the system aborts with a clear error message.
Hardware and Software Requirements
Nested virtualization is not automatically available on all Apple Silicon devices. The implementation relies on specific CPU extensions and kernel APIs that only exist in newer hardware and operating system versions.
Apple Silicon M3 or Newer
The host must be an M3 or newer Apple Silicon Mac. Earlier silicon generations (M1 and M2) lack the necessary hardware-assisted virtualization extensions—the ARM equivalent of Intel's VMX or AMD's SVM. According to the source code in Sources/ContainerCommands/Machine/MachineCapabilities.swift, the runtime check requireNestedVirtualizationSupported() validates the CPU architecture before allowing the --virtualization flag to proceed.
macOS 15 or Later
The host must run macOS 15 (Sequoia) or a newer version. Apple's Hypervisor Framework, which backs the virtual /dev/kvm device, was opened to third-party developers starting with macOS 15 on M3 silicon. The kernel APIs required to expose KVM functionality are absent in earlier macOS releases, making this a hard dependency regardless of the host's CPU generation.
Custom Kernel with KVM Support
The container machine must run a custom Linux kernel built with CONFIG_KVM=y. The default kernel shipped with the apple/container project is intentionally minimal and omits KVM support to reduce image size. You must compile or obtain a kernel binary that includes the KVM subsystem, as the kernel cannot create /dev/kvm at boot time without this compile-time flag.
Creating a Container Machine with Nested Virtualization
Once you satisfy the three requirements, use the --virtualization flag combined with the --kernel option to point to your KVM-enabled kernel binary.
Create a new machine with nested virtualization enabled:
# Ensure you have a kernel compiled with CONFIG_KVM=y (e.g., vmlinux-kvm)
container machine create \
--virtualization \
--kernel /path/to/vmlinux-kvm \
--name kvm-dev \
alpine:latest
The --virtualization flag triggers the capability check in Sources/ContainerCommands/Machine/MachineCreate.swift, which calls MachineCapabilities.requireNestedVirtualizationSupported() to verify the host meets the M3 and macOS 15 requirements.
Verifying KVM Device Availability
After creating the machine, confirm that the /dev/kvm device exists inside the container:
container machine run -n kvm-dev -- ls -l /dev/kvm
A successful configuration shows the device file with appropriate permissions, allowing guest workloads to initialize the KVM subsystem.
Managing Nested Virtualization on Existing Machines
You can enable or disable nested virtualization on existing machines by modifying the machine configuration and rebooting.
Enable nested virtualization on an existing machine:
container machine set -n kvm-dev virtualization=true kernel=/path/to/vmlinux-kvm
container machine stop kvm-dev
container machine start kvm-dev
container machine run -n kvm-dev -- ls -l /dev/kvm
Disable nested virtualization and revert to the default kernel:
container machine set -n kvm-dev kernel=
container machine stop kvm-dev
container machine start kvm-dev
container machine run -n kvm-dev -- ls -l /dev/kvm # Device should not exist
Setting kernel= to an empty value removes the custom kernel path, causing the machine to use the default minimal kernel on next boot.
Implementation Details in the Source Code
The requirement checks are implemented in specific source files within the apple/container repository:
-
Sources/ContainerCommands/Machine/MachineCapabilities.swift– Contains the platform validation logic that emits the error"nested virtualization is not supported on the platform"when the host lacks M3 silicon or macOS 15. -
Sources/ContainerCommands/Machine/MachineCreate.swift– Defines the--virtualizationand--kernelcommand-line flags. This file orchestrates the validation sequence before machine creation. -
docs/container-machine.md– Documents the hardware requirements and provides guidance on building custom kernels withCONFIG_KVM=y.
Summary
- Nested virtualization in
apple/containerrequires M3+ Apple Silicon, macOS 15+, and a custom kernel withCONFIG_KVM=y. - The default kernel does not support KVM; you must supply a custom kernel binary using the
--kernelflag. - The CLI validates requirements at runtime via
MachineCapabilities.requireNestedVirtualizationSupported()and aborts with an error if the platform is unsupported. - Use
container machine setto modify virtualization settings on existing machines, followed by a stop/start cycle to apply changes.
Frequently Asked Questions
Why don't M1 or M2 Macs support nested virtualization?
M1 and M2 chips lack the specific hardware-assisted virtualization extensions required by Apple's Hypervisor Framework to safely expose /dev/kvm to guest machines. The MachineCapabilities.swift source code explicitly checks for M3 or newer silicon because these processors include the necessary ARM virtualization features that match the capabilities exposed in macOS 15.
Can I use the default kernel provided by the container project?
No. The default kernel shipped with apple/container is built without CONFIG_KVM=y to minimize size and attack surface. You must compile your own kernel or obtain one from a Linux distribution that includes KVM support, then specify it using the --kernel flag when creating or configuring the machine.
How do I check if my system supports nested virtualization before attempting to create a machine?
The most reliable method is attempting to create a machine with the --virtualization flag. The CLI will immediately validate your hardware and OS version through MachineCapabilities.requireNestedVirtualizationSupported() and return the error "nested virtualization is not supported on the platform" if your M-series chip or macOS version is incompatible. Alternatively, verify you are running macOS 15 or later on an M3, M3 Pro, M3 Max, or newer chip.
What happens if I try to enable nested virtualization without meeting all requirements?
The container CLI aborts the operation with the error message "unsupported: \"nested virtualization is not supported on the platform\"". This check occurs in MachineCapabilities.swift before any machine resources are allocated, preventing configuration errors that would result in missing /dev/kvm devices inside the container.
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 →