Skip to content

Commit 107b3c0

Browse files
authored
Merge pull request #2514 from frezbo/fix/drop-containerd-config-mounts-when-nri-enabled
fix: drop containerd config mounts when NRI is enabled
2 parents 1ab8a08 + d91f4aa commit 107b3c0

2 files changed

Lines changed: 102 additions & 19 deletions

File tree

controllers/object_controls.go

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,11 +1379,50 @@ func TransformToolkit(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicySpec, n
13791379
func transformForRuntime(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicySpec, runtime string, container *corev1.Container) error {
13801380
setContainerEnv(container, "RUNTIME", runtime)
13811381

1382-
if runtime == gpuv1.Containerd.String() {
1383-
// Set the runtime class name that is to be configured for containerd
1384-
setContainerEnv(container, "CONTAINERD_RUNTIME_CLASS", getRuntimeClassName(config))
1382+
// In NRI plugin mode the toolkit installer runs the noop runtime configurer
1383+
// (see nvidia-ctk-installer's NewConfigurer): it does not read or modify the
1384+
// container runtime configuration and does not restart the runtime. Mounting the
1385+
// runtime config files and socket is therefore unnecessary in this mode, and the
1386+
// hostPath mounts (e.g. /etc/containerd/conf.d with DirectoryOrCreate) break on
1387+
// read-only hosts such as Talos. Only the NRI socket mount (below) is required.
1388+
if config.CDI.IsNRIPluginEnabled() {
1389+
transformNRISocketMounts(obj, container)
1390+
} else {
1391+
if runtime == gpuv1.Containerd.String() {
1392+
// Set the runtime class name that is to be configured for containerd
1393+
setContainerEnv(container, "CONTAINERD_RUNTIME_CLASS", getRuntimeClassName(config))
1394+
}
1395+
1396+
if err := transformRuntimeConfigAndSocketMounts(obj, runtime, container); err != nil {
1397+
return err
1398+
}
13851399
}
13861400

1401+
return nil
1402+
}
1403+
1404+
// transformNRISocketMounts adds the required NRI socket environment variable and
1405+
// sets up the NRI socket mount
1406+
func transformNRISocketMounts(obj *appsv1.DaemonSet, container *corev1.Container) {
1407+
// setup mounts for the runtime NRI socket file
1408+
nriSocketFile := getContainerEnv(container, "NRI_SOCKET")
1409+
if nriSocketFile == "" {
1410+
nriSocketFile = DefaultRuntimeNRISocketFile
1411+
}
1412+
setContainerEnv(container, "NRI_SOCKET", path.Join(DefaultRuntimeNRISocketTargetDir, path.Base(nriSocketFile)))
1413+
1414+
nriVolMountSocketName := "nri-socket"
1415+
nriVolMountSocket := corev1.VolumeMount{Name: nriVolMountSocketName, MountPath: DefaultRuntimeNRISocketTargetDir}
1416+
container.VolumeMounts = append(container.VolumeMounts, nriVolMountSocket)
1417+
1418+
nriSocketVol := corev1.Volume{Name: nriVolMountSocketName, VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{Path: path.Dir(nriSocketFile), Type: ptr.To(corev1.HostPathDirectoryOrCreate)}}}
1419+
obj.Spec.Template.Spec.Volumes = append(obj.Spec.Template.Spec.Volumes, nriSocketVol)
1420+
}
1421+
1422+
// transformRuntimeConfigAndSocketMounts configures the toolkit container with the
1423+
// mounts and environment required for the toolkit installer to update the container
1424+
// runtime configuration (top-level config, drop-in config, and runtime socket).
1425+
func transformRuntimeConfigAndSocketMounts(obj *appsv1.DaemonSet, runtime string, container *corev1.Container) error {
13871426
// For runtime config files we have top-level configs and drop-in files.
13881427
// These are supported as follows:
13891428
// * Docker only supports top-level config files.
@@ -1489,22 +1528,6 @@ func transformForRuntime(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicySpec,
14891528
obj.Spec.Template.Spec.Volumes = append(obj.Spec.Template.Spec.Volumes, socketVol)
14901529
}
14911530

1492-
if config.CDI.IsNRIPluginEnabled() {
1493-
// setup mounts for the runtime NRI socket file
1494-
nriSocketFile := getContainerEnv(container, "NRI_SOCKET")
1495-
if nriSocketFile == "" {
1496-
nriSocketFile = DefaultRuntimeNRISocketFile
1497-
}
1498-
setContainerEnv(container, "NRI_SOCKET", DefaultRuntimeNRISocketTargetDir+path.Base(nriSocketFile))
1499-
1500-
nriVolMountSocketName := "nri-socket"
1501-
nriVolMountSocket := corev1.VolumeMount{Name: nriVolMountSocketName, MountPath: DefaultRuntimeNRISocketTargetDir}
1502-
container.VolumeMounts = append(container.VolumeMounts, nriVolMountSocket)
1503-
1504-
nriSocketVol := corev1.Volume{Name: nriVolMountSocketName, VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{Path: path.Dir(nriSocketFile), Type: ptr.To(corev1.HostPathDirectoryOrCreate)}}}
1505-
obj.Spec.Template.Spec.Volumes = append(obj.Spec.Template.Spec.Volumes, nriSocketVol)
1506-
}
1507-
15081531
return nil
15091532
}
15101533

