Skip to content

feat: support pod-level resources (KEP-2837) - #5059

Open
washcycle wants to merge 6 commits into
armadaproject:masterfrom
washcycle:pod-level-resources
Open

feat: support pod-level resources (KEP-2837)#5059
washcycle wants to merge 6 commits into
armadaproject:masterfrom
washcycle:pod-level-resources

Conversation

@washcycle

Copy link
Copy Markdown

Adds optional support for Kubernetes pod-level resources (podSpec.resources), gated by submission.podLevelResources (default false).

When enabled:

  • submit validation lets a container omit its own resources if the pod declares a pod-level block
  • resource accounting (TotalPodResourceRequest, SchedulingResourceRequirementsFromPodSpec) uses the effective request max(sum(container requests), pod-level request)
  • the pod-level block is filtered through the scheduler resource allow-list
  • Lookout reports the effective footprint

Default false preserves current behaviour; the accounting branches are inert unless podSpec.resources is set.

Requires the executor cluster's apiserver to have the PodLevelResources feature gate enabled (k8s 1.32 alpha, 1.34+ beta).

Tests added for validation and accounting. Opening as draft for feedback on approach.

Add optional support for Kubernetes pod-level resources (podSpec.resources),
gated by submission.podLevelResources (default false).

When enabled, a container may omit its own resources if the pod declares a
pod-level block, and resource accounting uses the effective request
max(sum(container requests), pod-level request). Also filters the pod-level
block through the scheduler resource allow-list and reports it in Lookout.

Signed-off-by: Matt Landowski <matthew.landowski@apqx.com>
@washcycle
washcycle marked this pull request as ready for review July 28, 2026 12:38
Comment thread pkg/api/util.go
Comment thread internal/server/submit/validation/submit_request.go Outdated
Comment thread internal/scheduler/api.go
@greptile-apps

greptile-apps Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds feature-gated Kubernetes pod-level resource support across submission, accounting, lease filtering, and Lookout reporting.

  • Clears pod-level resources during conversion when the feature is disabled.
  • Computes effective requests and limits as the maximum of container-derived and pod-level resources.
  • Validates pod-level resource blocks and filters them through the executor resource allow-list.
  • Updates Lookout resource extraction and adds accounting and validation tests.

Confidence Score: 4/5

The PR is not yet safe to merge because lease-time filtering can remove the pod’s only resource budget and per-container minimum validation still rejects valid effective requests.

The disabled-accounting and raw pod-level minimum issues are fixed, but two previously reported failures remain: resource allow-list filtering can leave resource-less containers with an empty pod-level block immediately before lease delivery, and successful effective-request validation is still followed by independent per-container minimum checks.

Files Needing Attention: internal/scheduler/api.go; internal/server/submit/validation/submit_request.go

Important Files Changed

Filename Overview
internal/server/submit/validation/submit_request.go Adds pod-level validation and effective-request minimum checking while retaining existing container validation.
internal/server/submit/conversion/post_process.go Removes pod-level resources before downstream processing when the feature is disabled.
internal/scheduler/api.go Extends lease-time resource allow-list filtering to pod-level requests and limits.
pkg/api/util.go Includes pod-level requests and limits in canonical scheduling resource calculations.
internal/common/resource/resource.go Includes pod-level requests in total pod request accounting.
internal/lookoutingester/instructions/instructions.go Uses the canonical effective scheduling requirements when recording Lookout resource fields.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Server
    participant Scheduler
    participant Executor
    participant Lookout
    Client->>Server: Submit pod with pod-level resources
    Server->>Server: Validate and feature-gate resources
    Server->>Scheduler: Publish processed job
    Scheduler->>Scheduler: Account effective resource maximum
    Scheduler->>Executor: Filter resources and send lease
    Server-->>Lookout: Project effective footprint
Loading

Reviews (6): Last reviewed commit: "test: make pod-level resource tests tabl..." | Re-trigger Greptile

- clear podSpec.resources in post-processing when the feature is disabled, so
  disabled pod-level values no longer affect scheduler/Lookout accounting
- check MinJobResources against the effective request max(pod-level, container
  sum) rather than the raw pod-level value, so a pod whose container total meets
  the minimum is not wrongly rejected

Addresses review feedback on armadaproject#5059.

Signed-off-by: Matt Landowski <matthew.landowski@apqx.com>
@washcycle

Copy link
Copy Markdown
Author

Thanks for the review. Addressed in 4157310:

1. Disabled resources still affect accounting — fixed. Added a dropPodLevelResourcesIfDisabled post-processor that clears podSpec.resources when submission.podLevelResources is false, so all downstream accounting (scheduler + Lookout) ignores it when the feature is off. This keeps the accounting helpers gate-free while making disabled fully inert.

2. Minimum checks ignore effective requests — fixed. MinJobResources is now checked against the effective request max(pod-level, sum(container requests)) via SchedulingResourceRequirementsFromPodSpec, so a 5-CPU container + 2-CPU pod-level request is no longer rejected under a 4-CPU minimum. Added a test for both the accept and reject cases.

3. Filtering can erase the pod budget — this mirrors the existing container-level behaviour: the allow-list intentionally strips floating resources before the pod reaches k8s while the scheduler retains them for accounting. Applying a different rule only to the pod-level block would be inconsistent with how container resources are already handled. Open to a follow-up if you'd prefer a revalidation step, but I kept it consistent with the current container path for now.

Tests added for 1 and 2.

Comment thread internal/common/resource/resource_test.go
washcycle and others added 2 commits August 13, 2026 07:56
Convert TestTotalResourceRequest_PodLevelResources and
TestDropPodLevelResourcesIfDisabled from sequential t.Run blocks to the
map-based table style used elsewhere in these packages, and add a case
covering an unset pod-level block in the post-processor.

Signed-off-by: Matt Landowski <matthew.landowski@apqx.com>
@washcycle

Copy link
Copy Markdown
Author

@dejanzele how does that look now?

"container total meets minimum, low pod-level ok": {
req: req(&v1.ResourceRequirements{Requests: cpu("2"), Limits: cpu("2")}, container5),
expectSuccess: 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.

Hey I think greptile was correct here. If you define:

container2 := []v1.Container{{Name: "main", Resources: v1.ResourceRequirements{Requests: cpu("2"), Limits: cpu("2")}}}

And add test:

"container below minimum covered by pod-level block, accepted": {
  req:           req(&v1.ResourceRequirements{Requests: cpu("4"), Limits: cpu("4")}, container2),
   expectSuccess: true,
 },

container 2cpu + pod-level 4cpu -> effective max(2,4)=4cpu >= 4cpu min, but the per-container minimum check only sees the container's raw 2cpu and rejects.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants