Skip to content

Commit 8586977

Browse files
committed
Merge branch '23.03-cherry-picks' into 'release-23.03'
Cherry-picks for 23.3.0 release See merge request nvidia/kubernetes/gpu-operator!669
2 parents 9d68920 + 26bb2b2 commit 8586977

24 files changed

+422
-104
lines changed

assets/state-container-toolkit/0400_configmap.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ data:
3333
#
3434
sleep 5
3535
36-
exec nvidia-toolkit /usr/local/nvidia
36+
exec nvidia-toolkit

assets/state-container-toolkit/0500_daemonset.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ spec:
5959
args:
6060
- /bin/entrypoint.sh
6161
env:
62+
- name: ROOT
63+
value: "/usr/local/nvidia"
6264
- name: RUNTIME_ARGS
6365
value: ""
6466
- name: NVIDIA_CONTAINER_RUNTIME_MODES_CDI_DEFAULT_KIND

assets/state-device-plugin/0400_configmap.yaml

+21-7
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,28 @@ data:
99
entrypoint.sh: |-
1010
#!/bin/bash
1111
12-
driver_root=/run/nvidia/driver
13-
driver_root_ctr_path=$driver_root
14-
if [[ -f /run/nvidia/validations/host-driver-ready ]]; then
15-
driver_root=/
16-
driver_root_ctr_path=/host
17-
fi;
12+
driver_root=""
13+
container_driver_root=""
14+
while true; do
15+
if [[ -f /run/nvidia/validations/host-driver-ready ]]; then
16+
driver_root=/
17+
container_driver_root=/host
18+
break
19+
elif [[ -f /run/nvidia/validations/driver-ready ]]; then
20+
driver_root=/run/nvidia/driver
21+
container_driver_root=$driver_root
22+
break
23+
else
24+
echo "waiting for the driver validations to be ready..."
25+
sleep 5
26+
fi
27+
done
1828
1929
export NVIDIA_DRIVER_ROOT=$driver_root
20-
export DRIVER_ROOT_CTR_PATH=$driver_root_ctr_path
30+
echo "NVIDIA_DRIVER_ROOT=$NVIDIA_DRIVER_ROOT"
2131
32+
export CONTAINER_DRIVER_ROOT=$container_driver_root
33+
echo "CONTAINER_DRIVER_ROOT=$CONTAINER_DRIVER_ROOT"
34+
35+
echo "Starting nvidia-device-plugin"
2236
exec nvidia-device-plugin
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: nvidia-mig-manager-entrypoint
5+
namespace: "FILLED BY THE OPERATOR"
6+
labels:
7+
app: nvidia-mig-manager
8+
data:
9+
entrypoint.sh: |-
10+
#!/bin/bash
11+
12+
host_driver=""
13+
driver_root=""
14+
driver_root_ctr_path=""
15+
while true; do
16+
if [[ -f /run/nvidia/validations/host-driver-ready ]]; then
17+
host_driver=true
18+
driver_root="/"
19+
driver_root_ctr_path="/host"
20+
break
21+
elif [[ -f /run/nvidia/validations/driver-ready ]]; then
22+
host_driver=false
23+
driver_root="/run/nvidia/driver"
24+
driver_root_ctr_path="/run/nvidia/driver"
25+
break
26+
else
27+
echo "waiting for the driver validations to be ready..."
28+
sleep 5
29+
fi
30+
done
31+
32+
export WITH_SHUTDOWN_HOST_GPU_CLIENTS=$host_driver
33+
echo "WITH_SHUTDOWN_HOST_GPU_CLIENTS=$WITH_SHUTDOWN_HOST_GPU_CLIENTS"
34+
35+
export DRIVER_ROOT=$driver_root
36+
echo "DRIVER_ROOT=$DRIVER_ROOT"
37+
38+
export DRIVER_ROOT_CTR_PATH=$driver_root_ctr_path
39+
echo "DRIVER_ROOT_CTR_PATH=$DRIVER_ROOT_CTR_PATH"
40+
41+
echo "Starting nvidia-mig-manager"
42+
exec nvidia-mig-manager

assets/state-mig-manager/0600_daemonset.yaml

