KEP-6386: Ephemeral Storage Support for Pod-Level Resource Specifications
KEP-6386: Ephemeral Storage Support for Pod-Level Resource Specifications
- Release Signoff Checklist
- Summary
- Motivation
- Proposal
- Design Details
- Production Readiness Review Questionnaire
- Implementation History
- Drawbacks
- Alternatives
- Infrastructure Needed (Optional)
Release Signoff Checklist
Items marked with (R) are required prior to targeting to a milestone / release.
- (R) Enhancement issue in release milestone, which links to KEP dir in kubernetes/enhancements (not the initial KEP PR)
- (R) KEP approvers have approved the KEP status as
implementable - (R) Design details are appropriately documented
- (R) Test plan is in place, giving consideration to SIG Architecture and SIG Testing input (including test refactors)
- e2e Tests for all Beta API Operations (endpoints)
- (R) Ensure GA e2e tests meet requirements for Conformance Tests
- (R) Minimum Two Week Window for GA e2e tests to prove flake free
- (R) Graduation criteria is in place
- (R) all GA Endpoints must be hit by Conformance Tests within one minor version of promotion to GA
- (R) Production readiness review completed
- (R) Production readiness review approved
- “Implementation History” section is up-to-date for milestone
- User-facing documentation has been created in kubernetes/website , for publication to kubernetes.io
- Supporting documentation—e.g., additional design documents, links to mailing list discussions/SIG meetings, relevant PRs/issues, release notes
Summary
KEP-2837: Pod Level Resource Specifications
introduced the resources field at the PodSpec level (pod.spec.resources), allowing users to define aggregate compute resource requests and limits shared across all containers in a Pod. However, KEP-2837 initially scoped support strictly to CPU, memory, and hugepages-*, deferring ephemeral-storage to a future enhancement.
This KEP proposes extending Pod-Level Resource Specifications to support ephemeral-storage (pod.spec.resources.requests[ephemeral-storage] and pod.spec.resources.limits[ephemeral-storage]), gated by a new dedicated feature gate: PodLevelResourcesEphemeralStorage. This aligns ephemeral storage with KEP-2837 and allows multi-container Pods to manage a unified Pod-level ephemeral storage budget across container writable layers, container logs, and disk-backed emptyDir volumes.
Motivation
Kubernetes workloads often consist of multiple containers collaborating within a Pod. While container-level resource specifications allow granular control per container, estimating and allocating ephemeral-storage for each individual container in a multi-container Pod is challenging:
- Pod-Scoped Shared Storage (
emptyDir): Unlike CPU and memory, ephemeral storage includes disk-backedemptyDirvolumes (medium: "") that are defined at the Pod level and shared across multiple containers. With only container-level specifications, users cannot naturally attribute sharedemptyDirstorage to the Pod as a whole and are forced to arbitrarily assign or split the storage request and limit across individual containers. - Avoiding Unintended Whole-Pod Limits from Injected Sidecars: Kubelet’s Pod-level ephemeral storage eviction (
podEphemeralStorageLimitEviction) calculates a Pod’s total ephemeral storage limit by summing the declared container-level limits across the Pod. If an injected sidecar declares anephemeral-storagelimit while the primary application containers omit it, the sidecar’s limit unintentionally becomes the effective ephemeral storage limit for the entire Pod (bounding the main containers and any sharedemptyDirvolumes). Allowingephemeral-storageto be specified directly at the Pod level avoids this pitfall. - Shared Pod-Level Limit Without Per-Container Limit Over-Allocation: Kubelet enforces container-level
ephemeral-storagelimits against each individual container’s writable layer and logs (containerEphemeralStorageLimitEviction), in addition to enforcing the sum of container limits against the Pod’s total usage. When multiple containers experience staggered peaks in ephemeral storage usage (e.g., two containers each peaking at10Giat different times while combined usage never exceeds15Gi), setting10Gicontainer-level limits on each container results in an aggregated20GiPod limit (and a20Gidefaulted Pod request if requests are not separately specified), whereas a Pod-level specification allows bounding and reserving15Gifor the Pod as a whole.
Supporting ephemeral-storage requests and limits at the Pod level (pod.spec.resources) complements existing container-level settings by allowing containers within a Pod to share a unified ephemeral storage budget while bounding the Pod’s total disk consumption.
Goals
- Relax Pod API validation and update defaulting to allow specifying
ephemeral-storagerequests and limits at the Pod level (pod.spec.resources), gated by thePodLevelResourcesEphemeralStoragefeature gate. - Update Pod resource helpers (
k8s.io/component-helpers/resourceandpkg/apis/core/helper) andLimitRangerto support Pod-levelephemeral-storagealongside existing container-levelephemeral-storagespecifications,emptyDir.sizeLimit, andResourceQuota. - Wire
PodLevelResourcesEphemeralStorageintokube-schedulerand Kubelet’s eviction manager (viaresourcehelper.PodRequestsandresourcehelper.PodLimits) so Pod-levelephemeral-storagerequests and limits are accounted for and enforced.
Non-Goals
- No Changes to Ephemeral Storage Accounting: Any changes to how
ephemeral-storageusage is measured or which storage types are accounted against it (container writable layers, container logs, and disk-backedemptyDirvolumes; excluding memory-backedtmpfsemptyDirvolumes, PVCs,hostPath, and CSI volumes) are out of scope. - No In-Place Resizing of
ephemeral-storage: In-place resizing of container-level or Pod-levelephemeral-storagerequests and limits at runtime is out of scope. - No Changes to Pod QoS Class Calculation: As with container-level
ephemeral-storage, Pod-levelephemeral-storagedoes not participate in Pod QoS class determination (Guaranteed,Burstable,BestEffort).
Proposal
When the PodLevelResourcesEphemeralStorage and PodLevelResources feature gates are enabled, users can specify ephemeral-storage in pod.spec.resources.requests and pod.spec.resources.limits.
User Stories
Story 1
Multi-Container Pod Sharing Disk-Backed emptyDir: A data processing Pod uses an initContainer (data-fetcher) to download raw dataset files into a shared disk-backed emptyDir volume, a main container (processor) that transforms the data and writes intermediate scratch files to its writable layer, and a sidecar (log-shipper) that processes logs.
Instead of arbitrarily inflating one container’s ephemeral storage request to account for the shared emptyDir, the user specifies ephemeral-storage directly at the Pod level:
apiVersion: v1
kind: Pod
metadata:
name: data-pipeline-pod
spec:
resources:
requests:
ephemeral-storage: "10Gi"
limits:
ephemeral-storage: "20Gi"
volumes:
- name: shared-data
emptyDir: {}
initContainers:
- name: data-fetcher
image: fetcher:latest
volumeMounts:
- name: shared-data
mountPath: /data
containers:
- name: processor
image: processor:latest
volumeMounts:
- name: shared-data
mountPath: /data
- name: log-shipper
image: shipper:latest
resources:
limits:
ephemeral-storage: "2Gi" # Optional per-container ceiling for shipper's rootfs + logs
Here, kube-scheduler reserves 10Gi of ephemeral-storage on the node for the entire Pod. At runtime, Kubelet ensures that the aggregate disk usage of all container writable layers, container logs, and the shared-data emptyDir volume does not exceed 20Gi, while also enforcing that log-shipper’s individual writable layer + logs do not exceed 2Gi.
Story 2
Bounding Volume Spikes with Individual emptyDir.sizeLimit and Pod Limit: A Pod mounts two disk-backed emptyDir volumes (cache-dir with sizeLimit: 5Gi and scratch-dir without sizeLimit) and sets pod.spec.resources.limits[ephemeral-storage]: 8Gi. Kubelet enforces that cache-dir never exceeds 5Gi, while total Pod ephemeral storage usage (both volumes + container rootfs layers + logs) never exceeds 8Gi.
Notes/Constraints/Caveats (Optional)
- Storage Types Governed:
Pod-level
ephemeral-storagegoverns:- Container writable layers (e.g.,
overlayfsupperdir). - Container
stdout/stderrlogs (/var/log/pods/<pod-uid>/...). - Disk-backed
emptyDirvolumes (medium: ""on local disk). It explicitly excludes memory-backedemptyDirvolumes (medium: Memory) and CSI/PVC persistent volumes.
- Container writable layers (e.g.,
Risks and Mitigations
- Opt-In Rollout Safety: Since Pod-level
ephemeral-storageis an opt-in feature guarded byPodLevelResourcesEphemeralStorage, merging and enabling the feature does not affect existing workloads that specify container-level resources. - Third-Party Tools and Custom Controllers: External tools, custom schedulers, or monitoring agents that calculate Pod ephemeral storage requirements by summing
pod.spec.containers[*].resourcesdirectly (instead of usingpod.spec.resourcesork8s.io/component-helpers/resource) may underestimate a Pod’s ephemeral storage reservation or limit when only Pod-level resources are specified.- Mitigation: Update
k8s.io/component-helpers/resource(PodRequestsandPodLimits) so ecosystem components consuming standard Kubernetes helpers automatically support Pod-levelephemeral-storage, and clearly document the behavior in release notes.
- Mitigation: Update
- Asynchronous Eviction Polling Latency: Kubelet enforces
pod.spec.resources.limits[ephemeral-storage]asynchronously via its eviction manager polling loop (housekeeping-interval), allowing brief bursts above the limit before eviction.- Mitigation: This matches existing Kubernetes container-level
ephemeral-storagelimit enforcement behavior.
- Mitigation: This matches existing Kubernetes container-level
Design Details
Feature Gate
A new feature gate PodLevelResourcesEphemeralStorage will be introduced across kube-apiserver, kube-scheduler, and kubelet:
- Name:
PodLevelResourcesEphemeralStorage - Default:
false(Alpha) - Stage: Alpha in v1.38
- Dependencies:
PodLevelResources(GA in v1.37) andLocalStorageCapacityIsolation(GA in v1.25).
PodSpec API Changes
With PodLevelResourcesEphemeralStorage enabled, ephemeral-storage is supported under pod.spec.resources.requests and pod.spec.resources.limits:
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
resources:
requests:
ephemeral-storage: "2Gi"
limits:
ephemeral-storage: "5Gi"
PodSpec Validation & Defaulting Rules
Pod-level ephemeral-storage follows the same validation, defaulting, and precedence rules defined in KEP-2837
for CPU and memory:
- Pod-level and Container-level Coexistence:
- When Pod-level
ephemeral-storagerequests or limits are set, Pod-level resource calculations (PodRequestsandPodLimits, used for scheduling,ResourceQuota, disk-pressure eviction ranking, and total Pod limit eviction) use the Pod-level value directly instead of summing container-level values. - At runtime, each container is constrained to the lesser of the Pod-level limit and its container-level limit: if a container specifies a container-level
ephemeral-storagelimit, Kubelet continues to enforce that limit against the container’s individual writable layer and logs (containerEphemeralStorageLimitEviction), while enforcing the Pod-level limit against the aggregate ephemeral storage usage of the Pod (podEphemeralStorageLimitEviction).
- When Pod-level
- Validation Rules:
- The aggregated container-level
ephemeral-storagerequests cannot exceed the Pod-level request or limit. - The sum of container-level
ephemeral-storagelimits may exceed the Pod-level limit, but no single container-level limit can exceed the Pod-level limit.
- The aggregated container-level
- Defaulting Rules:
- Container-level and Pod-level defaulting for
ephemeral-storagefollow the exact same rules as CPU and memory defined in KEP-2837 . emptyDir.sizeLimitdoes not participate in Pod-levelephemeral-storagedefaulting; it remains strictly a per-volume limit enforced at runtime.
- Container-level and Pod-level defaulting for
Scheduler Changes
kube-scheduler already computes pod resource requests via resourcehelper.PodRequests. Once ephemeral-storage is added to the supported pod-level resources in resourcehelper (gated by PodLevelResourcesEphemeralStorage), kube-scheduler will automatically use pod.spec.resources.requests[ephemeral-storage] when specified and fall back to aggregated container requests otherwise.
Eviction Manager
Like container-level ephemeral-storage today, pod-level ephemeral-storage is enforced reactively by Kubelet’s eviction manager during its periodic housekeeping loop (rather than via proactive kernel/cgroup write limits). For ephemeral storage eviction and disk pressure signals, the eviction manager already uses resourcehelper.PodLimits and resourcehelper.PodRequests to compare the pod’s ephemeral storage usage against its effective requests and limits: when pod-level ephemeral-storage requests or limits are specified, it uses the pod-level values directly instead of aggregating container-level values; otherwise, it falls back to aggregating container-level values.
ResourceQuota & LimitRanger
ResourceQuota: Namespacerequests.ephemeral-storageandlimits.ephemeral-storagequotas evaluate pods using their pod-levelephemeral-storagerequests and limits when specified, falling back to aggregated container requests and limits when unspecified.LimitRanger: ForLimitRangeobjects withtype: Pod,LimitRangervalidates that pod-levelephemeral-storagerequests and limits satisfy configuredmin,max, andmaxLimitRequestRatiobounds, and applies pod-leveldefaultanddefaultRequestvalues when unspecified.
Test Plan
[x] I/we understand the owners of the involved components may require updates to existing tests to make this code solid enough prior to committing the changes necessary to implement this enhancement.
Prerequisite testing updates
None required prior to implementation.
Unit tests
Unit tests will be added/updated in the following packages:
pkg/apis/core/validation: Verify validation rules forpod.spec.resources.requests[ephemeral-storage]andlimits[ephemeral-storage](request $\le$ limit, aggregated container requests $\le$ pod request, individual container limits $\le$ pod limit, and allowing aggregated container limits $>$ pod limit).pkg/apis/core/v1: Verify defaulting rules for pod-levelephemeral-storage.staging/src/k8s.io/component-helpers/resource: VerifyPodRequestsandPodLimitsresolve pod-level and container-levelephemeral-storagerequests and limits.pkg/kubelet/eviction:- Verify pod eviction and event message (
Evicted: Pod ephemeral local storage usage (...) exceeds pod-level limit (...)) when total pod usage exceedspod.spec.resources.limits[ephemeral-storage]. - Verify eviction precedence between
emptyDir.sizeLimit, container limit, and pod limit. - Verify disk pressure eviction ranking uses pod-level
ephemeral-storagerequests when specified.
- Verify pod eviction and event message (
pkg/scheduler/framework/plugins/noderesources: VerifyNodeResourcesFitFilter and Score plugins with pod-levelephemeral-storage.pkg/quota/v1/evaluator/coreandplugin/pkg/admission/limitranger: VerifyResourceQuotaandLimitRangerwith pod-levelephemeral-storage.
Current unit test coverage of key touched packages:
k8s.io/kubernetes/pkg/apis/core/validation:2026-09-17-~84%k8s.io/kubernetes/pkg/kubelet/eviction:2026-09-17-~76%k8s.io/component-helpers/resource:2026-09-17-~92%
Integration tests
Integration tests will be added to test/integration:
test/integration/scheduler: Verify Pod scheduling withpod.spec.resources.requests[ephemeral-storage]across nodes with different allocatable ephemeral storage capacities.test/integration/quota: Verify namespaceResourceQuotaadmission and usage tracking forrequests.ephemeral-storageandlimits.ephemeral-storagewith Pod-level specifications.
e2e tests
Node e2e and cluster e2e tests will be added under test/e2e_node/ and test/e2e/common/node/:
- Pod-Level Ephemeral Storage Limit Eviction (
test/e2e_node/eviction_test.go):- Launch a multi-container Pod with
pod.spec.resources.limits[ephemeral-storage]: 100Miand a shared disk-backedemptyDir. - Write
60Mito container writable layer/logs and50MitoemptyDir(total110Mi>100Mi). - Verify Kubelet evicts the Pod with message
Evicted: Pod ephemeral local storage usage (...) exceeds pod-level limit (100Mi).
- Launch a multi-container Pod with
- Eviction Precedence with
emptyDir.sizeLimit(test/e2e_node/eviction_test.go):- Launch a Pod with
pod.spec.resources.limits[ephemeral-storage]: 200Miand anemptyDirwithsizeLimit: 50Mi. - Write
60Mito theemptyDirand verify eviction triggers specifically for breachingemptyDir.sizeLimit(50Mi).
- Launch a Pod with
- Disk Pressure Eviction Priority (
test/e2e_node/eviction_test.go):- Under simulated node disk pressure, verify a Pod whose usage is below
pod.spec.resources.requests[ephemeral-storage]is protected relative to a Pod exceeding its Pod-level request.
- Under simulated node disk pressure, verify a Pod whose usage is below
- Scheduling Fit e2e (
test/e2e/common/node/pod_level_resources.go):- Verify Pods requesting
pod.spec.resources.requests[ephemeral-storage]exceeding node allocatable capacity remainPendingwithInsufficient ephemeral-storage.
- Verify Pods requesting
Graduation Criteria
Alpha
- Feature implemented behind
PodLevelResourcesEphemeralStoragefeature gate (disabled by default). - API validation, defaulting, and resource helpers implemented and unit-tested.
kube-scheduler, Kubelet admission, Kubelet eviction manager (including clear eviction messaging andemptyDir.sizeLimitprecedence),LimitRanger, andResourceQuotaupdated.- Unit, integration, and node e2e tests passing in CI.
Beta
PodLevelResourcesEphemeralStorageenabled by default.- Cluster Autoscaler and Vertical Pod Autoscaler (VPA) compatibility verified.
- All e2e tests running flake-free in TestGrid.
GA
PodLevelResourcesEphemeralStoragegraduated to GA (stable) and locked totrue.- At least two minor releases in Beta with positive operational feedback and zero critical bugs.
- Conformance and e2e tests stable with a minimum two-week flake-free window.
Deprecation
N/A.
Upgrade / Downgrade Strategy
- Upgrade:
- Existing Pods without
pod.spec.resources.requests/limits[ephemeral-storage]experience no behavioral change. - Once
kube-apiserver,kube-scheduler, andkubeletinstances havePodLevelResourcesEphemeralStorageenabled, users can submit Pods with Pod-levelephemeral-storage.
- Existing Pods without
- Downgrade:
- If
PodLevelResourcesEphemeralStorageis disabled onkube-apiserver, new Pod creations or updates specifying Pod-levelephemeral-storageare rejected by validation. - Already running Pods persisted in etcd continue to run; if Kubelet has the feature gate disabled, Kubelet falls back to container-level
ephemeral-storagerequests and limits.
- If
Version Skew Strategy
Pod-level ephemeral-storage specification is an opt-in feature. For this feature to work correctly, PodLevelResourcesEphemeralStorage must be enabled in all parts of the cluster (kube-scheduler, kube-apiserver, kubelet).
When the feature gate is disabled on the control plane, but enabled on kubelet, users will not be able to create Pods with ephemeral-storage in pod.spec.resources.
When the feature gate is enabled on the control plane, but disabled on kubelet, NodeDeclaredFeatures (KEP-5328
) ensures kube-scheduler only schedules Pods with Pod-level ephemeral-storage onto nodes that declare PodLevelResourcesEphemeralStorage in node.status.declaredFeatures, and kubelet will reject those Pods at admission if scheduled onto a node where the feature gate is disabled.
Production Readiness Review Questionnaire
Feature Enablement and Rollback
How can this feature be enabled / disabled in a live cluster?
- Feature gate (also fill in values in
kep.yaml)- Feature gate name:
PodLevelResourcesEphemeralStorage - Components depending on the feature gate:
kubelet,kube-apiserver,kube-scheduler - Will enabling / disabling the feature require downtime of the control plane? No. Once the feature is disabled, control plane components (
kube-apiserver) reject new Pod creations/updates containingephemeral-storageinpod.spec.resources. - Will enabling / disabling the feature require downtime or reprovisioning of a node? No. Once the feature is disabled on
kubelet, Kubelet rejects new Pods with Pod-levelephemeral-storageat admission and falls back to container-levelephemeral-storageaccounting for already admitted Pods. - Note: Requires
PodLevelResources(GA in v1.37) to be enabled.
- Feature gate name:
Does enabling the feature change any default behavior?
For Pods that do not specify pod.spec.resources, enabling PodLevelResourcesEphemeralStorage does not change any default behavior.
For Pods that specify pod.spec.resources (e.g., for cpu or memory) and also specify container-level ephemeral-storage, enabling PodLevelResourcesEphemeralStorage will cause DefaultPodLevelResources to also default ephemeral-storage in pod.spec.resources (requests[ephemeral-storage] to the aggregated container requests, and limits[ephemeral-storage] to the aggregated container limits if all containers specify an ephemeral-storage limit). Because the defaulted Pod-level values match the aggregated container values, scheduling and runtime eviction behavior for these Pods remains unchanged.
Can the feature be disabled once it has been enabled (i.e. can we roll back the enablement)?
Yes (disable-supported: true). When the feature gate is disabled:
- New Pods are not permitted to specify
ephemeral-storageinpod.spec.resources. - For existing Pods that were created with Pod-level
ephemeral-storage,resourcehelper.PodRequestsandresourcehelper.PodLimitsignoreephemeral-storageinpod.spec.resourcesand only consider container-levelephemeral-storagespecifications.
What happens if we reenable the feature if it was previously rolled back?
If PodLevelResourcesEphemeralStorage is re-enabled after being previously disabled:
- Any new Pods will again be able to specify
ephemeral-storageinpod.spec.resources. - For existing Pods with Pod-level
ephemeral-storage,resourcehelper.PodRequestsandresourcehelper.PodLimitswill immediately resume usingpod.spec.resourcesforephemeral-storageacrossResourceQuota,kube-scheduler, andkubelet’s Eviction Manager.
Are there any tests for feature enablement/disablement?
Yes, unit and integration tests cover feature gate toggling:
- Validate that users can set
ephemeral-storageinpod.spec.resourcesonly whenPodLevelResourcesEphemeralStorageis enabled. - Validate that
kube-scheduler(NodeResourcesFit) andk8s.io/component-helpers/resourceconsider Pod-levelephemeral-storagewhen the gate is enabled, and fall back to container-level aggregation when the gate is disabled. - Validate that Kubelet’s Eviction Manager enforces
pod.spec.resources.limits[ephemeral-storage]when enabled, and reverts to container-level limits when disabled. - Confirm that
LimitRangerapplies Pod-leveldefaultRequestanddefaultforephemeral-storagewhen enabled, and ignores them when disabled.
Rollout, Upgrade and Rollback Planning
How can a rollout or rollback fail? Can it impact already running workloads?
Rollouts and rollbacks do not impact existing workloads. During mixed-version rollouts, NodeDeclaredFeatures (KEP-5328
) ensures Pods using Pod-level ephemeral-storage are only scheduled onto nodes with the feature enabled.
What specific metrics should inform a rollback?
Any unusual observations in the following metrics should signal a rollback:
kubelet_evictions{eviction_signal="ephemeralpodfs.limit"}: Unexpected spikes in Pod-level ephemeral storage limit evictions after enabling the feature (alongsideephemeralcontainerfs.limitandemptydirfs.limit).node_collector_evictions_total: Node-level eviction anomalies.started_pods_errors_total: Exposed by Kubelet to detect unusual spikes in Pod startup failures.started_containers_errors_total: Exposed by Kubelet to detect unusual spikes in container startup failures.scheduler_pending_pods: Number of pending Pods in theunschedulablequeue to detect scheduling regressions.schedule_attempts_total{result="error|unschedulable"}: Spikes in scheduling errors or unschedulable attempts.apiserver_rejected_requests: Unexpected spikes in API validation rejections.
Were upgrade and rollback tested? Was the upgrade->downgrade->upgrade path tested?
Testing plan for Beta (upgrade -> downgrade -> upgrade):
- Initial State: Cluster running previous minor version with
PodLevelResourcesEphemeralStoragedisabled. Create a baseline Pod with container-levelephemeral-storage. - Upgrade Phase:
- Upgrade control plane (
kube-apiserver,kube-scheduler) and enablePodLevelResourcesEphemeralStorage. - Verify existing baseline Pods continue running without issue.
- Create a test Pod with
pod.spec.resources.limits[ephemeral-storage]. Verify API server admits it. - Upgrade node (
kubelet) and enablePodLevelResourcesEphemeralStorage. - Verify Kubelet enforces the Pod-level ephemeral storage limit when total usage (writable layers + logs +
emptyDir) exceeds the limit.
- Upgrade control plane (
- Downgrade Phase:
- Disable
PodLevelResourcesEphemeralStorageonkubeletand control plane components. - Verify existing running Pods continue running without crashing.
- Attempt to create a new Pod with
pod.spec.resources.requests[ephemeral-storage]; verifykube-apiserverrejects the creation.
- Disable
- Re-upgrade Phase:
- Re-enable
PodLevelResourcesEphemeralStorageon control plane andkubelet. - Verify existing persisted Pods resume Pod-level ephemeral storage enforcement and new Pods with Pod-level
ephemeral-storageare admitted and enforced properly.
- Re-enable
Is the rollout accompanied by any deprecations and/or removals of features, APIs, fields of API types, flags, etc.?
No.
Monitoring Requirements
How can an operator determine if the feature is in use by workloads?
Operators can use:
kubelet_pod_level_resources_admission_total: Tracks Kubelet admission of Pods using Pod-level resources, categorized by resource configuration strategy (config_mode), admission status, and QoS class.kube_pod_level_resource_spec{resource="ephemeral_storage"}(fromkube-state-metrics): Identifies specific Pods specifyingephemeral-storageat the Pod level and their configured requests/limits.
How can someone using this feature know that it is working for their instance?
- Events
- Event Reason:
Evictedwith messageEvicted: Pod ephemeral local storage usage (<usedQuantity>) exceeds pod-level limit (<limitQuantity>).
- Event Reason:
- API .status
- Other field:
pod.status.phase == "Failed",pod.status.reason == "Evicted", andpod.status.messagedetailing the Pod-level ephemeral storage limit breach.
- Other field:
- Other (treat as last resort)
- Details: Kubelet
/stats/summaryAPI (ephemeral-storagePod-level stats:usedBytes,capacityBytes,inodesUsed).
- Details: Kubelet
What are the reasonable SLOs (Service Level Objectives) for the enhancement?
- Pod admission and scheduling latency SLOs remain unchanged from standard Kubernetes SLOs.
- Overall node ephemeral storage utilization remains bounded within configured Pod ceilings without unexpected node disk exhaustion.
- Eviction detection latency: Pods breaching
pod.spec.resources.limits[ephemeral-storage]are evicted within 1–2 Kubelet housekeeping intervals (default10s–20s).
What are the SLIs (Service Level Indicators) an operator can use to determine the health of the service?
- Metrics
- Metric name:
kubelet_pod_level_resources_admission_total: Total Pods processed during Kubelet admission using Pod-level resources.kubelet_evictions{eviction_signal="ephemeralpodfs.limit"}: Total Pods evicted due to exceeding their Pod-level ephemeral storage limit.kube_pod_level_resource_spec(kube-state-metrics): Exposes configured numeric values of Pod-level resource requests/limits.schedule_attempts_total{result="error|unschedulable"}: Scheduler health and fit metrics.node_collector_evictions_total: Node eviction tracking.started_pods_errors_total/started_containers_errors_total: Pod and container startup error rates.
- Components exposing the metric:
kube-apiserver,kubelet,kube-scheduler,kube-state-metrics.
- Metric name:
Are there any missing metrics that would be useful to have to improve observability of this feature?
No.
Dependencies
Does this feature depend on any specific services running in the cluster?
No external services are required. The feature depends on internal feature gates:
PodLevelResources(GA in v1.37).LocalStorageCapacityIsolation(GA in v1.25).
Scalability
Will enabling / using this feature result in any new API calls?
No. It only modifies existing API request/response payloads.
Will enabling / using this feature result in introducing new API types?
No. It extends the supported resource keys within the existing pod.spec.resources (v1.ResourceRequirements) field introduced by KEP-2837.
Will enabling / using this feature result in any new calls to the cloud provider?
No.
Will enabling / using this feature result in increasing size or count of the existing API objects?
Negligible.
- API type(s):
v1.Pod(v1.ResourceRequirementsandv1.ResourceList) - Estimated increase in size: ~54B increase per Pod when both request and limit are specified:
v1.ResourceRequirementswithephemeral-storagekey (17B) and quantity value (~10B) inrequestsandlimits:2 * (17B + 10B) = ~54Bper Pod.
- Estimated amount of new objects: 0 new API objects.
Will enabling / using this feature result in increasing time taken by any operations covered by existing SLIs/SLOs?
No. The computational overhead in kube-apiserver validation, kube-scheduler fit evaluation, and kubelet eviction checking is negligible ($O(1)$ map lookups and comparisons on already-collected filesystem stats).
Will enabling / using this feature result in non-negligible increase of resource usage (CPU, RAM, disk, IO, …) in any components?
No.
Can enabling / using this feature result in resource exhaustion of some node resources (PIDs, sockets, inodes, etc.)?
Yes, indirectly via increased Pod density.
Allowing containers within a Pod to share a single Pod-level ephemeral-storage pool reduces over-provisioning compared to per-container requests, which can allow kube-scheduler to pack more Pods onto a node. Higher Pod density can increase consumption of node resources such as inodes (nodefs.inodesFree), PIDs, and network sockets.
This is mitigated by:
- Kubelet’s
maxPodsconfiguration limiting total Pods per node. - Kubelet’s existing inode eviction monitoring (
nodefs.inodesFreeandimagefs.inodesFreeeviction signals).
Troubleshooting
How does this feature react if the API server and/or etcd is unavailable?
Kubelet enforces pod.spec.resources.limits[ephemeral-storage] locally using its cached Pod state and local filesystem usage observations (cadvisor / CRI stats). If kube-apiserver or etcd is unavailable, Kubelet still detects Pod-level ephemeral storage limit breaches and kills the offending Pod’s containers locally to reclaim disk space and protect node health. The resulting Evicted Pod status update is queued and synced once API server connectivity recovers.
What are other known failure modes?
- Pod evicted due to exceeding Pod-level ephemeral storage limit:
- Detection:
kubelet_evictions{eviction_signal="ephemeralpodfs.limit"}increments; Pod status transitions toFailed(reason: Evicted) with messageEvicted: Pod ephemeral local storage usage (<usedQuantity>) exceeds pod-level limit (<limitQuantity>). - Mitigations: Query Kubelet
/stats/summaryto inspect which container writable layer, container log directory, or disk-backedemptyDirvolume consumed the budget. Increasepod.spec.resources.limits[ephemeral-storage], add log rotation, or set an explicitemptyDir.sizeLimit/ container limit on noisy sidecars. - Diagnostics: Kubelet logs at verbosity
V(2)log detailed per-container and per-volume byte usage when an eviction threshold is triggered. - Testing: Covered by node e2e eviction tests (
test/e2e_node/eviction_test.go).
- Detection:
What steps should be taken if SLOs are not being met to determine the problem?
- Inspect Kubelet logs (
journalctl -u kubelet) for errors ineviction_manager.goorcadvisorfilesystem stats collection delays. - Check Kubelet’s
housekeeping-intervalflag if asynchronous eviction latency is higher than expected. - If an issue specific to
PodLevelResourcesEphemeralStoragecauses regressions, disable thePodLevelResourcesEphemeralStoragefeature gate onkube-apiserver,kube-scheduler, andkubeletto roll back to container-level ephemeral storage handling.
Implementation History
- 2026-09-17: Initial KEP draft created proposing
PodLevelResourcesEphemeralStoragefor Alpha in v1.38.
Drawbacks
- Enforcement of
pod.spec.resources.limits[ephemeral-storage]is asynchronous (via Kubelet’s eviction manager housekeeping loop) rather than synchronous kernel write blocking (ENOSPC). This matches existing Kubernetes container-levelephemeral-storagebehavior.
Alternatives
1. Reuse the existing PodLevelResources feature gate
We considered adding ephemeral-storage support directly under the existing PodLevelResources feature gate (KEP-2837).
- Why rejected:
PodLevelResourcesis graduating to GA (stable) in v1.37. Introducing a new resource type with distinct Kubelet eviction manager semantics requires a separate feature gate (PodLevelResourcesEphemeralStorage) so it can progress through Alpha $\rightarrow$ Beta $\rightarrow$ GA independently without delaying KEP-2837.
Infrastructure Needed (Optional)
None beyond standard Kubernetes CI / TestGrid infrastructure (sig-node-presubmits and node e2e test suites).