Skip to content

Commit a722522

Browse files
authored
Merge pull request #289 from spinframework/add-systemd-cgroup
feat: add SystemCgroup option to containerd runtime options
2 parents a9c8e24 + d0fa28a commit a722522

File tree

9 files changed

+126
-8
lines changed

9 files changed

+126
-8
lines changed

.github/workflows/action-node-installer.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,15 @@ jobs:
101101
if: matrix.distribution == 'k3s' && failure()
102102
run: |
103103
sudo k3s kubectl describe pods -n kwasm
104+
sudo k3s kubectl logs k3s-provision-kwasm-dev -n kwasm
104105
sudo k3s kubectl describe pods
106+
107+
- name: Collect minikube debug logs
108+
if: matrix.distribution == 'minikube' && failure()
109+
run: |
110+
kubectl describe pods -n kwasm
111+
kubectl logs minikube-provision-kwasm-dev -n kwasm
112+
kubectl describe pods
105113
106114
publish:
107115
needs: build-and-test

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,18 @@ To carry out the installation step-by-step, do the following:
6666

6767
```toml
6868
[plugins."io.containerd.cri.v1.runtime".containerd.runtimes.spin]
69-
runtime_type = "io.containerd.spin.v2"
69+
runtime_type = "io.containerd.spin.v2"
70+
[plugins."io.containerd.cri.v1.runtime".containerd.runtimes.spin.options]
71+
SystemdCgroup = true
7072
```
7173

7274
Otherwise, add:
7375

7476
```toml
7577
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.spin]
76-
runtime_type = "io.containerd.spin.v2"
78+
runtime_type = "io.containerd.spin.v2"
79+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.spin.options]
80+
SystemdCgroup = true
7781
```
7882

