Skip to content

Commit a158889

Browse files
committed
Enhance SandboxFleet to support Kata runtime
- Updated README to include instructions for building and deploying with Kata runtime. - Added e2e workflow for testing Kata runtime, including setup for KVM device permissions. - Modified CRI runtime configuration to support host devices, allowing for nested virtualization. - Updated API definitions and validation rules to include host devices in SandboxPool. - Enhanced StatefulSetBuilder to mount host devices in Worker Pods. - Added tests to validate the integration of Kata runtime and host device mounting functionality.
1 parent fcd97fd commit a158889

23 files changed

Lines changed: 827 additions & 26 deletions

.github/workflows/e2e.yaml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,70 @@ jobs:
4343

4444
- name: Run e2e tests
4545
run: ./hack/verify-e2e.sh
46+
47+
e2e-kata:
48+
runs-on: ubuntu-latest
49+
timeout-minutes: 60
50+
steps:
51+
- name: Check out repository
52+
uses: actions/checkout@v4
53+
54+
- name: Set up Go
55+
uses: actions/setup-go@v5
56+
with:
57+
go-version-file: go.mod
58+
59+
- name: Free disk space
60+
run: |
61+
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
62+
df -h /
63+
64+
- name: Enable KVM device permissions
65+
id: kvm
66+
run: |
67+
if [[ ! -e /dev/kvm ]]; then
68+
echo "available=false" >> "$GITHUB_OUTPUT"
69+
echo "/dev/kvm missing; skipping nested-virt e2e"
70+
exit 0
71+
fi
72+
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \
73+
| sudo tee /etc/udev/rules.d/99-kvm4all.rules
74+
sudo udevadm control --reload-rules
75+
sudo udevadm trigger --name-match=kvm
76+
if ! docker run --rm --device /dev/kvm busybox true; then
77+
echo "available=false" >> "$GITHUB_OUTPUT"
78+
echo "/dev/kvm not usable from Docker; skipping"
79+
exit 0
80+
fi
81+
echo "available=true" >> "$GITHUB_OUTPUT"
82+
83+
- name: Install kind
84+
if: steps.kvm.outputs.available == 'true'
85+
run: |
86+
curl -fsSL -o ./kind "https://kind.sigs.k8s.io/dl/v0.27.0/kind-linux-amd64"
87+
chmod +x ./kind
88+
sudo mv ./kind /usr/local/bin/kind
89+
kind version
90+
91+
- name: Install kubectl
92+
if: steps.kvm.outputs.available == 'true'
93+
run: |
94+
curl -fsSL -o ./kubectl "https://dl.k8s.io/release/$(curl -fsSL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
95+
chmod +x ./kubectl
96+
sudo mv ./kubectl /usr/local/bin/kubectl
97+
kubectl version --client
98+
99+
- name: Deploy SandboxFleet (kata)
100+
if: steps.kvm.outputs.available == 'true'
101+
env:
102+
WORKER_RUNTIME: kata
103+
APPLY_SAMPLES: "0"
104+
CLUSTER_NAME: sandboxfleet-kata
105+
ENSURE_NESTED_VIRT: "1"
106+
run: ./hack/deploy-kind.sh
107+
108+
- name: Run e2e tests (kata)
109+
if: steps.kvm.outputs.available == 'true'
110+
env:
111+
CLUSTER_NAME: sandboxfleet-kata
112+
run: ./hack/verify-e2e.sh

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@ Optional cleanup:
4242
- `deploy-kind.sh` writes kubeconfig to `bin/KUBECONFIG` and runtime selection to
4343
`bin/runtime.env` (used by `verify-e2e.sh`).
4444
- `WORKER_RUNTIME` selects which Worker image to build and load (`gvisor` default,
45-
or `runc`). Example: `WORKER_RUNTIME=runc ./hack/deploy-kind.sh` builds only the
46-
base image and sets `runtimeHandler=runc`.
45+
`runc`, or `kata`). It only picks image + `runtimeHandler` (+ optional sample
46+
`hostDevices`). Nested virt is handled by `hack/ensure-kind-cluster.sh` via
47+
`ENSURE_NESTED_VIRT=auto|1|0` (independent of runtime name).
48+
Kata pools declare `spec.runtime.cri.hostDevices: ["/dev/kvm"]`.
4749
- `APPLY_SAMPLES=1` (default) also applies demo Pool/Sandbox manifests; e2e uses
4850
its own namespace and does not depend on those samples.
4951
- `APPLY_SAMPLES=0 ./hack/deploy-kind.sh` installs only the control plane.
5052
- Re-run tests later without rebuilding: `./hack/verify-e2e.sh`
51-
- Build Worker images alone: `./hack/build-worker-images.sh runc|gvisor|all`
53+
- Build Worker images alone: `./hack/build-worker-images.sh runc|gvisor|kata|all`

