Change:
} } <del> // Although the CDI devices are expected to be empty when this feature is disabled, we still // guard this with a feature gate to avoid any potential issues. if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.DevicePluginCDIDevices) { // We construct a resource ID from the pod UID and container name. // This ID has no semantic meaning, and is only used to ensure that the generated CDI annotation key is unique // for a given container. Since this is only called once per pod-container combination, this should be the case. resourceID := podUID + "-" + contName cdiAnnotations := getCDIAnnotations(resourceID, allCDIDevices, annotationsMap) opts.Annotations = append(opts.Annotations, cdiAnnotations...) } </del> return opts } <del> // getCDIAnnotations returns the cdi annotations for a given container. // This creates a CDI annotation with a key of the form: devicemanager_{{resourceID}}. // The value of the annotation is a comma separated list of sorted CDI device IDs. // If the annotation key is already defined in the provided annotations map, then the existing value is used. func getCDIAnnotations(resourceID string, cdiDevices sets.Set[string], annotationsMap map[string]string) []kubecontainer.Annotation { // We sort the CDI devices to ensure that the annotation value is deterministic. sortedCDIDevices := sets.List[string](cdiDevices) annotations, err := cdi.GenerateAnnotations(types.UID(resourceID), "devicemanager", sortedCDIDevices) if err != nil { klog.ErrorS(err, "Failed to create CDI annotations") return nil } var cdiAnnotations []kubecontainer.Annotation for _, annotation := range annotations { if e, ok := annotationsMap[annotation.Name]; ok { klog.V(4).InfoS("Skip existing annotation", "annotationKey", annotation.Name, "annotationValue", annotation.Value) if e != annotation.Value { klog.ErrorS(nil, "Annotation has conflicting setting", "annotationKey", annotation.Name, "expected", e, "got", annotation.Value) } continue } klog.V(4).InfoS("Add annotation", "annotationKey", annotation.Name, "annotationValue", annotation.Value) annotationsMap[annotation.Name] = annotation.Value cdiAnnotations = append(cdiAnnotations, kubecontainer.Annotation{Name: annotation.Name, Value: annotation.Value}) } return cdiAnnotations } </del> // getCDIDeviceInfo returns CDI devices from an allocate response func getCDIDeviceInfo(resp *pluginapi.ContainerAllocateResponse, knownCDIDevices sets.Set[string]) []kubecontainer.CDIDevice { var cdiDevices []kubecontainer.CDIDevice

Discussion:
Kubelet should stop using annotations to pass CDI device IDs to CRI runtimes. CDIDevices CRI field should be used for this purpose. This should be done when Kubelet that doesn't support CRI field reaches EOL and two major CRI runtimes support CRI field. Here is a PR comment that gives more details about this: Kubelet started using CDIDevices CRI field in . Previous version 1.27 will reach EOL .CRI-O started using it in . Previous version 1.27 will reach EOL together with Kubernetes 1.27.Containerd started using it in . Version 1.7 will reach EOL in a 6 months after Containerd 2.0 release Previous version 1.6 doesn't support CDI injections and should not be considered. So, safer option would be to wait until Containerd 1.7 reaches EOL. However it's relatively safe to do it earlier when 1.7.0 and 1.7.1 have little chances to be in real use. Containerd v1.7.0 and v1.7.1 is not used by the Linux distributions from , so it's safe to remove annotations support from the Kubelet in 1.31 in my opinion.
/sig node
/triage accepted /priority important-longterm
/assign