diff --git a/docs/content/reference/agent/nspawn.md b/docs/content/reference/agent/nspawn.md index 74becdafa..dccf6a427 100644 --- a/docs/content/reference/agent/nspawn.md +++ b/docs/content/reference/agent/nspawn.md @@ -175,7 +175,9 @@ The configuration is written to two files on the host before the machine boots: | bpffs `ExecStartPre=` mount commands | Service override | Creates and mounts the machine-scoped host bpffs before the machine starts. | | `SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=1` | Service override | Forces cgroups v2 inside the container. | | `SYSTEMD_NSPAWN_API_VFS_WRITABLE=network` | Service override | Makes `/proc/sys/net` writable for CNI and kube-proxy. | +| `DeviceAllow=char-ipvtap rwm` / `DeviceAllow=char-macvtap rwm` | Service override | Allows network tooling inside the node to create and use ipvtap and macvtap devices. | | `Bind=/dev/kvm` | nspawn config | KVM device bind-mount (auto-generated when `/dev/kvm` is present). | +| `Bind=/dev/net/tun` / `DeviceAllow=/dev/net/tun rwm` | Both | Exposes the generic TUN/TAP device when it is present on the host. | | `Bind=` | nspawn config | Storage block device bind-mount (auto-generated for non-virtual `/sys/class/block` entries, including partitions, `dm-*`, and `md*`). | | `Bind=/dev/infiniband/*` | nspawn config | InfiniBand HCA device bind-mount (auto-generated when `/dev/infiniband` devices are present). | | `Bind=` | nspawn config | Additional host device bind-mount (configured with agent config `AdditionalHostDevices`). | diff --git a/pkg/agent/phases/rootfs/assets/service-override.conf b/pkg/agent/phases/rootfs/assets/service-override.conf index 54e468524..4ae633223 100644 --- a/pkg/agent/phases/rootfs/assets/service-override.conf +++ b/pkg/agent/phases/rootfs/assets/service-override.conf @@ -42,6 +42,9 @@ ExecStartPre=/usr/bin/mkdir -p {{.BPFFSMountPath}} ExecStartPre=/bin/sh -c '/usr/bin/mountpoint -q {{.BPFFSMountPath}} || /usr/bin/mount -t bpf bpf {{.BPFFSMountPath}}' Environment=SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=1 Environment=SYSTEMD_NSPAWN_API_VFS_WRITABLE=network + +DeviceAllow=char-ipvtap rwm +DeviceAllow=char-macvtap rwm {{- if or .HostDevicePaths .HostDeviceGroupSpecifiers}} # Allow the container to access configured host device nodes and groups (e.g. diff --git a/pkg/agent/phases/rootfs/nspawn_render_test.go b/pkg/agent/phases/rootfs/nspawn_render_test.go index b630148e1..8dddbda5f 100644 --- a/pkg/agent/phases/rootfs/nspawn_render_test.go +++ b/pkg/agent/phases/rootfs/nspawn_render_test.go @@ -304,19 +304,24 @@ func TestPathsExcluding(t *testing.T) { require.Equal(t, []string{"/dev/kfd"}, got) } -func TestServiceOverride_NoHostDevicesNoDeviceAllow(t *testing.T) { +func TestServiceOverride_BaseDeviceAllow(t *testing.T) { t.Parallel() var buf bytes.Buffer require.NoError(t, nspawnTemplates.ExecuteTemplate(&buf, "service-override.conf", nspawnTemplateData{ MachineName: "kube1", BPFFSMountPath: goalstates.BPFFSMountPath("kube1"), - // No HostDevicePaths and no GPU devices. })) - // With no devices the drop-in must not contain any DeviceAllow lines, - // which is what keeps the existing golden snapshots unchanged. - require.NotContains(t, buf.String(), "DeviceAllow=") + out := buf.String() + + // With no detected host devices, the override must not contain direct + // device paths. This keeps the golden image unchanged while still allowing + // generic device classes that do not depend on host discovery. + require.NotContains(t, out, "DeviceAllow=/") + require.Contains(t, out, "DeviceAllow=char-ipvtap rwm") + require.Contains(t, out, "DeviceAllow=char-macvtap rwm") + require.Equal(t, 2, strings.Count(out, "DeviceAllow=")) } func nspawnRenderScenarioData() nspawnTemplateData { diff --git a/pkg/agent/phases/rootfs/testdata/render/cpu-only.service-override.conf.golden b/pkg/agent/phases/rootfs/testdata/render/cpu-only.service-override.conf.golden index db147d346..907d0e5f7 100644 --- a/pkg/agent/phases/rootfs/testdata/render/cpu-only.service-override.conf.golden +++ b/pkg/agent/phases/rootfs/testdata/render/cpu-only.service-override.conf.golden @@ -42,3 +42,6 @@ ExecStartPre=/usr/bin/mkdir -p /run/bpffs/kube1 ExecStartPre=/bin/sh -c '/usr/bin/mountpoint -q /run/bpffs/kube1 || /usr/bin/mount -t bpf bpf /run/bpffs/kube1' Environment=SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=1 Environment=SYSTEMD_NSPAWN_API_VFS_WRITABLE=network + +DeviceAllow=char-ipvtap rwm +DeviceAllow=char-macvtap rwm diff --git a/pkg/agent/phases/rootfs/testdata/render/nvidia-all-helpers.service-override.conf.golden b/pkg/agent/phases/rootfs/testdata/render/nvidia-all-helpers.service-override.conf.golden index 47281cca9..994310799 100644 --- a/pkg/agent/phases/rootfs/testdata/render/nvidia-all-helpers.service-override.conf.golden +++ b/pkg/agent/phases/rootfs/testdata/render/nvidia-all-helpers.service-override.conf.golden @@ -43,6 +43,9 @@ ExecStartPre=/bin/sh -c '/usr/bin/mountpoint -q /run/bpffs/kube1 || /usr/bin/mou Environment=SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=1 Environment=SYSTEMD_NSPAWN_API_VFS_WRITABLE=network +DeviceAllow=char-ipvtap rwm +DeviceAllow=char-macvtap rwm + # GPU support - allow the container to access NVIDIA device nodes via the # cgroup device controller. DeviceAllow grants read/write permission so that # the bind-mounted devices from the [Files] section in the .nspawn config diff --git a/pkg/agent/phases/rootfs/testdata/render/nvidia-gb300-rack-full.service-override.conf.golden b/pkg/agent/phases/rootfs/testdata/render/nvidia-gb300-rack-full.service-override.conf.golden index fa02127be..317671f89 100644 --- a/pkg/agent/phases/rootfs/testdata/render/nvidia-gb300-rack-full.service-override.conf.golden +++ b/pkg/agent/phases/rootfs/testdata/render/nvidia-gb300-rack-full.service-override.conf.golden @@ -43,6 +43,9 @@ ExecStartPre=/bin/sh -c '/usr/bin/mountpoint -q /run/bpffs/kube1 || /usr/bin/mou Environment=SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=1 Environment=SYSTEMD_NSPAWN_API_VFS_WRITABLE=network +DeviceAllow=char-ipvtap rwm +DeviceAllow=char-macvtap rwm + # GPU support - allow the container to access NVIDIA device nodes via the # cgroup device controller. DeviceAllow grants read/write permission so that # the bind-mounted devices from the [Files] section in the .nspawn config diff --git a/pkg/agent/phases/rootfs/testdata/service-override-kube1.conf.golden b/pkg/agent/phases/rootfs/testdata/service-override-kube1.conf.golden index db147d346..907d0e5f7 100644 --- a/pkg/agent/phases/rootfs/testdata/service-override-kube1.conf.golden +++ b/pkg/agent/phases/rootfs/testdata/service-override-kube1.conf.golden @@ -42,3 +42,6 @@ ExecStartPre=/usr/bin/mkdir -p /run/bpffs/kube1 ExecStartPre=/bin/sh -c '/usr/bin/mountpoint -q /run/bpffs/kube1 || /usr/bin/mount -t bpf bpf /run/bpffs/kube1' Environment=SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=1 Environment=SYSTEMD_NSPAWN_API_VFS_WRITABLE=network + +DeviceAllow=char-ipvtap rwm +DeviceAllow=char-macvtap rwm diff --git a/pkg/agent/phases/rootfs/testdata/service-override-kube2.conf.golden b/pkg/agent/phases/rootfs/testdata/service-override-kube2.conf.golden index 2e445ebc1..6489a76b9 100644 --- a/pkg/agent/phases/rootfs/testdata/service-override-kube2.conf.golden +++ b/pkg/agent/phases/rootfs/testdata/service-override-kube2.conf.golden @@ -42,3 +42,6 @@ ExecStartPre=/usr/bin/mkdir -p /run/bpffs/kube2 ExecStartPre=/bin/sh -c '/usr/bin/mountpoint -q /run/bpffs/kube2 || /usr/bin/mount -t bpf bpf /run/bpffs/kube2' Environment=SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=1 Environment=SYSTEMD_NSPAWN_API_VFS_WRITABLE=network + +DeviceAllow=char-ipvtap rwm +DeviceAllow=char-macvtap rwm