From bde66bfb55cbf2134dde1f62b21059c6bcf5c049 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Wed, 21 Jun 2023 16:43:46 +0200 Subject: [PATCH] kubelet dra: restore skipping of unused resource claims 1aeec10efb removed iterating over containers in favor of iterating over pod claims. This had the unintended consequence that NodePrepareResource gets called unnecessarily when no container needs the claim. The more natural behavior is to skip unused resources. This enables (theoretic, at this time) use cases where some DRA driver relies on the controller part to influence scheduling, but then doesn't use CDI with containers. --- pkg/kubelet/cm/dra/manager.go | 38 ++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/pkg/kubelet/cm/dra/manager.go b/pkg/kubelet/cm/dra/manager.go index 7ef397bfcd4..2596646c473 100644 --- a/pkg/kubelet/cm/dra/manager.go +++ b/pkg/kubelet/cm/dra/manager.go @@ -67,7 +67,8 @@ func NewManagerImpl(kubeClient clientset.Interface, stateFileDirectory string) ( // containerResources on success. func (m *ManagerImpl) PrepareResources(pod *v1.Pod) error { for i := range pod.Spec.ResourceClaims { - claimName := resourceclaim.Name(pod, &pod.Spec.ResourceClaims[i]) + podClaim := &pod.Spec.ResourceClaims[i] + claimName := resourceclaim.Name(pod, podClaim) klog.V(3).InfoS("Processing resource", "claim", claimName, "pod", pod.Name) // Query claim object from the API server @@ -85,6 +86,13 @@ func (m *ManagerImpl) PrepareResources(pod *v1.Pod) error { pod.Name, pod.UID, claimName, resourceClaim.UID) } + // If no container actually uses the claim, then we don't need + // to prepare it. + if !claimIsUsedByPod(podClaim, pod) { + klog.V(5).InfoS("Skipping unused resource", "claim", claimName, "pod", pod.Name) + continue + } + // Is the resource already prepared? Then add the pod UID to it. if claimInfo := m.cache.get(claimName, pod.Namespace); claimInfo != nil { // We delay checkpointing of this change until this call @@ -178,6 +186,34 @@ func (m *ManagerImpl) PrepareResources(pod *v1.Pod) error { return nil } +func claimIsUsedByPod(podClaim *v1.PodResourceClaim, pod *v1.Pod) bool { + if claimIsUsedByContainers(podClaim, pod.Spec.InitContainers) { + return true + } + if claimIsUsedByContainers(podClaim, pod.Spec.Containers) { + return true + } + return false +} + +func claimIsUsedByContainers(podClaim *v1.PodResourceClaim, containers []v1.Container) bool { + for i := range containers { + if claimIsUsedByContainer(podClaim, &containers[i]) { + return true + } + } + return false +} + +func claimIsUsedByContainer(podClaim *v1.PodResourceClaim, container *v1.Container) bool { + for _, c := range container.Resources.Claims { + if c.Name == podClaim.Name { + return true + } + } + return false +} + // GetResources gets a ContainerInfo object from the claimInfo cache. // This information is used by the caller to update a container config. func (m *ManagerImpl) GetResources(pod *v1.Pod, container *v1.Container) (*ContainerInfo, error) {