Skip to content

Pod level in place pod resize - alpha#132919

Merged
k8s-ci-robot merged 16 commits intokubernetes:masterfrom
ndixita:pod-level-in-place-pod-resize
Nov 12, 2025
Merged

Pod level in place pod resize - alpha#132919
k8s-ci-robot merged 16 commits intokubernetes:masterfrom
ndixita:pod-level-in-place-pod-resize

Conversation

@ndixita
Copy link
Copy Markdown
Contributor

@ndixita ndixita commented Jul 13, 2025

What type of PR is this?

/kind feature

/kind api-change

What this PR does / why we need it:

This PR adds support for IPPR + Pod Level resources to allow in place resizing of pod-level resources in alpha stage.

Which issue(s) this PR is related to:

Issue: kubernetes/enhancements#5419

Reference KEPs when applicable in addition to specific issues.

KEP: https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/5419-pod-level-resources-in-place-resize/README.md
https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/2837-pod-level-resource-spec/README.md

Does this PR introduce a user-facing change?

This change allows In Place Resize of Pod Level Resources 
- Add Resources in PodStatus to capture resources set at pod-level cgroup
- Add AllocatedResources in PodStatus to capture resources requested in the PodSpec

@k8s-ci-robot
Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@k8s-ci-robot k8s-ci-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/needs-kind Indicates a PR lacks a `kind/foo` label and requires one. do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Jul 13, 2025
@k8s-ci-robot
Copy link
Copy Markdown
Contributor

This issue is currently awaiting triage.

If a SIG or subproject determines this is a relevant issue, they will accept it by applying the triage/accepted label and provide further guidance.

The triage/accepted label can be added by org members by writing /triage accepted in a comment.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot added needs-priority Indicates a PR lacks a `priority/foo` label and requires one. area/code-generation kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. sig/apps Categorizes an issue or PR as relevant to SIG Apps. and removed do-not-merge/needs-kind Indicates a PR lacks a `kind/foo` label and requires one. do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Jul 13, 2025
@github-project-automation github-project-automation Bot moved this to Needs Triage in SIG Apps Jul 13, 2025
@ndixita
Copy link
Copy Markdown
Contributor Author

ndixita commented Jul 13, 2025

/ok-to-test

@k8s-ci-robot k8s-ci-robot added the ok-to-test Indicates a non-member PR verified by an org member that is safe to test. label Jul 13, 2025
@ndixita ndixita force-pushed the pod-level-in-place-pod-resize branch 4 times, most recently from 1c21c5b to b2b7220 Compare July 14, 2025 17:39
@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. area/test sig/node Categorizes an issue or PR as relevant to SIG Node. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jul 14, 2025
@tallclair
Copy link
Copy Markdown
Member

The WiFi isn't working at the conference, so I won't be able to review this until I get back to my hotel room tonight.

@natasha41575 can you help review today? If you lgtm I'll try to just approve tonight.