7983
The [Node Installer script](./node-installer/script/installer.sh) that is used by the [`runtime-class-manager`](https://www.spinkube.dev/docs/topics/architecture/#runtime-class-manager) does this for you and is a good reference to understand the common paths to the containerd configuration file for popular Kubernetes distributions.

conformance-tests/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ Containerd must be configured to access the `containerd-shim-spin`:
1919
```toml
2020
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.spin]
2121
runtime_type = "/usr/bin/containerd-shim-spin-v2"
22+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.spin.options]
23+
SystemdCgroup = true
2224
```
2325
3. Restart containerd if it is running as a service
2426
```sh

node-installer/script/installer.sh

100644100755
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ IS_MICROK8S=false
1111
IS_K3S=false
1212
IS_RKE2_AGENT=false
1313
IS_K0S_WORKER=false
14+
1415
if pgrep -f snap/microk8s > /dev/null; then
1516
CONTAINERD_CONF=/var/snap/microk8s/current/args/containerd-template.toml
1617
IS_MICROK8S=true
@@ -34,11 +35,40 @@ elif pgrep -f /var/lib/k0s/bin/kubelet > /dev/null; then
3435
touch $NODE_ROOT$CONTAINERD_CONF
3536
fi
3637

38+
# If SYSTEMD_CGROUP is not set, default to true except for distros that do not default to systemd
39+
# TODO: detect k3d which defaults to cgroupfs
40+
if [ -z "${SYSTEMD_CGROUP+x}" ] && [ "$IS_MICROK8S" = "true" ]; then
41+
SYSTEMD_CGROUP=false
42+
else
43+
: "${SYSTEMD_CGROUP:=true}"
44+
fi
45+
46+
# Install D-Bus if it's not available but systemd cgroups are requested
47+
if [ "$SYSTEMD_CGROUP" = "true" ]; then
48+
if ! nsenter -m/$NODE_ROOT/proc/1/ns/mnt -- which dbus-daemon >/dev/null 2>&1; then
49+
if nsenter -m/$NODE_ROOT/proc/1/ns/mnt -- which apt-get >/dev/null 2>&1; then
50+
nsenter -m/$NODE_ROOT/proc/1/ns/mnt -- apt-get update -y
51+
nsenter -m/$NODE_ROOT/proc/1/ns/mnt -- apt-get install -y dbus
52+
elif nsenter -m/$NODE_ROOT/proc/1/ns/mnt -- which yum >/dev/null 2>&1; then
53+
nsenter -m/$NODE_ROOT/proc/1/ns/mnt -- yum install -y dbus
54+
elif nsenter -m/$NODE_ROOT/proc/1/ns/mnt -- which dnf >/dev/null 2>&1; then
55+
nsenter -m/$NODE_ROOT/proc/1/ns/mnt -- dnf install -y dbus
56+
elif nsenter -m/$NODE_ROOT/proc/1/ns/mnt -- which apk >/dev/null 2>&1; then
57+
nsenter -m/$NODE_ROOT/proc/1/ns/mnt -- apk add dbus
58+
else
59+
echo "WARNING: Could not install D-Bus. No supported package manager found."
60+
SYSTEMD_CGROUP=false
61+
echo "SYSTEMD_CGROUP is now set to $SYSTEMD_CGROUP"
62+
fi
63+
fi
64+
fi
65+
3766
mkdir -p $NODE_ROOT$KWASM_DIR/bin/
3867

3968
cp /assets/containerd-shim-spin-v2 $NODE_ROOT$KWASM_DIR/bin/
4069

4170
if ! grep -q spin $NODE_ROOT$CONTAINERD_CONF; then
71+
echo "Adding Spin runtime to containerd"
4272
if $IS_K3S; then
4373
echo '
4474
[plugins."io.containerd.cri.v1.runtime".containerd.runtimes."spin"]
@@ -53,12 +83,36 @@ if ! grep -q spin $NODE_ROOT$CONTAINERD_CONF; then
5383
rm -Rf $NODE_ROOT$KWASM_DIR/active
5484
fi
5585

86+
# Configure Spin runtime options if using systemd cgroups and no options are configured
87+
# TODO: this should allow for some options to already be configured and just additively
88+
# configure SystemdCgroup
89+
if ! grep -q 'runtimes.spin.options' $NODE_ROOT$CONTAINERD_CONF && [ "$SYSTEMD_CGROUP" = "true" ]; then
90+
echo "Setting SystemdCgroup to $SYSTEMD_CGROUP in Spin containerd configuration"
91+
if $IS_K3S; then
92+
echo '
93+
[plugins."io.containerd.cri.v1.runtime".containerd.runtimes.spin.options]
94+
SystemdCgroup = '$SYSTEMD_CGROUP'
95+
' >> $NODE_ROOT$CONTAINERD_CONF
96+
else
97+
echo '
98+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.spin.options]
99+
SystemdCgroup = '$SYSTEMD_CGROUP'
100+
' >> $NODE_ROOT$CONTAINERD_CONF
101+
fi
102+
fi
103+
56104
if $IS_K3S; then
57105
sed -i "s|runtime_type = \"io.containerd.spin.*\"|runtime_type = \"$KWASM_DIR/bin/containerd-shim-spin-v2\"|g" $NODE_ROOT$CONTAINERD_CONF
58106
fi
59107

60108
if [ ! -f $NODE_ROOT$KWASM_DIR/active ]; then
61109
touch $NODE_ROOT$KWASM_DIR/active
110+
111+
# Ensure D-Bus is running before restarting services if using systemd cgroups
112+
if [ "$SYSTEMD_CGROUP" = "true" ]; then
113+
nsenter -m/$NODE_ROOT/proc/1/ns/mnt -- systemctl restart dbus
114+
fi
115+
62116
if $IS_MICROK8S; then
63117
nsenter -m/$NODE_ROOT/proc/1/ns/mnt -- systemctl restart snap.microk8s.daemon-containerd
64118
elif $IS_K3S; then
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
FROM gcr.io/k8s-minikube/kicbase:v0.0.46@sha256:fd2d445ddcc33ebc5c6b68a17e6219ea207ce63c005095ea1525296da2d1a279
2+
3+
RUN apt-get update -y || true && \
4+
apt-get -y install wget curl apt-transport-https ca-certificates gnupg2 && \
5+
6+
# Remove existing repository configurations to avoid conflicts
7+
rm -f /etc/apt/sources.list.d/devel:kubic:*.list && \
8+
9+
mkdir -p /etc/apt/keyrings && \
10+
curl -fsSL "https://downloadcontent.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_22.04/Release.key" | gpg --dearmor > /etc/apt/keyrings/libcontainers-stable.gpg && \
11+
curl -fsSL "https://downloadcontent.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/1.24/xUbuntu_22.04/Release.key" | gpg --dearmor > /etc/apt/keyrings/crio-stable.gpg && \
12+
echo "deb [signed-by=/etc/apt/keyrings/libcontainers-stable.gpg] https://downloadcontent.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_22.04/ /" > /etc/apt/sources.list.d/devel-kubic-libcontainers-stable.list && \
13+
echo "deb [signed-by=/etc/apt/keyrings/crio-stable.gpg] https://downloadcontent.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/1.24/xUbuntu_22.04/ /" > /etc/apt/sources.list.d/devel-kubic-libcontainers-crio-stable.list && \
14+
apt-get update -y || true

node-installer/tests/integration-test-k3s.sh

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,16 @@ echo "Applying KWasm node installer job..."
5151
kubectl apply -f ./k3s-kwasm-job.yml
5252

5353
echo "Waiting for node installer job to complete..."
54-
kubectl wait -n kwasm --for=condition=Ready pod --selector=job-name=k3s-provision-kwasm --timeout=90s || true
5554
kubectl wait -n kwasm --for=jsonpath='{.status.phase}'=Succeeded pod --selector=job-name=k3s-provision-kwasm --timeout=60s
5655

56+
# Verify the SystemdCgroup is set to true
57+
if sudo cat /var/lib/rancher/k3s/agent/etc/containerd/config.toml | grep -A2 "runtimes.spin.options" | grep -q "SystemdCgroup = true"; then
58+
echo "SystemdCgroup is set to true"
59+
else
60+
echo "SystemdCgroup is not set to true"
61+
exit 1
62+
fi
63+
5764
if ! kubectl get pods -n kwasm | grep -q "k3s-provision-kwasm.*Completed"; then
5865
echo "Node installer job failed!"
5966
kubectl logs -n kwasm $(kubectl get pods -n kwasm -o name | grep k3s-provision-kwasm)

node-installer/tests/integration-test-kind.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ echo "Waiting for node installer job to complete..."
5555
kubectl --context=kind-spin-test wait -n kwasm --for=condition=Ready pod --selector=job-name=spin-test-control-plane-provision-kwasm --timeout=90s || true
5656
kubectl --context=kind-spin-test wait -n kwasm --for=jsonpath='{.status.phase}'=Succeeded pod --selector=job-name=spin-test-control-plane-provision-kwasm --timeout=60s
5757

58+
# Verify the SystemdCgroup is set to true
59+
if docker exec spin-test-control-plane cat /etc/containerd/config.toml | grep -A5 "spin" | grep -q "SystemdCgroup = true"; then
60+
echo "SystemdCgroup is set to true"
61+
else
62+
echo "SystemdCgroup is not set to true"
63+
exit 1
64+
fi
65+
5866
if ! kubectl --context=kind-spin-test get pods -n kwasm | grep -q "spin-test-control-plane-provision-kwasm.*Completed"; then
5967
echo "Node installer job failed!"
6068
kubectl --context=kind-spin-test logs -n kwasm $(kubectl --context=kind-spin-test get pods -n kwasm -o name | grep spin-test-control-plane-provision-kwasm)

node-installer/tests/integration-test-microk8s.sh

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/bin/bash
22
set -euo pipefail
3+
shopt -s expand_aliases
34

45
: ${IMAGE_NAME:=ghcr.io/spinkube/containerd-shim-spin/node-installer:dev}
56

@@ -12,12 +13,12 @@ fi
1213
if ! microk8s status | grep -q "microk8s is running"; then
1314
echo "Starting MicroK8s..."
1415
sudo microk8s start
15-
sleep 10
1616
else
1717
sudo microk8s reset
18-
sleep 10
1918
fi
2019

20+
sudo microk8s status --wait-ready
21+
2122
sudo microk8s enable dns
2223

2324
alias kubectl='sudo microk8s kubectl'
@@ -59,9 +60,16 @@ echo "Applying KWasm node installer job..."
5960
kubectl apply -f ./microk8s-kwasm-job.yml
6061

6162
echo "Waiting for node installer job to complete..."
62-
kubectl wait -n kwasm --for=condition=Ready pod --selector=job-name=microk8s-provision-kwasm --timeout=90s || true
6363
kubectl wait -n kwasm --for=jsonpath='{.status.phase}'=Succeeded pod --selector=job-name=microk8s-provision-kwasm --timeout=60s
6464

65+
# Ensure the SystemdCgroup is not set to true
66+
if sudo cat /var/snap/microk8s/current/args/containerd.toml | grep -A5 "spin" | grep -q "SystemdCgroup = true"; then
67+
echo "Failed: SystemdCgroup is set to true"
68+
exit 1
69+
else
70+
echo "Passed: SystemdCgroup is not set to true"
71+
fi
72+
6573
if ! kubectl get pods -n kwasm | grep -q "microk8s-provision-kwasm.*Completed"; then
6674
echo "Node installer job failed!"
6775
kubectl logs -n kwasm $(kubectl get pods -n kwasm -o name | grep microk8s-provision-kwasm)
@@ -72,7 +80,11 @@ echo "=== Step 4: Apply the workload ==="
7280
kubectl apply -f ./tests/workloads/workload.yaml
7381

7482
echo "Waiting for deployment to be ready..."
75-
kubectl wait --for=condition=Available deployment/wasm-spin --timeout=120s
83+
if ! kubectl wait --for=condition=Available deployment/wasm-spin --timeout=120s; then
84+
echo "Deployment failed to become ready!"
85+
kubectl describe deployment wasm-spin
86+
exit 1
87+
fi
7688

7789
echo "Checking pod status..."
7890
kubectl get pods

node-installer/tests/integration-test-minikube.sh

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ set -euo pipefail
44
: ${IMAGE_NAME:=ghcr.io/spinkube/containerd-shim-spin/node-installer:dev}
55

66
echo "=== Step 1: Create a MiniKube cluster ==="
7-
minikube start -p minikube --driver=docker --container-runtime=containerd
7+
docker build -t minikube-custom:v0.0.46-fixed -f ./tests/Dockerfile.minikube-custom .
8+
minikube start -p minikube --driver=docker --container-runtime=containerd --base-image="minikube-custom:v0.0.46-fixed"
89

910
echo "=== Step 2: Create namespace and deploy RuntimeClass ==="
1011
kubectl create namespace kwasm || true
@@ -44,6 +45,14 @@ echo "Waiting for node installer job to complete..."
4445
kubectl wait -n kwasm --for=condition=Ready pod --selector=job-name=minikube-provision-kwasm --timeout=90s || true
4546
kubectl wait -n kwasm --for=jsonpath='{.status.phase}'=Succeeded pod --selector=job-name=minikube-provision-kwasm --timeout=60s
4647

48+
# Verify the SystemdCgroup is set to true
49+
if docker exec $NODE_NAME cat /etc/containerd/config.toml | grep -A5 "spin" | grep -q "SystemdCgroup = true"; then
50+
echo "SystemdCgroup is set to true"
51+
else
52+
echo "SystemdCgroup is not set to true"
53+
exit 1
54+
fi
55+
4756
if ! kubectl get pods -n kwasm | grep -q "minikube-provision-kwasm.*Completed"; then
4857
echo "Node installer job failed!"
4958
kubectl logs -n kwasm $(kubectl get pods -n kwasm -o name | grep minikube-provision-kwasm)

0 commit comments

Comments
 (0)