api/v1alpha1/sandboxpool_types.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,21 @@ const RuntimeBackendCRI RuntimeBackend = "cri"
1111

1212
type CRIRuntimeConfig struct {
1313
// RuntimeHandler is the CRI runtime handler name configured in the Worker's
14-
// containerd. It is an opaque string (for example "runsc" or "runc");
14+
// containerd. It is an opaque string (for example "runsc", "runc", or "kata");
1515
// SandboxFleet does not interpret runtime-specific values.
1616
// +kubebuilder:validation:MinLength=1
1717
// +kubebuilder:validation:MaxLength=253
1818
RuntimeHandler string `json:"runtimeHandler"`
19+
20+
// HostDevices lists host paths to mount into every Worker Pod for this Pool
21+
// (for example "/dev/kvm"). Runtime-agnostic: the controller mounts whatever
22+
// is declared here and does not special-case handler names.
23+
// +optional
24+
// +listType=set
25+
// +kubebuilder:validation:MaxItems=16
26+
// +kubebuilder:validation:items:MinLength=1
27+
// +kubebuilder:validation:items:MaxLength=256
28+
HostDevices []string `json:"hostDevices,omitempty"`
1929
}
2030

2131
// +kubebuilder:validation:XValidation:rule="self.backend != 'cri' || has(self.cri)",message="cri configuration is required for the cri backend"

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/runtimes/kata/Dockerfile

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# syntax=docker/dockerfile:1.7
2+
3+
# Kata Worker image: generic CRI base + kata-containers (Cloud Hypervisor).
4+
# Control-plane code stays runtime-agnostic; only this image knows about Kata.
5+
6+
ARG BASE_IMAGE=sandboxfleet-worker-base:latest
7+
ARG KATA_VERSION=4.0.0
8+
9+
FROM ${BASE_IMAGE}
10+
ARG TARGETARCH
11+
ARG KATA_VERSION
12+
13+
RUN apt-get update \
14+
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
15+
zstd \
16+
&& rm -rf /var/lib/apt/lists/*
17+
18+
RUN case "${TARGETARCH}" in \
19+
amd64) ARCH=amd64 ;; \
20+
arm64) ARCH=arm64 ;; \
21+
*) echo "unsupported TARGETARCH=${TARGETARCH}" >&2; exit 1 ;; \
22+
esac \
23+
&& curl -fsSL -o /tmp/kata-static.tar.zst \
24+
"https://github.com/kata-containers/kata-containers/releases/download/${KATA_VERSION}/kata-static-${KATA_VERSION}-${ARCH}.tar.zst" \
25+
&& mkdir -p /tmp/kata-extract \
26+
&& tar --zstd -xf /tmp/kata-static.tar.zst -C /tmp/kata-extract \
27+
&& cp -a /tmp/kata-extract/opt/kata /opt/kata \
28+
&& ln -sf /opt/kata/bin/containerd-shim-kata-v2 /usr/local/bin/containerd-shim-kata-v2 \
29+
&& ln -sf /opt/kata/bin/kata-runtime /usr/local/bin/kata-runtime \
30+
&& test -x /opt/kata/bin/cloud-hypervisor \
31+
&& test -f /opt/kata/share/defaults/kata-containers/configuration-clh.toml \
32+
&& rm -rf /tmp/kata-static.tar.zst /tmp/kata-extract
33+
34+
COPY build/runtimes/kata/containerd.toml /etc/containerd/config.toml
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Local containerd config for the Kata Worker image (Cloud Hypervisor VMM).
2+
# Registers opaque CRI handler name "kata" used by SandboxPool.spec.runtime.cri.runtimeHandler.
3+
4+
version = 2
5+
root = "/var/lib/containerd"
6+
state = "/run/containerd"
7+
8+
[grpc]
9+
address = "/run/containerd/containerd.sock"
10+
11+
[plugins."io.containerd.grpc.v1.cri"]
12+
sandbox_image = "registry.k8s.io/pause:3.10"
13+
14+
[plugins."io.containerd.grpc.v1.cri".cni]
15+
bin_dir = "/opt/cni/bin"
16+
conf_dir = "/etc/cni/net.d"
17+
18+
[plugins."io.containerd.grpc.v1.cri".containerd]
19+
default_runtime_name = "runc"
20+
21+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
22+
runtime_type = "io.containerd.runc.v2"
23+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
24+
SystemdCgroup = false
25+
26+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata]
27+
runtime_type = "io.containerd.kata.v2"
28+
privileged_without_host_devices = true
29+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata.options]
30+
ConfigPath = "/opt/kata/share/defaults/kata-containers/configuration-clh.toml"

config/crd/sandboxpools.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,15 @@ spec:
6464
type: string
6565
minLength: 1
6666
maxLength: 253
67+
hostDevices:
68+
type: array
69+
maxItems: 16
70+
uniqueItems: true
71+
items:
72+
type: string
73+
minLength: 1
74+
maxLength: 256
75+
description: Host paths mounted into every Worker Pod (for example /dev/kvm).
6776
x-kubernetes-validations:
6877
- rule: "self.backend != 'cri' || has(self.cri)"
6978
message: cri configuration is required for the cri backend
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Sample Pool for Kata Worker image (WORKER_RUNTIME=kata).
2+
# Requires /dev/kvm on the node (see hack/ensure-kind-cluster.sh).
3+
apiVersion: sandboxfleet.io/v1alpha1
4+
kind: SandboxPool
5+
metadata:
6+
name: demo
7+
namespace: default
8+
spec:
9+
runtime:
10+
backend: cri
11+
cri:
12+
runtimeHandler: kata
13+
hostDevices:
14+
- /dev/kvm
15+
slotProfiles:
16+
- name: default
17+
resources:
18+
requests:
19+
cpu: 100m
20+
memory: 128Mi
21+
limits:
22+
cpu: 100m
23+
memory: 128Mi
24+
workerTemplates:
25+
- name: mixed
26+
replicas: 1
27+
slots:
28+
- profile: default
29+
count: 2
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Sample Pool for runc Worker image (WORKER_RUNTIME=runc).
2+
apiVersion: sandboxfleet.io/v1alpha1
3+
kind: SandboxPool
4+
metadata:
5+
name: demo
6+
namespace: default
7+
spec:
8+
runtime:
9+
backend: cri
10+
cri:
11+
runtimeHandler: runc
12+
slotProfiles:
13+
- name: default
14+
resources:
15+
requests:
16+
cpu: 100m
17+
memory: 128Mi
18+
limits:
19+
cpu: 100m
20+
memory: 128Mi
21+
workerTemplates:
22+
- name: mixed
23+
replicas: 1
24+
slots:
25+
- profile: default
26+
count: 2

config/samples/sandboxpool.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Default sample Pool (gVisor / runsc).
2+
# Other runtimes: sandboxpool-runc.yaml, sandboxpool-kata.yaml
13
apiVersion: sandboxfleet.io/v1alpha1
24
kind: SandboxPool
35
metadata:

0 commit comments

Comments
 (0)