// comparison (DeepEqual) against oldPod.Spec. If the specs match after masking,
// it guarantees that no changes were made other than the allowed resource modifications
// needed for the resize.
func validatePodLevelResourcesResize(newPod, oldPod *core.Pod, podSpecToMutate *core.PodSpec, specPath *field.Path, opts PodValidationOptions) field.ErrorList {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add some of these cases to the e2e tests in test/e2e/common/node/pod_resize.go, in doPodResizePatchErrorTests

// owner: @ndixita
// kep: https://kep.k8s.io/5419
//
// Enables specifying resources at pod-level.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update the description

GetContainerResources(podUID types.UID, containerName string) (v1.ResourceRequirements, bool)
GetPodResourceInfoMap() PodResourceInfoMap
GetPodResourceInfo(podUID types.UID) (PodResourceInfo, bool)
GetPodLevelResources(podUID types.UID) (*v1.ResourceRequirements, bool)
Copy link
Copy Markdown
Contributor

@natasha41575 natasha41575 Nov 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(tiny optional nit) the analogous GetContainerResources returns (v1.ResourceRequirements, bool), should we keep it consistent and have the same return values?

type writer interface {
SetContainerResources(podUID types.UID, containerName string, resources v1.ResourceRequirements) error
SetPodResourceInfo(podUID types.UID, resourceInfo PodResourceInfo) error
SetPodLevelResources(podUID types.UID, alloc *v1.ResourceRequirements) error
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar comment here


podInfo, ok := s.podResources[podUID]
if !ok {
podInfo.PodLevelResources = &v1.ResourceRequirements{}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this line do anything? You are immediately overwriting it in the next line

expectPodSyncTriggered: "true",
},
{
name: "pod-level: Request CPU and memory increase - expect InProgress",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding these cases. They look good. I would like to request one or two cases with both pod level and container level resources

Comment on lines +732 to +734
if tt.inPlacePodLevelResizeEnabled {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.InPlacePodLevelResourcesVerticalScaling, true)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see a few other places actually where the same comment applies, you can update them all

Suggested change
if tt.inPlacePodLevelResizeEnabled {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.InPlacePodLevelResourcesVerticalScaling, true)
}
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.InPlacePodLevelResourcesVerticalScaling, tt.inPlacePodLevelResizeEnabled)

Comment on lines +2251 to +2252
// testPods[0] has the highest priority, as it doesn't increase resource requests (pod-level).
// testPods[1] has the next highest priority, as it doesn't increase resource requests (container-level).
Copy link
Copy Markdown
Contributor

@natasha41575 natasha41575 Nov 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(nonblocking)

  1. Is the pod with pod-level resources being prioritied over the pod with container-level resources intentional? (I think the answer is and should be no, they are equal priority and either being first is acceptable) Let's leave a comment to state as such

  2. What I want this test to cover is that the resize of pod-level resources is taken into account when determining priority. As in, resizes that do not increase any requests are prioritized over resizes that do increase pod-level requests. To that end, I think some of the other pods should be converted to using pod-level resources. One option to ensure all our bases are covered:

  • testPods[2] should have both pod and container-level resources specified, with only pod-level resources being increased
  • testPods[3] should be converted to having only pod-level resources, with the resize increasing them
  • testPods[4] should have both pod and container-level resources, with the resize increasing only container-level resources
  • testPods[5] and testPods[6] cover the case of only container-level resources being specified and resized.

currentResources := containerResourcesFromRequirements(&actuatedResources)
var actuatedPodResources *v1.ResourceRequirements
if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodLevelResourcesVerticalScaling) {
actuatedPodResources, _ = m.actuatedState.GetPodLevelResources(pod.UID)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to check the return value of found here (similar to what we do with container resources above)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just used for logging, but probably good to know?

Comment on lines +2107 to +2111
if m.isContainerResourceResizeInProgress(allocatedPod, podStatus) {
return true
}

return m.isPodLevelResourcesResizeInProgress(allocatedPod, podStatus)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional nit, just a personal style preference

Suggested change
if m.isContainerResourceResizeInProgress(allocatedPod, podStatus) {
return true
}
return m.isPodLevelResourcesResizeInProgress(allocatedPod, podStatus)
return m.isContainerResourceResizeInProgress(allocatedPod, podStatus) || m.isPodLevelResourcesResizeInProgress(allocatedPod, podStatus)

// b) api-server in services doesn't start with --enable-admission-plugins=ResourceQuota
// and is not possible to start it from TEST_ARGS
// Above tests in test/e2e/node/pod_resize.go
var _ = SIGDescribe("Pod InPlace Resize Container", func() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#132919 (comment)

I don't want to change this here because this description is included in the name of the test in conformance.yaml (see https://github.com/kubernetes/kubernetes/pull/135067/files)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i.e. make sure there's no diff when you run ./hack/update-conformance.sh

Copy link
Copy Markdown
Contributor

@natasha41575 natasha41575 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The WiFi isn't working at the conference, so I won't be able to review this until I get back to my hotel room tonight.

@natasha41575 can you help review today? If you lgtm I'll try to just approve tonight.

I'm out of time today. I have a few outstanding comments here and also above but besides this I think this largely LGTM if those are addressed

I will also add a caveat that I did not get around to looking at the e2e tests super carefully after they were updated to make everything pass - so that still needs another eye on it.

Comment thread pkg/kubelet/kuberuntime/kuberuntime_manager.go
return resizeResult
}

updateActuatedPodLevelResources := func(resourceName v1.ResourceName) error {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to move this function definition to right before it's called (L903) so that the code block is within the FG?

Comment thread test/e2e/common/node/pod_level_resources_resize.go Outdated
Comment thread test/e2e/node/pod_resize.go Outdated
@tallclair
Copy link
Copy Markdown
Member

/hold
Just to gate the merge. I'll remove the hold with my LGTM.

Signed-off-by: ndixita <[email protected]>
Copy link
Copy Markdown
Member

@tallclair tallclair left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Were you going to pull #135203 into this PR?

I don't think any of the outstanding feedback is blocking for alpha. I'll take another look in a couple hours. In the meantime, try to track down the missing approvals.

@liggitt I think this is ready for your approval.

/approve


podWithoutContainerResources := pod.DeepCopy()
podWithoutContainerResources.Spec.Containers[0].Resources = v1.ResourceRequirements{}
podWithoutContainerResources.Spec.InitContainers[0].Resources = v1.ResourceRequirements{}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the pod has 2 regular containers and 2 init containers. Also, did you mean for this pod to have pod-level resources?

Comment thread pkg/kubelet/util/util.go
// The implementation of CPU/Memory limit calculation is duplicated here and in
// pkg/kubelet/kuberuntime/kuberuntime_container_linux.go (getCPULimits/getMemoryLimits).
// Refactor into a shared utility function.
func GetLimits(res *ResourceOpts) v1.ResourceList {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: why the ResourceOpts struct, rather than just passing 2 parameters?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While testing I swapped the two params :| so for clarity or I could pass container resources as the v1.ResourceRequirements and pod resources as *v1.ResourceRequirements.

currentResources := containerResourcesFromRequirements(&actuatedResources)
var actuatedPodResources *v1.ResourceRequirements
if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodLevelResourcesVerticalScaling) {
actuatedPodResources, _ = m.actuatedState.GetPodLevelResources(pod.UID)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just used for logging, but probably good to know?


if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodLevelResourcesVerticalScaling) {
if err = updateActuatedPodLevelResources(rName); err != nil {
logger.Error(err, "Failed to update pod-level actuated resources", "resource", rName, "pod", klog.KObj(pod))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still need to address this.

return nil
}

if actuatedPod.Spec.Resources == nil {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this and the nil check below seem unnecessary.

if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodLevelResourcesVerticalScaling) {
apiPodStatus.Resources = kl.convertToAPIPodLevelResourcesStatus(pod, oldPodStatus)
opts := resourcehelper.PodResourcesOptions{
SkipPodLevelResources: !utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should exclude overhead, right?

}

func (kl *Kubelet) convertToAPIPodLevelResourcesStatus(allocatedPod *v1.Pod, oldPodStatus v1.PodStatus) *v1.ResourceRequirements {
if allocatedPod.Status.Phase != v1.PodRunning {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we discussed just leaving the actual resources unset when the pod isn't running?

if !opts.SkipPodLevelResources && IsPodLevelRequestsSet(pod) {

var effectiveReqs v1.ResourceList
if opts.InPlacePodLevelResourcesVerticalScalingEnabled && opts.UseStatusResources {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes should have unit test coverage.

},
}

if podResources != nil {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: nil check is unnecessary

@liggitt
Copy link
Copy Markdown
Member

liggitt commented Nov 12, 2025

/approve
for API bits

looks like lint / verify has some cleanup to make happy

Comment thread test/e2e/common/node/pod_level_resources_resize.go Outdated
Comment thread test/e2e/common/node/pod_level_resources_resize.go Outdated
@ndixita
Copy link
Copy Markdown
Contributor Author

ndixita commented Nov 12, 2025

/test pull-kubernetes-unit-windows-master

Signed-off-by: ndixita <[email protected]>
@ndixita
Copy link
Copy Markdown
Contributor Author

ndixita commented Nov 12, 2025

/retest

1 similar comment
@ndixita
Copy link
Copy Markdown
Contributor Author

ndixita commented Nov 12, 2025

/retest

@ndixita
Copy link
Copy Markdown
Contributor Author

ndixita commented Nov 12, 2025

/test pull-kubernetes-node-e2e-containerd

@k8s-ci-robot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: dom4ha, liggitt, ndixita, tallclair

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ndixita
Copy link
Copy Markdown
Contributor Author

ndixita commented Nov 12, 2025

/test pull-kubernetes-e2e-gce

@ndixita
Copy link
Copy Markdown
Contributor Author

ndixita commented Nov 12, 2025

/retest

@k8s-ci-robot
Copy link
Copy Markdown
Contributor

k8s-ci-robot commented Nov 12, 2025

@ndixita: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
pull-kubernetes-node-e2e-restartallcontainers c2f8fec link false /test pull-kubernetes-node-e2e-restartallcontainers
pull-kubernetes-node-kubelet-inplace-pod-level-resources-resize e687175 link false /test pull-kubernetes-node-kubelet-inplace-pod-level-resources-resize
pull-kubernetes-conformance-image-test eed667f link false /test pull-kubernetes-conformance-image-test

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@ndixita
Copy link
Copy Markdown
Contributor Author

ndixita commented Nov 12, 2025

/test pull-kubernetes-e2e-gce

Comment on lines +51 to +54
if oldPodInfo.Spec.Resources == nil && newPodInfo.Spec.Resources == nil {
return false
}
return !reflect.DeepEqual(oldPodInfo.Spec.Resources, newPodInfo.Spec.Resources)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't catch this before, but I think we forbid updating a pod with pod-level-resources before? So can this logic just be:

Suggested change
if oldPodInfo.Spec.Resources == nil && newPodInfo.Spec.Resources == nil {
return false
}
return !reflect.DeepEqual(oldPodInfo.Spec.Resources, newPodInfo.Spec.Resources)
return oldPodInfo.Spec.Resources != nil || newPodInfo.Spec.Resources != nil

If we do need the resource comparison, it should use api.Semantic.DeepEqual instead.

@tallclair
Copy link
Copy Markdown
Member

/lgtm

Some follow-up to do, but I think this is good enough for alpha.

@k8s-ci-robot
Copy link
Copy Markdown
Contributor

LGTM label has been added.

DetailsGit tree hash: 87219c958ab2fc2dea5777e8039fae6ced1de7d4

@tallclair
Copy link
Copy Markdown
Member

/hold cancel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api-review Categorizes an issue or PR as actively needing an API review. approved Indicates a PR has been approved by an approver from all required OWNERS files. area/code-generation area/e2e-test-framework Issues or PRs related to refactoring the kubernetes e2e test framework area/kubectl area/kubelet area/stable-metrics Issues or PRs involving stable metrics area/test cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API lgtm "Looks good to me", indicates that a PR is ready to be merged. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. sig/apps Categorizes an issue or PR as relevant to SIG Apps. sig/architecture Categorizes an issue or PR as relevant to SIG Architecture. sig/auth Categorizes an issue or PR as relevant to SIG Auth. sig/cli Categorizes an issue or PR as relevant to SIG CLI. sig/instrumentation Categorizes an issue or PR as relevant to SIG Instrumentation. sig/node Categorizes an issue or PR as relevant to SIG Node. sig/scheduling Categorizes an issue or PR as relevant to SIG Scheduling. sig/testing Categorizes an issue or PR as relevant to SIG Testing. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

Status: API review completed, 1.35
Archived in project
Archived in project
Archived in project
Archived in project
Archived in project
Archived in project

Development

Successfully merging this pull request may close these issues.