# How to Install and Manage Custom Linux Kernels with `container system kernel set`

> Install and manage custom Linux kernels for Apple Container system VMs. Use container system kernel set with flags to update or replace the default guest kernel.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: how-to-guide
- Published: 2026-06-13

---

**Use `container system kernel set` with flags like `--recommended`, `--binary`, or `--tar` to install, update, or replace the default guest kernel that boots lightweight Linux VMs in the Apple Container system.**

The Apple Container system stores a guest kernel configuration in [`config.toml`](https://github.com/apple/container/blob/main/config.toml) under the `[kernel]` table to define which Linux image boots the lightweight VMs. While the runtime automatically prompts for installation when starting without a default kernel, the `container system kernel set` command provides the primary interface for managing custom kernels, supporting direct binary installation, tarball extraction, and remote downloads.

## Understanding the Kernel Configuration System

### The config.toml Schema

According to [`Sources/ContainerPersistence/ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift), the kernel configuration resides in the `[kernel]` table with two critical fields:

- **`binaryPath`**: A `String` specifying the path inside a downloaded archive to the actual kernel binary (default: `"opt/kata/share/kata-containers/vmlinux-6.18.15-186"`).
- **`url`**: A `URL` pointing to the remote archive for automatic downloads (default: `"https://github.com/kata-containers/kata-containers/releases/download/3.28.0/kata-static-3.28.0-arm64.tar.zst"`).

### Default Kernel Behavior

When you execute `container system start`, the runtime checks for a default kernel matching the host architecture. If absent, the system prompts you to install one. The default kernel is stored under `<app-root>/kernels/` with a symbolic link named `default.kernel-<arch>` pointing to the active binary, as implemented in [`Sources/Services/ContainerAPIService/Server/Kernel/KernelService.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Server/Kernel/KernelService.swift).

## Installing Kernels with `container system kernel set`

The command implementation in [`Sources/ContainerCommands/System/Kernel/KernelSet.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/System/Kernel/KernelSet.swift) supports three distinct usage patterns for kernel installation.

### Install the Recommended Kernel

To download and install the kernel defined in the current [`config.toml`](https://github.com/apple/container/blob/main/config.toml) `url` field, use the `--recommended` flag:

```bash
container system kernel set --recommended

```

This extracts the binary from the remote archive using the configured `binaryPath` and establishes it as the default for the host architecture.

### Install a Custom Binary Path

For kernels already compiled and available on local disk, specify the path directly with `--binary`:

```bash
container system kernel set --binary /path/to/vmlinux

```

This bypasses the download logic and installs the specified raw kernel image immediately.

### Install from a Tar Archive

When the kernel resides inside a tarball, combine `--tar` with `--binary` to specify both the archive location and the internal path to the kernel.

Local tarball:

```bash
container system kernel set \
    --binary vmlinux \
    --tar /tmp/kata-static-3.28.0-arm64.tar

```

Remote tarball:

```bash
container system kernel set \
    --binary vmlinux \
    --tar https://example.com/kata-static.tar.zst \
    --force

```

## Architecture Selection and Force Installation

The command accepts `--arch <arch>` to target specific architectures (`amd64` or `arm64`), which internally resolves to `SystemPlatform` values (`.linuxArm` or `.linuxAmd`). This is essential on multi-arch hosts or when cross-installing kernels.

Use `--force` to overwrite existing kernels with the same name:

```bash
container system kernel set \
    --arch amd64 \
    --binary /tmp/vmlinux-amd64 \
    --force

```

## Internal Implementation Details

### Client to Server Flow

The [`KernelSet.swift`](https://github.com/apple/container/blob/main/KernelSet.swift) implementation resolves the architecture flag and forwards requests to the `ClientKernel` API. Helper functions like `setKernelFromBinary`, `setKernelFromTar`, and `downloadAndInstallWithProgressBar` handle the different input types before communicating with the server-side `KernelService`.

### Storage Structure and Symbolic Links

As defined in [`KernelService.swift`](https://github.com/apple/container/blob/main/KernelService.swift) (lines 34-70), the server stores kernel files under `<app-root>/kernels/` and creates a symbolic link named `default.kernel-<arch>` to mark the active kernel. The service also updates [`config.toml`](https://github.com/apple/container/blob/main/config.toml) to ensure subsequent runtime invocations automatically use the new kernel.

## Verifying the Active Kernel

After installation, confirm the current configuration using:

```bash
container system config get kernel

```

This displays the active `binaryPath` and `url` values, verifying that `container system kernel set` successfully updated the default kernel for the chosen architecture.

## Summary

- The `[kernel]` table in [`config.toml`](https://github.com/apple/container/blob/main/config.toml) defines the default `binaryPath` and `url` for guest kernels.
- **`container system kernel set`** is the unified command for installing, updating, or replacing kernels.
- Use **`--recommended`** to install the official kernel from the configured remote URL.
- Use **`--binary`** for direct installation of local kernel images.
- Combine **`--tar`** and **`--binary`** to extract kernels from local or remote archives.
- The **`--arch`** flag supports `amd64` and `arm64`, while **`--force`** overwrites existing installations.
- Kernel files reside in `<app-root>/kernels/` with `default.kernel-<arch>` symlinks managed by [`KernelService.swift`](https://github.com/apple/container/blob/main/KernelService.swift).

## Frequently Asked Questions

### What is the default kernel path in the configuration?

The default `binaryPath` in [`config.toml`](https://github.com/apple/container/blob/main/config.toml) points to `"opt/kata/share/kata-containers/vmlinux-6.18.15-186"` inside the downloaded archive. This path is defined in [`Sources/ContainerPersistence/ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift) and represents the location of the kernel binary after extraction.

### How do I overwrite an existing kernel installation?

Append the `--force` flag to any `container system kernel set` command. This instructs the `KernelService` to replace the existing kernel for the specified architecture, updating both the stored file and the `default.kernel-<arch>` symbolic link.

### Can I install a kernel for a different architecture than my host?

Yes. Use the `--arch` flag with `amd64` or `arm64` to specify the target architecture. The command resolves these values to `SystemPlatform` enums (`.linuxAmd` or `.linuxArm`) and stores the kernel appropriately, though ensure the binary matches the target architecture to avoid boot failures.

### Where are kernel files stored on disk?

The system stores kernels under `<app-root>/kernels/` and creates symbolic links named `default.kernel-<arch>` to identify the active default kernel. This storage mechanism is implemented in [`Sources/Services/ContainerAPIService/Server/Kernel/KernelService.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Server/Kernel/KernelService.swift).