+16-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ spec:
4040
image: "FILLED BY THE OPERATOR"
4141
imagePullPolicy: IfNotPresent
4242
command: [bash, -c]
43-
args: [" [[ -f /run/nvidia/validations/host-driver-ready ]] && host_driver=true || host_driver=false; export WITH_SHUTDOWN_HOST_GPU_CLIENTS=$host_driver; exec nvidia-mig-manager"]
43+
args:
44+
- /bin/entrypoint.sh
4445
env:
4546
- name: NODE_NAME
4647
valueFrom:
@@ -57,6 +58,10 @@ spec:
5758
securityContext:
5859
privileged: true
5960
volumeMounts:
61+
- name: nvidia-mig-manager-entrypoint
62+
readOnly: true
63+
mountPath: /bin/entrypoint.sh
64+
subPath: entrypoint.sh
6065
- mountPath: /sys
6166
name: host-sys
6267
- mountPath: /mig-parted-config
@@ -69,7 +74,13 @@ spec:
6974
- name: run-nvidia
7075
mountPath: /run/nvidia
7176
mountPropagation: HostToContainer
77+
- name: cdi-root
78+
mountPath: /var/run/cdi
7279
volumes:
80+
- name: nvidia-mig-manager-entrypoint
81+
configMap:
82+
name: nvidia-mig-manager-entrypoint
83+
defaultMode: 448
7384
- name: host-sys
7485
hostPath:
7586
path: /sys
@@ -87,3 +98,7 @@ spec:
8798
- name: gpu-clients
8899
configMap:
89100
name: "FILLED_BY_OPERATOR"
101+
- name: cdi-root
102+
hostPath:
103+
path: /var/run/cdi
104+
type: DirectoryOrCreate

