Repository: kubernetes/kubernetes (language: go)

Issue:
removeMissingExtendedResources() did not remove unknown extension resources from InitContainer
### What happened?

The function removeMissingExtendedResources() located at pkg/kubelet/lifecycle/predicate.go:217, is designed to remove any extended resources from a container’s requests that are not found in nodeInfo.Allocatable before the pod is admitted. This is necessary to support cluster-level resources, which are extended resources that are unknown to nodes.
However, this function only removes missingExtendedResources from the container’s requests, and does not process the requests of initContainers. This could lead to issues, as initContainers might request resources that do not exist on the node, which could result in the pod failing to be admitted or other unforeseen issues. As such, it may be necessary to refine the removeMissingExtendedResources() function to also handle initContainer’s requests.

### What did you expect to happen?

Refine the removeMissingExtendedResources() function to also handle initContainer’s requests.

### How can we reproduce it (as minimally and precisely as possible)?

Create a pod that requests cluster-level extended resources in both the container and InitContainer.

### Anything else we need to know?

_No response_

### Kubernetes version

The problem persists in the latest version.


### Cloud provider

-

### OS version

<details>

```console
# On Linux:
$ cat /etc/os-release
# paste output here
$ uname -a
# paste output here

# On Windows:
C:\> wmic os get Caption, Version, BuildNumber, OSArchitecture
# paste output here
```

</details>


### Install tools

<details>

</details>


### Container runtime (CRI) and version (if applicable)

<details>

</details>


### Related plugins (CNI, CSI, ...) and versions (if applicable)

<details>

</details>



Discussion / hints:
/sig node

Fix patch:
diff --git a/pkg/kubelet/lifecycle/predicate.go b/pkg/kubelet/lifecycle/predicate.go
index 8b93ba39ae3a7..af9bde9c89d83 100644
--- a/pkg/kubelet/lifecycle/predicate.go
+++ b/pkg/kubelet/lifecycle/predicate.go
@@ -215,21 +215,26 @@ func rejectPodAdmissionBasedOnOSField(pod *v1.Pod) bool {
 }
 
 func removeMissingExtendedResources(pod *v1.Pod, nodeInfo *schedulerframework.NodeInfo) *v1.Pod {
-	podCopy := pod.DeepCopy()
-	for i, c := range pod.Spec.Containers {
-		// We only handle requests in Requests but not Limits because the
-		// PodFitsResources predicate, to which the result pod will be passed,
-		// does not use Limits.
-		podCopy.Spec.Containers[i].Resources.Requests = make(v1.ResourceList)
-		for rName, rQuant := range c.Resources.Requests {
-			if v1helper.IsExtendedResourceName(rName) {
-				if _, found := nodeInfo.Allocatable.ScalarResources[rName]; !found {
-					continue
+	filterExtendedResources := func(containers []v1.Container) {
+		for i, c := range containers {
+			// We only handle requests in Requests but not Limits because the
+			// PodFitsResources predicate, to which the result pod will be passed,
+			// does not use Limits.
+			filteredResources := make(v1.ResourceList)
+			for rName, rQuant := range c.Resources.Requests {
+				if v1helper.IsExtendedResourceName(rName) {
+					if _, found := nodeInfo.Allocatable.ScalarResources[rName]; !found {
+						continue
+					}
 				}
+				filteredResources[rName] = rQuant
 			}
-			podCopy.Spec.Containers[i].Resources.Requests[rName] = rQuant
+			containers[i].Resources.Requests = filteredResources
 		}
 	}
+	podCopy := pod.DeepCopy()
+	filterExtendedResources(podCopy.Spec.Containers)
+	filterExtendedResources(podCopy.Spec.InitContainers)
 	return podCopy
 }
 


Test patch:
diff --git a/pkg/kubelet/lifecycle/predicate_test.go b/pkg/kubelet/lifecycle/predicate_test.go
index 649ba679bf4e7..98db94d39b9cd 100644
--- a/pkg/kubelet/lifecycle/predicate_test.go
+++ b/pkg/kubelet/lifecycle/predicate_test.go
@@ -106,6 +106,14 @@ func makeTestPod(requests, limits v1.ResourceList) *v1.Pod {
 					},
 				},
 			},
+			InitContainers: []v1.Container{
+				{
+					Resources: v1.ResourceRequirements{
+						Requests: requests,
+						Limits:   limits,
+					},
+				},
+			},
 		},
 	}
 }