Cloud Computing

How to Optimize Kubernetes Pod Performance with Pod-Level Resource Managers (Alpha)

2026-05-04 18:05:11

Introduction

Kubernetes v1.36 introduces a powerful alpha feature called Pod-Level Resource Managers that transforms how you allocate CPU and memory for performance-sensitive workloads. Instead of forcing every container in a pod to require exclusive, integer-based resources, this enhancement lets you define a pod-level resource budget alongside flexible per-container allocations. The result? You can achieve NUMA alignment and Guaranteed QoS for your main application while letting lightweight sidecars share a common pool—saving cores and reducing waste.

How to Optimize Kubernetes Pod Performance with Pod-Level Resource Managers (Alpha)

This guide walks you through enabling and using Pod-Level Resource Managers, from prerequisites to real-world configuration examples. By the end, you’ll be able to deploy pods that combine exclusive resources for critical containers with shared resources for helpers, all without losing deterministic performance.

What You Need

Before you begin, ensure your environment meets these prerequisites:

Step-by-Step Guide

Step 1: Determine If Pod-Level Resource Managers Are Right for You

Pod-Level Resource Managers are ideal when your pod contains at least one container that needs exclusive, NUMA-aligned resources (e.g., a database engine) and others that can tolerate shared resources (e.g., a logging sidecar). If all containers in your pod demand exclusive resources or you don’t require NUMA alignment, the existing per-container model may suffice.

Tip: This feature is still alpha. Test it in a non-production cluster first.

Step 2: Enable Feature Gates on the Kubelet

Edit the kubelet configuration (usually /var/lib/kubelet/config.yaml on the node) to activate the two required feature gates:

featureGates:
PodLevelResourceManagers: true
PodLevelResources: true

Restart the kubelet service (systemctl restart kubelet). Verify the gates are active by checking the kubelet logs or using kubectl describe node (look for “PodLevelResourceManagers” in the feature gates list).

Step 3: Configure Topology Manager Scope to Pod

Set the Topology Manager scope to pod so that NUMA alignment considers the entire pod’s resource budget, not just individual containers. Add this flag to the kubelet:

--topology-manager-scope=pod

If you previously used container scope, change it now. Restart the kubelet again. Confirm the scope with kubectl describe node | grep TopologyManager.

Step 4: Define Pod-Level Resources in Your Pod Spec

Add a resources field at the pod level (spec.resources) to establish the total CPU and memory budget available to all containers. This budget also defines the alignment size for NUMA.

apiVersion: v1
kind: Pod
metadata:
name: tightly-coupled-database
spec:
resources:
requests:
cpu: "8"
memory: "16Gi"
limits:
cpu: "8"
memory: "16Gi"

In this example, the pod requests and limits 8 CPU cores and 16 GiB of memory. The kubelet will attempt to allocate all these resources from a single NUMA node.

Step 5: Specify Per-Container Resource Requirements

For each container, you can now set container-level resources that are relative to the pod’s budget. The main application container gets exclusive, integer-based resources (e.g., 4 CPUs), while sidecars can use fractional or shared allocations.

containers:
- name: database
image: postgres:15
resources:
requests:
cpu: "4"
memory: "10Gi"
limits:
cpu: "4"
memory: "10Gi"
- name: metrics-exporter
image: prom/node-exporter:v1
resources:
requests:
cpu: "100m"
memory: "128Mi"
- name: backup-agent
image: my-backup:latest
resources:
requests:
cpu: "200m"
memory: "256Mi"

Notice that the sidecar containers use millicores (m) and small memory amounts. The kubelet will: (1) allocate exclusive 4 CPUs + 10 GiB to the database from the pod budget, (2) create a “pod shared pool” from the remaining budget (~4 CPUs + 6 GiB), and (3) run the sidecars from that shared pool.

Step 6: Apply the Pod and Verify Allocation

Use kubectl apply -f pod.yaml to create the pod. After the pod runs, inspect its resource allocation:

kubectl describe pod tightly-coupled-database

Look for the Conditions section to confirm the pod is PodLevelResourcesAllocated. Also check the Allocated Resources section (kubelet metrics or node status) to see that exclusive and shared pools are formed correctly.

For deeper verification, run kubectl exec into each container and check /proc/self/status for Cpus_allowed_list and Mems_allowed_list to confirm NUMA affinity.

Step 7: Tweak and Iterate

Experiment with different pod-to-container resource ratios. If a sidecar becomes a bottleneck, increase its request from the shared pool. If the main container needs more isolation, raise its exclusive allocation. Remember that total container requests cannot exceed the pod-level requests (that would be rejected by the scheduler or kubelet).

Tips for Success

Explore

The Art of Design Dialects: How Flexible Systems Beat Rigid Consistency Exploring NVIDIA's Open Ising Models for Quantum Computing Challenges 10 Reasons to Grab the AdGuard VPN 5-Year Plan for $40 How AI Revolutionized Firefox Security: 271 Vulnerabilities Found in Days Spotify Launches Verified Badge to Fight AI Impersonation in Music