bundle/manifests/gpu-operator-certified.clusterserviceversion.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ metadata:
4040
"timeoutSeconds": 300
4141
},
4242
"maxParallelUpgrades": 1,
43+
"maxUnavailable": "25%",
4344
"podDeletion": {
4445
"deleteEmptyDir": false,
4546
"force": false,

bundle/manifests/nvidia.com_clusterpolicies.yaml

+12
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,18 @@ spec:
10851085
will be upgraded in parallel
10861086
minimum: 0
10871087
type: integer
1088+
maxUnavailable:
1089+
anyOf:
1090+
- type: integer
1091+
- type: string
1092+
default: 25%
1093+
description: 'MaxUnavailable is the maximum number of nodes
1094+
with the driver installed, that can be unavailable during
1095+
the upgrade. Value can be an absolute number (ex: 5) or
1096+
a percentage of total nodes at the start of upgrade (ex:
1097+
10%). Absolute number is calculated from percentage by rounding
1098+
up. By default, a fixed value of 1 is used.'
1099+
x-kubernetes-int-or-string: true
10881100
podDeletion:
10891101
description: PodDeletionSpec describes configuration for deletion
10901102
of pods using special resources during automatic upgrade

config/crd/bases/nvidia.com_clusterpolicies.yaml

+12
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,18 @@ spec:
10851085
will be upgraded in parallel
10861086
minimum: 0
10871087
type: integer
1088+
maxUnavailable:
1089+
anyOf:
1090+
- type: integer
1091+
- type: string
1092+
default: 25%
1093+
description: 'MaxUnavailable is the maximum number of nodes
1094+
with the driver installed, that can be unavailable during
1095+
the upgrade. Value can be an absolute number (ex: 5) or
1096+
a percentage of total nodes at the start of upgrade (ex:
1097+
10%). Absolute number is calculated from percentage by rounding
1098+
up. By default, a fixed value of 1 is used.'
1099+
x-kubernetes-int-or-string: true
10881100
podDeletion:
10891101
description: PodDeletionSpec describes configuration for deletion
10901102
of pods using special resources during automatic upgrade

controllers/object_controls.go

+71-35
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ const (
4545
DefaultDockerConfigFile = "/etc/docker/daemon.json"
4646
// DefaultDockerSocketFile indicates default docker socket file
4747
DefaultDockerSocketFile = "/var/run/docker.sock"
48+
// DefaultCRIOConfigFile indicates default config file path for cri-o.
49+
// Note, config files in the drop-in directory, /etc/crio/crio.conf.d,
50+
// have a higher priority than the default /etc/crio/crio.conf file.
51+
DefaultCRIOConfigFile = "/etc/crio/crio.conf.d/99-nvidia.conf"
4852
// TrustedCAConfigMapName indicates configmap with custom user CA injected
4953
TrustedCAConfigMapName = "gpu-operator-trusted-ca"
5054
// TrustedCABundleFileName indicates custom user ca certificate filename
@@ -111,18 +115,26 @@ const (
111115
ServiceMonitorCRDName = "servicemonitors.monitoring.coreos.com"
112116
// DefaultToolkitInstallDir is the default toolkit installation directory on the host
113117
DefaultToolkitInstallDir = "/usr/local/nvidia"
118+
// ToolkitInstallDirEnvName is the name of the toolkit container env for configuring where NVIDIA Container Toolkit is installed
119+
ToolkitInstallDirEnvName = "ROOT"
114120
// VgpuDMDefaultConfigMapName indicates name of ConfigMap containing default vGPU devices configuration
115121
VgpuDMDefaultConfigMapName = "default-vgpu-devices-config"
116122
// VgpuDMDefaultConfigName indicates name of default configuration in the vGPU devices config file
117123
VgpuDMDefaultConfigName = "default"
118124
// NvidiaCtrRuntimeModeEnvName is the name of the toolkit container env for configuring the NVIDIA Container Runtime mode
119125
NvidiaCtrRuntimeModeEnvName = "NVIDIA_CONTAINER_RUNTIME_MODE"
126+
// NvidiaCtrRuntimeCDIPrefixesEnvName is the name of toolkit container env for configuring the CDI annotation prefixes
127+
NvidiaCtrRuntimeCDIPrefixesEnvName = "NVIDIA_CONTAINER_RUNTIME_MODES_CDI_ANNOTATION_PREFIXES"
120128
// CDIEnabledEnvName is the name of the envvar used to enable CDI in the operands
121129
CDIEnabledEnvName = "CDI_ENABLED"
122130
// NvidiaCTKPathEnvName is the name of the envvar specifying the path to the 'nvidia-ctk' binary
123131
NvidiaCTKPathEnvName = "NVIDIA_CTK_PATH"
124132
// CrioConfigModeEnvName is the name of the envvar controlling how the toolkit container updates the cri-o configuration
125133
CrioConfigModeEnvName = "CRIO_CONFIG_MODE"
134+
// DeviceListStrategyEnvName is the name of the envvar for configuring the device-list-strategy in the device-plugin
135+
DeviceListStrategyEnvName = "DEVICE_LIST_STRATEGY"
136+
// CDIAnnotationPrefixEnvName is the name of the device-plugin envvar for configuring the CDI annotation prefix
137+
CDIAnnotationPrefixEnvName = "CDI_ANNOTATION_PREFIX"
126138
)
127139

128140
// RepoConfigPathMap indicates standard OS specific paths for repository configuration files
@@ -1047,6 +1059,7 @@ func TransformToolkit(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicySpec, n
10471059
// update env required for CDI support
10481060
if config.CDI.IsEnabled() {
10491061
setContainerEnv(&(obj.Spec.Template.Spec.Containers[0]), CDIEnabledEnvName, "true")
1062+
setContainerEnv(&(obj.Spec.Template.Spec.Containers[0]), NvidiaCtrRuntimeCDIPrefixesEnvName, "nvidia.cdi.k8s.io/")
10501063
setContainerEnv(&(obj.Spec.Template.Spec.Containers[0]), CrioConfigModeEnvName, "config")
10511064
if config.CDI.IsDefault() {
10521065
setContainerEnv(&(obj.Spec.Template.Spec.Containers[0]), NvidiaCtrRuntimeModeEnvName, "cdi")
@@ -1055,13 +1068,8 @@ func TransformToolkit(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicySpec, n
10551068

10561069
// set install directory for the toolkit
10571070
if config.Toolkit.InstallDir != "" && config.Toolkit.InstallDir != DefaultToolkitInstallDir {
1058-
// set args for the toolkit
1059-
toolkitArgStrFmt := "[[ -f /run/nvidia/validations/host-driver-ready ]] && driver_root=/ || driver_root=/run/nvidia/driver; export NVIDIA_DRIVER_ROOT=$driver_root; sleep 5; exec nvidia-toolkit %s"
1060-
toolkitArg := fmt.Sprintf(toolkitArgStrFmt, config.Toolkit.InstallDir)
1061-
args := []string{toolkitArg}
1062-
obj.Spec.Template.Spec.Containers[0].Args = args
1071+
setContainerEnv(&(obj.Spec.Template.Spec.Containers[0]), ToolkitInstallDirEnvName, config.Toolkit.InstallDir)
10631072

1064-
// update install directory for the toolkit
10651073
for i, volume := range obj.Spec.Template.Spec.Volumes {
10661074
if volume.Name == "toolkit-install-dir" {
10671075
obj.Spec.Template.Spec.Volumes[i].HostPath.Path = config.Toolkit.InstallDir
@@ -1086,27 +1094,30 @@ func TransformToolkit(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicySpec, n
10861094
setContainerEnv(&(obj.Spec.Template.Spec.Containers[0]), "CONTAINERD_RUNTIME_CLASS", getRuntimeClass(config))
10871095
}
10881096

1089-
// setup mounts for runtime config file and socket file
1090-
if runtime == gpuv1.Docker.String() || runtime == gpuv1.Containerd.String() {
1091-
runtimeConfigFile := getRuntimeConfigFile(&(obj.Spec.Template.Spec.Containers[0]), runtime)
1092-
runtimeSocketFile := getRuntimeSocketFile(&(obj.Spec.Template.Spec.Containers[0]), runtime)
1093-
1094-
sourceSocketFileName := path.Base(runtimeSocketFile)
1095-
sourceConfigFileName := path.Base(runtimeConfigFile)
1097+
// setup mounts for runtime config file
1098+
runtimeConfigFile, err := getRuntimeConfigFile(&(obj.Spec.Template.Spec.Containers[0]), runtime)
1099+
if err != nil {
1100+
return fmt.Errorf("error getting path to runtime config file: %v", err)
1101+
}
1102+
sourceConfigFileName := path.Base(runtimeConfigFile)
1103+
runtimeArgs := "--config " + DefaultRuntimeConfigTargetDir + sourceConfigFileName
10961104

1097-
// docker needs socket file as runtime arg
1098-
setContainerEnv(&(obj.Spec.Template.Spec.Containers[0]), "RUNTIME_ARGS",
1099-
"--socket "+DefaultRuntimeSocketTargetDir+sourceSocketFileName+" --config "+DefaultRuntimeConfigTargetDir+sourceConfigFileName)
1105+
volMountConfigName := fmt.Sprintf("%s-config", runtime)
1106+
volMountConfig := corev1.VolumeMount{Name: volMountConfigName, MountPath: DefaultRuntimeConfigTargetDir}
1107+
obj.Spec.Template.Spec.Containers[0].VolumeMounts = append(obj.Spec.Template.Spec.Containers[0].VolumeMounts, volMountConfig)
11001108

1101-
// setup config file mount
1102-
volMountConfigName := fmt.Sprintf("%s-config", runtime)
1103-
volMountConfig := corev1.VolumeMount{Name: volMountConfigName, MountPath: DefaultRuntimeConfigTargetDir}
1104-
obj.Spec.Template.Spec.Containers[0].VolumeMounts = append(obj.Spec.Template.Spec.Containers[0].VolumeMounts, volMountConfig)
1109+
configVol := corev1.Volume{Name: volMountConfigName, VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{Path: path.Dir(runtimeConfigFile), Type: newHostPathType(corev1.HostPathDirectoryOrCreate)}}}
1110+
obj.Spec.Template.Spec.Volumes = append(obj.Spec.Template.Spec.Volumes, configVol)
11051111

1106-
configVol := corev1.Volume{Name: volMountConfigName, VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{Path: path.Dir(runtimeConfigFile)}}}
1107-
obj.Spec.Template.Spec.Volumes = append(obj.Spec.Template.Spec.Volumes, configVol)
1112+
// setup mounts for runtime socket file
1113+
if runtime == gpuv1.Docker.String() || runtime == gpuv1.Containerd.String() {
1114+
runtimeSocketFile, err := getRuntimeSocketFile(&(obj.Spec.Template.Spec.Containers[0]), runtime)
1115+
if err != nil {
1116+
return fmt.Errorf("error getting path to runtime socket: %v", err)
1117+
}
1118+
sourceSocketFileName := path.Base(runtimeSocketFile)
1119+
runtimeArgs += " --socket " + DefaultRuntimeSocketTargetDir + sourceSocketFileName
11081120

1109-
// setup socket file mount
11101121
volMountSocketName := fmt.Sprintf("%s-socket", runtime)
11111122
volMountSocket := corev1.VolumeMount{Name: volMountSocketName, MountPath: DefaultRuntimeSocketTargetDir}
11121123
obj.Spec.Template.Spec.Containers[0].VolumeMounts = append(obj.Spec.Template.Spec.Containers[0].VolumeMounts, volMountSocket)
@@ -1115,6 +1126,9 @@ func TransformToolkit(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicySpec, n
11151126
obj.Spec.Template.Spec.Volumes = append(obj.Spec.Template.Spec.Volumes, socketVol)
11161127
}
11171128

1129+
// update runtime args
1130+
setContainerEnv(&(obj.Spec.Template.Spec.Containers[0]), "RUNTIME_ARGS", runtimeArgs)
1131+
11181132
// Update CRI-O hooks path to use default path for non OCP cases
11191133
if n.openshift == "" && n.runtime == gpuv1.CRIO {
11201134
for index, volume := range obj.Spec.Template.Spec.Volumes {
@@ -1187,6 +1201,8 @@ func TransformDevicePlugin(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicySpe
11871201
// update env required for CDI support
11881202
if config.CDI.IsEnabled() {
11891203
setContainerEnv(&(obj.Spec.Template.Spec.Containers[0]), CDIEnabledEnvName, "true")
1204+
setContainerEnv(&(obj.Spec.Template.Spec.Containers[0]), DeviceListStrategyEnvName, "envvar,cdi-annotations")
1205+
setContainerEnv(&(obj.Spec.Template.Spec.Containers[0]), CDIAnnotationPrefixEnvName, "nvidia.cdi.k8s.io/")
11901206
if config.Toolkit.IsEnabled() {
11911207
setContainerEnv(&(obj.Spec.Template.Spec.Containers[0]), NvidiaCTKPathEnvName, filepath.Join(config.Toolkit.InstallDir, "toolkit/nvidia-ctk"))
11921208
}
@@ -1506,6 +1522,11 @@ func TransformMIGManager(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicySpec,
15061522
break
15071523
}
15081524

1525+
// update env required for CDI support
1526+
if config.CDI.IsEnabled() {
1527+
setContainerEnv(&(obj.Spec.Template.Spec.Containers[0]), CDIEnabledEnvName, "true")
1528+
}
1529+
15091530
return nil
15101531
}
15111532

@@ -1856,35 +1877,50 @@ func TransformNodeStatusExporter(obj *appsv1.DaemonSet, config *gpuv1.ClusterPol
18561877
}
18571878

18581879
// get runtime(docker, containerd) config file path based on toolkit container env or default
1859-
func getRuntimeConfigFile(c *corev1.Container, runtime string) (runtimeConfigFile string) {
1860-
if runtime == gpuv1.Docker.String() {
1880+
func getRuntimeConfigFile(c *corev1.Container, runtime string) (string, error) {
1881+
var runtimeConfigFile string
1882+
switch runtime {
1883+
case gpuv1.Docker.String():
18611884
runtimeConfigFile = DefaultDockerConfigFile
1862-
if getContainerEnv(c, "DOCKER_CONFIG") != "" {
1863-
runtimeConfigFile = getContainerEnv(c, "DOCKER_CONFIG")
1885+
if value := getContainerEnv(c, "DOCKER_CONFIG"); value != "" {
1886+
runtimeConfigFile = value
18641887
}
1865-
} else if runtime == gpuv1.Containerd.String() {
1888+
case gpuv1.Containerd.String():
18661889
runtimeConfigFile = DefaultContainerdConfigFile
1867-
if getContainerEnv(c, "CONTAINERD_CONFIG") != "" {
1868-
runtimeConfigFile = getContainerEnv(c, "CONTAINERD_CONFIG")
1890+
if value := getContainerEnv(c, "CONTAINERD_CONFIG"); value != "" {
1891+
runtimeConfigFile = value
18691892
}
1893+
case gpuv1.CRIO.String():
1894+
runtimeConfigFile = DefaultCRIOConfigFile
1895+
if value := getContainerEnv(c, "CRIO_CONFIG"); value != "" {
1896+
runtimeConfigFile = value
1897+
}
1898+
default:
1899+
return "", fmt.Errorf("invalid runtime: %s", runtime)
18701900
}
1871-
return runtimeConfigFile
1901+
1902+
return runtimeConfigFile, nil
18721903
}
18731904

18741905
// get runtime(docker, containerd) socket file path based on toolkit container env or default
1875-
func getRuntimeSocketFile(c *corev1.Container, runtime string) (runtimeSocketFile string) {
1876-
if runtime == gpuv1.Docker.String() {
1906+
func getRuntimeSocketFile(c *corev1.Container, runtime string) (string, error) {
1907+
var runtimeSocketFile string
1908+
switch runtime {
1909+
case gpuv1.Docker.String():
18771910
runtimeSocketFile = DefaultDockerSocketFile
18781911
if getContainerEnv(c, "DOCKER_SOCKET") != "" {
18791912
runtimeSocketFile = getContainerEnv(c, "DOCKER_SOCKET")
18801913
}
1881-
} else if runtime == gpuv1.Containerd.String() {
1914+
case gpuv1.Containerd.String():
18821915
runtimeSocketFile = DefaultContainerdSocketFile
18831916
if getContainerEnv(c, "CONTAINERD_SOCKET") != "" {
18841917
runtimeSocketFile = getContainerEnv(c, "CONTAINERD_SOCKET")
18851918
}
1919+
default:
1920+
return "", fmt.Errorf("invalid runtime: %s", runtime)
18861921
}
1887-
return runtimeSocketFile
1922+
1923+
return runtimeSocketFile, nil
18881924
}
18891925

18901926
func getContainerEnv(c *corev1.Container, key string) string {

0 commit comments

Comments
 (0)