Skip to content

Commit 3fcf647

Browse files
authored
Add virtualization support for containers (apple#377)
1 parent 728527b commit 3fcf647

File tree

6 files changed

+42
-1
lines changed

6 files changed

+42
-1
lines changed

Package.resolved

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/ContainerClient/Core/ContainerConfiguration.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public struct ContainerConfiguration: Sendable, Codable {
4747
public var resources: Resources = .init()
4848
/// Name of the runtime that supports the container
4949
public var runtimeHandler: String = "container-runtime-linux"
50+
/// Configure exposing virtualization support in the container.
51+
public var virtualization: Bool = false
5052

5153
enum CodingKeys: String, CodingKey {
5254
case id
@@ -64,6 +66,7 @@ public struct ContainerConfiguration: Sendable, Codable {
6466
case platform
6567
case resources
6668
case runtimeHandler
69+
case virtualization
6770
}
6871

6972
/// Create a configuration from the supplied Decoder, initializing missing
@@ -86,6 +89,7 @@ public struct ContainerConfiguration: Sendable, Codable {
8689
platform = try container.decodeIfPresent(ContainerizationOCI.Platform.self, forKey: .platform) ?? .current
8790
resources = try container.decodeIfPresent(Resources.self, forKey: .resources) ?? .init()
8891
runtimeHandler = try container.decodeIfPresent(String.self, forKey: .runtimeHandler) ?? "container-runtime-linux"
92+
virtualization = try container.decodeIfPresent(Bool.self, forKey: .virtualization) ?? false
8993
}
9094

9195
public struct DNSConfiguration: Sendable, Codable {

Sources/ContainerClient/Flags.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,13 @@ public struct Flags {
148148

149149
@Option(name: [.customLong("label"), .short], help: "Add a key=value label to the container")
150150
public var labels: [String] = []
151+
152+
@Flag(
153+
name: [.customLong("virtualization")],
154+
help:
155+
"Expose virtualization capabilities to the container. (Host must have nested virtualization support, and guest kernel must have virtualization capabilities enabled)"
156+
)
157+
public var virtualization: Bool = false
151158
}
152159

153160
public struct Progress: ParsableArguments {

Sources/ContainerClient/Utility.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ public struct Utility {
150150
mounts.append(contentsOf: volumes)
151151
config.mounts = mounts
152152

153+
config.virtualization = management.virtualization
154+
153155
if management.networks.isEmpty {
154156
config.networks = [ClientNetwork.defaultNetworkName]
155157
} else {

Sources/Services/ContainerSandboxService/SandboxService.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,8 @@ public actor SandboxService {
696696
czConfig.sysctl = config.sysctls.reduce(into: [String: String]()) {
697697
$0[$1.key] = $1.value
698698
}
699+
// If the host doesn't support this, we'll throw on container creation.
700+
czConfig.virtualization = config.virtualization
699701

700702
for mount in config.mounts {
701703
if try mount.isSocket() {

docs/how-to.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,32 @@ Use the `--boot` option to see the logs for the virtual machine boot and init pr
286286
%
287287
</pre>
288288

289+
## Expose virtualization capabilities to a container
290+
291+
> [!NOTE]
292+
> This feature requires a M3 or newer Apple silicon machine and a Linux kernel that supports virtualization. For a kernel configuration that has all of the right features enabled, see https://github.com/apple/containerization/blob/0.5.0/kernel/config-arm64#L602.
293+
294+
You can enable virtualization capabilities in containers by using the `--virtualization` option of `container run` and `container create`.
295+
296+
If your machine does not have support for nested virtualization, you will see the following:
297+
298+
```console
299+
container run --name nested-virtualization --virtualization --kernel /path/to/a/kernel/with/virtualization/support --rm ubuntu:latest sh -c "dmesg | grep kvm"
300+
Error: unsupported: "nested virtualization is not supported on the platform"
301+
```
302+
303+
When nested virtualization is enabled successfully, `dmesg` will show output like the following:
304+
305+
```console
306+
container run --name nested-virtualization --virtualization --kernel /path/to/a/kernel/with/virtualization/support --rm ubuntu:latest sh -c "dmesg | grep kvm"
307+
[ 0.017245] kvm [1]: IPA Size Limit: 40 bits
308+
[ 0.017499] kvm [1]: GICv3: no GICV resource entry
309+
[ 0.017501] kvm [1]: disabling GICv2 emulation
310+
[ 0.017506] kvm [1]: GIC system register CPU interface enabled
311+
[ 0.017685] kvm [1]: vgic interrupt IRQ9
312+
[ 0.017893] kvm [1]: Hyp mode initialized successfully
313+
```
314+
289315
## Configure container defaults
290316

291317
`container` uses macOS user defaults to store configuration settings that persist between sessions. You can customize various aspects of container behavior, including build settings, default images, and network configuration.

0 commit comments

Comments
 (0)