How to Manage Linux Kernels in Containers Using Container System Kernel Commands

The apple/container project provides the container system kernel CLI commands to install, list, and switch Linux kernels used by the container runtime on macOS, storing binaries in a per-platform directory and managing the active kernel through a default symlink.

The apple/container repository implements a specialized container runtime for macOS that leverages lightweight virtual machines. To manage Linux kernels in container using container system kernel commands, the project exposes a gRPC-backed service that handles kernel installation, extraction from archives, and runtime configuration updates.

Understanding Kernel Configuration

ContainerSystemConfig and KernelConfig

The kernel configuration resides in the top-level system configuration defined in Sources/ContainerPersistence/ContainerSystemConfig.swift (lines 66-84). This Codable class aggregates several sub-configurations, including the kernel configuration (KernelConfig).

KernelConfig holds two critical properties:

  • binaryPath: The relative path of the kernel binary inside a downloaded Kata-Containers archive. The default value is opt/kata/share/kata-containers/vmlinux-6.18.15-186 (lines 67-71).
  • url: The URL of the archive providing the kernel binary, defaulting to the latest Kata-Containers release for arm64 (lines 71-74).

How the KernelService Manages Binaries

When the container runtime starts, it reads the kernel configuration and loads the kernel from the "default kernel" symlink managed by the KernelService in Sources/Services/ContainerAPIService/Server/Kernel/KernelService.swift (lines 27-45). This service maintains the active kernel selection independently of the configuration file, allowing runtime switching without editing TOML.

Installation Workflows

The KernelService implements two primary installation paths:

  1. Local file installation: The installKernel(kernelFile:platform:force:) method (lines 38-44) copies a supplied binary into the per-platform kernels directory and updates the default-kernel symlink.
  2. Archive extraction: The installKernelFrom(tar:kernelFilePath:platform:…) method (lines 81-88) extracts a specific member from a tar archive before delegating to the standard installation routine.

The KernelHarness.swift file bridges CLI requests to these service methods, translating container system kernel set invocations into gRPC calls.

Using Container System Kernel Commands

Listing Active and Available Kernels

To view all installed kernels and identify which one is currently active, use the list command:

container system kernel list

This enumerates all kernels stored under the <app-root>/kernels directory and highlights the symlink target.

The --recommended flag downloads the archive defined in KernelConfig.defaultURL and installs the default binary as the new system kernel:

container system kernel set --recommended

This command overrides any existing default kernel and is the preferred method for maintaining the latest Kata-Containers release.

Installing Custom Kernels

You can install kernels from local files or remote archives using the --binary and --tar flags.

To install a locally compiled kernel binary:

container system kernel set --binary /Users/me/kernels/vmlinux-custom

To extract and install a kernel from a specific Kata release:

container system kernel set \
    --tar https://github.com/kata-containers/kata-containers/releases/download/3.28.0/kata-static-3.28.0-arm64.tar.zst \
    --binary opt/kata/share/kata-containers/vmlinux-6.18.15-186

To force replacement of an existing kernel with the same name:

container system kernel set --binary ./vmlinux --force

Runtime Integration

The kernel that the runtime actually boots is exposed via the RuntimeConfiguration struct in Sources/Services/Runtime/RuntimeClient/RuntimeConfiguration.swift (lines 26-31). This structure contains a kernel: Kernel property that references the default kernel symlink. When you change the default kernel using the CLI commands, subsequent container VMs automatically use the new kernel image without requiring service restarts.

Summary

  • Configuration: Kernel settings are defined in ContainerSystemConfig.swift through the KernelConfig struct, specifying default URLs and binary paths.
  • Service Layer: KernelService.swift manages physical kernel storage, symlink updates, and archive extraction.
  • CLI Interface: The container system kernel commands provide list, set, and installation capabilities with support for local files, remote archives, and recommended defaults.
  • Runtime Impact: Changes to the default kernel immediately affect new container VMs via RuntimeConfiguration.

Frequently Asked Questions

How do I check which kernel is currently active?

Run container system kernel list. This command displays all kernels in the application directory and identifies which one is linked as the default target.

Where does the container runtime store kernel binaries?

Kernels are stored in a per-platform kernels directory under the application root. The KernelService maintains a symlink to the currently active default kernel, which the runtime reads when creating new VMs.

Can I use a custom-compiled Linux kernel instead of the Kata-Containers default?

Yes. Use container system kernel set --binary /path/to/vmlinux to install a custom kernel. The --force flag allows you to replace an existing kernel with the same filename. The KernelService.installKernel() method handles the copy operation and updates the default symlink automatically.

The --recommended flag triggers a download from the URL specified in KernelConfig.defaultURL, extracts the default binary path (opt/kata/share/kata-containers/vmlinux-6.18.15-186), and installs it as the new system kernel. This ensures you are running the latest Kata-Containers release for your architecture.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →