How to Configure Kernel Settings and Custom Kernels for Containers
You can configure custom kernels for Apple Container by editing the [kernel] table in config.toml, using the --kernel CLI flag at creation time, or running container system kernel set to download and persist custom kernel archives system-wide.
Apple Container implements its macOS runtime using a guest Linux kernel downloaded from Kata Containers releases. The KernelConfig struct in ContainerSystemConfig.swift defines default binary paths and download URLs, but you can override these settings to enable nested virtualization or use custom-built kernels with specific feature flags like CONFIG_KVM=y.
Understanding the Default Kernel Configuration
The source of truth for kernel defaults lives in Sources/ContainerPersistence/ContainerSystemConfig.swift. Here, the KernelConfig struct specifies the binaryPath (location of the vmlinux executable inside the archive) and the url (download location of the Kata static bundle). By default, the system pulls the latest Kata Containers release and extracts the kernel to a system directory.
The [kernel] table in config.toml stores these values persistently. When the runtime starts, it checks this configuration to determine which kernel binary to load into the virtual machine.
Method 1: Edit the System Configuration File
You can directly modify the [kernel] table in config.toml to point to custom archives. This table accepts two keys:
binaryPath: The path inside the downloaded archive that contains the kernel executable (vmlinux).url: A URL to a tar or zst archive containing the kernel.
[kernel]
binaryPath = "opt/kata/share/kata-containers/vmlinux-6.18.15-186"
url = "https://github.com/kata-containers/kata-containers/releases/download/3.28.0/kata-static-3.28.0-arm64.tar.zst"
After editing, new container machines will use the specified kernel automatically.
Method 2: Set a Custom Kernel at Creation Time
For one-off containers or machines, use the --kernel (or -k) CLI flag with container run, container create, or container machine create. This flag accepts a local path to any kernel binary that supports required features.
This is essential for nested virtualization on Apple Silicon M3+ and macOS 15+, where you need a kernel compiled with CONFIG_KVM=y:
container machine create \
--virtualization \
--kernel /path/to/vmlinux-kvm \
--name kvm-dev \
alpine:latest
The --kernel flag overrides the system default for that specific instance only.
Method 3: Persist a Custom Kernel System-Wide
The container system kernel set command downloads, extracts, and persists a custom kernel archive to config.toml. Use this to install kernels from remote URLs or local tarballs.
Install from a local archive:
container system kernel set --tar ./my-kernel.tar.xz --binary vmlinux --force
Install from a remote URL:
container system kernel set --tar https://example.com/my-kernel.tar.zst \
--binary vmlinux --force
Revert to the shipped default kernel:
container system kernel set --recommended --force
You can verify the current configuration with container system kernel get.
Enabling Nested Virtualization
The default Kata kernel does not enable CONFIG_KVM=y, which is required for nested virtualization on Apple Silicon M3+ and macOS 15+. To expose /dev/kvm inside your container machine, you must supply a custom kernel with KVM support compiled in.
Additionally, you can inject kernel command-line arguments via the kernel.commandLine.kernelArgs property handled in Sources/Services/RuntimeLinux/Server/RuntimeService.swift. This allows you to enable debugging features, security modules, or other boot parameters without rebuilding the kernel.
Practical Configuration Examples
# 1️⃣ Display current kernel configuration
container system kernel get
# 2️⃣ Run a container with a custom kernel for one-off testing
container run --kernel /opt/kernels/vmlinux-kvm ubuntu:latest uname -r
# 3️⃣ Persist a custom kernel archive for all future machines
container system kernel set --tar https://example.com/custom-kernel.tar.zst \
--binary vmlinux --force
# 4️⃣ Verify nested virtualization is available inside the machine
container machine run -n dev -- ls -l /dev/kvm
# 5️⃣ Return to the default Kata kernel
container system kernel set --recommended --force
Summary
- Default configuration is defined in
Sources/ContainerPersistence/ContainerSystemConfig.swiftvia theKernelConfigstruct, which points to Kata Containers releases. - Three customization methods: Edit
config.tomldirectly, use the--kernelCLI flag at runtime, or runcontainer system kernel setto persist custom archives. - Nested virtualization requires a custom kernel with
CONFIG_KVM=yon Apple Silicon M3+ and macOS 15+, as the default kernel lacks KVM support. - Kernel arguments can be modified via
kernel.commandLine.kernelArgshandling inSources/Services/RuntimeLinux/Server/RuntimeService.swift.
Frequently Asked Questions
How do I check which kernel my containers are currently using?
Run container system kernel get to display the current binaryPath and url values stored in config.toml. This shows whether you are using the default Kata kernel or a custom configuration.
Can I use any Linux kernel with Apple Container?
No. The kernel must support the specific features required by the container runtime, such as the virtio drivers needed for the virtualization layer. For nested virtualization on Apple Silicon, the kernel must explicitly enable CONFIG_KVM=y, which the default Kata kernel does not include.
How do I enable nested virtualization for KVM workloads?
You must obtain or build a Linux kernel with CONFIG_KVM=y enabled, then install it using either container system kernel set --tar <archive> --binary vmlinux for persistence, or container machine create --kernel <path> for temporary use. Once configured, /dev/kvm will be available inside the container machine.
Will switching kernels affect existing container machines?
Existing machines retain the kernel they were created with. Changing the system kernel via container system kernel set or editing config.toml only affects new containers or machines created after the change. To update an existing machine, you must recreate it with the --kernel flag or delete and recreate the machine after updating the system default.
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 →