controllers/transforms_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package controllers
1818

1919
import (
20+
"path"
2021
"path/filepath"
2122
"strings"
2223
"testing"
@@ -1073,6 +1074,65 @@ func TestTransformToolkit(t *testing.T) {
10731074
WithHostPathVolume("crio-config", "/etc/crio", ptr.To(corev1.HostPathDirectoryOrCreate)).
10741075
WithHostPathVolume("crio-drop-in-config", "/etc/crio/crio.conf.d", ptr.To(corev1.HostPathDirectoryOrCreate)),
10751076
},
1077+
{
1078+
description: "transform with NRI enabled has just the NRI socket mount",
1079+
ds: NewDaemonset().
1080+
WithContainer(corev1.Container{Name: "nvidia-container-toolkit-ctr"}),
1081+
runtime: gpuv1.Containerd,
1082+
cpSpec: &gpuv1.ClusterPolicySpec{
1083+
CDI: gpuv1.CDIConfigSpec{
1084+
Enabled: new(true),
1085+
NRIPluginEnabled: new(true),
1086+
},
1087+
Toolkit: gpuv1.ToolkitSpec{
1088+
Repository: "nvcr.io/nvidia/cloud-native",
1089+
Image: "nvidia-container-toolkit",
1090+
Version: "v1.0.0",
1091+
ImagePullPolicy: "IfNotPresent",
1092+
ImagePullSecrets: []string{"pull-secret"},
1093+
Resources: &gpuv1.ResourceRequirements{
1094+
Limits: corev1.ResourceList{
1095+
corev1.ResourceCPU: resource.MustParse("100m"),
1096+
corev1.ResourceMemory: resource.MustParse("100Mi"),
1097+
},
1098+
Requests: corev1.ResourceList{
1099+
corev1.ResourceCPU: resource.MustParse("50m"),
1100+
corev1.ResourceMemory: resource.MustParse("50Mi"),
1101+
},
1102+
},
1103+
},
1104+
},
1105+
expectedDs: NewDaemonset().
1106+
WithHostPathVolume("nri-socket", filepath.Dir(DefaultRuntimeNRISocketFile), new(corev1.HostPathDirectoryOrCreate)).
1107+
WithContainer(corev1.Container{
1108+
Name: "nvidia-container-toolkit-ctr",
1109+
Image: "nvcr.io/nvidia/cloud-native/nvidia-container-toolkit:v1.0.0",
1110+
ImagePullPolicy: corev1.PullIfNotPresent,
1111+
Resources: corev1.ResourceRequirements{
1112+
Limits: corev1.ResourceList{
1113+
corev1.ResourceCPU: resource.MustParse("100m"),
1114+
corev1.ResourceMemory: resource.MustParse("100Mi"),
1115+
},
1116+
Requests: corev1.ResourceList{
1117+
corev1.ResourceCPU: resource.MustParse("50m"),
1118+
corev1.ResourceMemory: resource.MustParse("50Mi"),
1119+
},
1120+
},
1121+
Env: []corev1.EnvVar{
1122+
{Name: CDIEnabledEnvName, Value: "true"},
1123+
{Name: NvidiaRuntimeSetAsDefaultEnvName, Value: "false"},
1124+
{Name: NvidiaCtrRuntimeModeEnvName, Value: "cdi"},
1125+
{Name: CRIOConfigModeEnvName, Value: "config"},
1126+
{Name: "ENABLE_NRI_PLUGIN", Value: "true"},
1127+
{Name: "RUNTIME", Value: "containerd"},
1128+
{Name: "NRI_SOCKET", Value: path.Join(DefaultRuntimeNRISocketTargetDir, path.Base(DefaultRuntimeNRISocketFile))},
1129+
},
1130+
VolumeMounts: []corev1.VolumeMount{
1131+
{Name: "nri-socket", MountPath: DefaultRuntimeNRISocketTargetDir},
1132+
},
1133+
}).
1134+
WithPullSecret("pull-secret"),
1135+
},
10761136
}
10771137

10781138
for _, tc := range testCases {

0 commit comments

Comments
 (0)