Change:
mutates the pod object in place (vs creating a copy first). That's illegal and can cause data races or potentially panics (the panic is unlikely here but I can't rule it out). This line should be: This should be fixed because we might serialize the object in the middle of this from somewhere else and if the object changes midway the protobuf object we create may not be valid, leading to panics in kubelets with this gate turned on. /sig node /priority critical-urgent /kind bug /assign No mutation of pod objects from within methods (in fact no mutation of should occur in most loops). N/A No response <details</details<details</details<details</details<details</details<details</details<details</details
This issue is currently awaiting triage. If a SIG or subproject determines this is a relevant issue, they will accept it by applying the label and provide further guidance. The label can be by org members by writing in a comment. <detailsInstructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
ACK. I'll fix it shortly.
is similar. is my try for both data races that we found.
One small , thanks.
Please review
This Issue/PR has been marked as release blocker. Please have the fix merged by eod today otherwise the feature has to be reverted. For the Issue/PR owner: please have a revert/feature disable PR open today in case the fix failed to get in. Thank you! See the -- Kubernetes 1.27 release manager

Discussion:
// TODO(vinaykul,InPlacePodVerticalScaling): Investigate doing this in HandlePodUpdates + periodic SyncLoop scan //     See: https://github.com/kubernetes/kubernetes/pull/102884#discussion_r663160060 if kl.podWorkers.CouldHaveRunningContainers(pod.UID) && !kubetypes.IsStaticPod(pod) { <del> kl.handlePodResourcesResize(pod) </del> <ins> pod = kl.handlePodResourcesResize(pod) </ins> } }

klog.ErrorS(err, "getNodeAnyway function failed") return false, nil, "" } <ins> podCopy := pod.DeepCopy() </ins> cpuAvailable := node.Status.Allocatable.Cpu().MilliValue() memAvailable := node.Status.Allocatable.Memory().Value() <del> cpuRequests := resource.GetResourceRequest(pod, v1.ResourceCPU) memRequests := resource.GetResourceRequest(pod, v1.ResourceMemory) </del> <ins> cpuRequests := resource.GetResourceRequest(podCopy, v1.ResourceCPU) memRequests := resource.GetResourceRequest(podCopy, v1.ResourceMemory) </ins> if cpuRequests > cpuAvailable || memRequests > memAvailable { <del> klog.V(3).InfoS("Resize is not feasible as request exceeds allocatable node resources", "pod", pod.Name) return false, nil, v1.PodResizeStatusInfeasible </del> <ins> klog.V(3).InfoS("Resize is not feasible as request exceeds allocatable node resources", "pod", podCopy.Name) return false, podCopy, v1.PodResizeStatusInfeasible </ins> } // Treat the existing pod needing resize as a new pod with desired resources seeking admit.

} } <del> if ok, failReason, failMessage := kl.canAdmitPod(otherActivePods, pod); !ok { </del> <ins> if ok, failReason, failMessage := kl.canAdmitPod(otherActivePods, podCopy); !ok { </ins> // Log reason and return. Let the next sync iteration retry the resize <del> klog.V(3).InfoS("Resize cannot be accommodated", "pod", pod.Name, "reason", failReason, "message", failMessage) return false, nil, v1.PodResizeStatusDeferred </del> <ins> klog.V(3).InfoS("Resize cannot be accommodated", "pod", podCopy.Name, "reason", failReason, "message", failMessage) return false, podCopy, v1.PodResizeStatusDeferred </ins> } <del> podCopy := pod.DeepCopy() </del> for _, container := range podCopy.Spec.Containers { idx, found := podutil.GetIndexOfContainerStatus(podCopy.Status.ContainerStatuses, container.Name) if found {

return true, podCopy, v1.PodResizeStatusInProgress } <del> func (kl *Kubelet) handlePodResourcesResize(pod *v1.Pod) { </del> <ins> func (kl *Kubelet) handlePodResourcesResize(pod *v1.Pod) *v1.Pod { </ins> if pod.Status.Phase != v1.PodRunning { <del> return </del> <ins> return pod </ins> } podResized := false for _, container := range pod.Spec.Containers {

} } if !podResized { <del> return </del> <ins> return pod </ins> } kl.podResizeMutex.Lock() defer kl.podResizeMutex.Unlock() fit, updatedPod, resizeStatus := kl.canResizePod(pod) <ins> if updatedPod == nil { return pod } </ins> if fit { // Update pod resource allocation checkpoint if err := kl.statusManager.SetPodAllocation(updatedPod); err != nil { //TODO(vinaykul,InPlacePodVerticalScaling): Can we recover from this in some way? Investigate <del> klog.ErrorS(err, "SetPodAllocation failed", "pod", klog.KObj(pod)) </del> <ins> klog.ErrorS(err, "SetPodAllocation failed", "pod", klog.KObj(updatedPod)) return pod </ins> } <del> *pod = *updatedPod </del> } if resizeStatus != "" { // Save resize decision to checkpoint <del> if err := kl.statusManager.SetPodResizeStatus(pod.UID, resizeStatus); err != nil { </del> <ins> if err := kl.statusManager.SetPodResizeStatus(updatedPod.UID, resizeStatus); err != nil { </ins> //TODO(vinaykul,InPlacePodVerticalScaling): Can we recover from this in some way? Investigate <del> klog.ErrorS(err, "SetPodResizeStatus failed", "pod", klog.KObj(pod)) </del> <ins> klog.ErrorS(err, "SetPodResizeStatus failed", "pod", klog.KObj(updatedPod)) return pod </ins> } <del> pod.Status.Resize = resizeStatus </del> <ins> updatedPod.Status.Resize = resizeStatus </ins> } <del> kl.podManager.UpdatePod(pod) kl.statusManager.SetPodStatus(pod, pod.Status) return </del> <ins> kl.podManager.UpdatePod(updatedPod) kl.statusManager.SetPodStatus(updatedPod, updatedPod.Status) return updatedPod </ins> } // LatestLoopEntryTime returns the last time in the sync loop monitor.

tt.pod.Spec.Containers[0].Resources.Requests = tt.newRequests tt.pod.Status.ContainerStatuses[0].AllocatedResources = v1.ResourceList{v1.ResourceCPU: cpu1000m, v1.ResourceMemory: mem1000M} kubelet.handlePodResourcesResize(tt.pod) <del> assert.Equal(t, tt.expectedAllocations, tt.pod.Status.ContainerStatuses[0].AllocatedResources, tt.name) assert.Equal(t, tt.expectedResize, tt.pod.Status.Resize, tt.name) </del> <ins> updatedPod, found := kubelet.podManager.GetPodByName(tt.pod.Namespace, tt.pod.Name) assert.True(t, found, "expected to find pod %s", tt.pod.Name) assert.Equal(t, tt.expectedAllocations, updatedPod.Status.ContainerStatuses[0].AllocatedResources, tt.name) assert.Equal(t, tt.expectedResize, updatedPod.Status.Resize, tt.name) </ins> testKubelet.fakeKubeClient.ClearActions() } }