Kubernetes v1.37 将 Pod-Level Resource Managers 从 Alpha 升级到 Beta,但仍默认关闭。这个变化的重点不只是新增一个字段,而是让 Kubelet 的 Topology Manager、CPU Manager 和 Memory Manager 能直接理解 Pod 级资源声明,并据此做 CPU 与内存的硬件布局决策。
对于延迟敏感型服务,这意味着可以把独占、NUMA 对齐的资源留给主业务容器,同时让日志代理、指标导出器等轻量 Sidecar 使用 Pod 隔离的共享资源池,而不再被迫为每个 Sidecar 分配一组专用物理核心。
从“所有容器都要分配”到混合资源模型
在此前的使用方式中,如果应用希望获得独占 CPU 核心或 NUMA 对齐内存,通常需要为 Pod 中的每个容器声明合适的整数资源请求,并满足相应的 QoS 与 CPU Manager 策略要求。
这种模式在只有一个主容器时还算直接,但现代工作负载经常会附带多个 Sidecar:
- 日志采集代理;
- OpenTelemetry 或 Prometheus 指标导出器;
- 配置同步进程;
- 服务网格代理。
这些 Sidecar 往往不需要专用物理核心。如果为了满足整个 Pod 的独占与 NUMA 对齐要求而给它们也分配整数 CPU,结果就是资源利用率下降;如果不分配,又可能无法获得期望的硬件亲和性。
Pod-Level Resource Managers 引入了更灵活的混合模型:
- 主工作负载可以获得独占、NUMA 对齐且不易受到节点其他工作负载影响的资源;
- 非 Guaranteed 的 Sidecar 可以进入 Pod 隔离的共享资源池;
- 共享池仍然保持 Pod 范围内的隔离与本地 NUMA 对齐;
- Sidecar 不必额外消耗专用物理 CPU 核心。
这里的关键边界是:Pod 级资源并不等于“所有容器自动获得独占资源”。最终结果仍取决于 CPU Manager、Memory Manager、Topology Manager 的配置、Pod 的资源声明以及节点硬件布局。
Beta 版本带来了什么
默认关闭,仍需显式启用
Kubernetes v1.37 中,该能力由 PodLevelResourceManagers feature gate 控制,Beta 阶段默认关闭。启用前应确认集群中的 kubelet 版本、节点管理策略和工作负载资源声明保持一致。
一种可以改造的 kubelet 配置示例如下:
# /var/lib/kubelet/config.yaml
featureGates:
PodLevelResourceManagers: true
cpuManagerPolicy: static
cpuManagerReconcilePeriod: 5s
memoryManager:
policy: Static
topologyManagerPolicy: single-numa-node
topologyManagerScope: pod
修改 kubelet 配置后,需要按发行版的运维方式重启 kubelet。不同安装方式可能使用 systemd、kubeadm 或托管节点配置管理系统,因此不要直接把上述命令当作所有发行版的通用操作。
可以先检查节点上的 kubelet 版本和 feature gate,再部署测试 Pod:
kubectl get nodes -o wide
kubectl get node "$NODE_NAME" -o jsonpath='{.status.nodeInfo.kubeletVersion}{"\n"}'
kubectl apply -f pod-level-resource-demo.yaml
kubectl get pod pod-level-resource-demo -o wide
PodResources API 增加 Pod 级报告
Beta 版本还增强了 v1 PodResources gRPC 服务。PodResourcesLister 的 PodResources 响应新增顶层 cpu_ids 和 memory 字段,使监控工具与设备插件可以直接查询 Pod 级独占资源分配。
这解决了一个容易被忽略的问题:如果工具只把每个容器的资源分配相加,可能会对 Pod 级资源进行重复统计。现在,工具可以区分容器级信息与 Pod 级信息,直接读取 Pod 的独占 CPU ID 和内存分配结果。
对于节点级监控系统,升级时应检查:
- 是否已经使用 v1 PodResources API;
- 是否假设所有资源都存在于容器级字段中;
- 是否会把 Pod 顶层资源和容器资源重复求和;
- 是否需要同时兼容尚未升级的 kubelet 节点。
一个可改造的 Pod 示例
下面是一个最小示例,展示如何把资源声明放在 Pod 级别,并为主容器与轻量 Sidecar 建立不同的资源角色。这个示例假设目标节点已经启用了相应 feature gate 和资源管理策略;它适合在测试节点上验证,不应直接作为生产容量规划的最终配置。
apiVersion: v1
kind: Pod
metadata:
name: pod-level-resource-demo
labels:
app: numa-sensitive-demo
spec:
# Pod 级资源声明:需要 Kubernetes v1.37,并且节点已启用
# PodLevelResourceManagers。
resources:
requests:
cpu: "2"
memory: "2Gi"
limits:
cpu: "2"
memory: "2Gi"
containers:
- name: worker
image: busybox:1.36
command: ["sh", "-c"]
args:
- |
echo "worker is running"
while true; do date; sleep 30; done
# 主容器的具体独占分配结果由 kubelet 的 CPU、Memory 和
# Topology Manager 根据 Pod 与节点策略共同决定。
- name: telemetry-sidecar
image: busybox:1.36
command: ["sh", "-c"]
args:
- |
echo "sidecar is running"
while true; do sleep 60; done
# 轻量 Sidecar 可以不声明专用整数 CPU,避免为辅助进程
# 额外消耗独占物理核心。
应用后可以从 Pod 事件、节点日志以及资源管理器的观测接口检查实际结果:
kubectl describe pod pod-level-resource-demo
kubectl get events --field-selector involvedObject.name=pod-level-resource-demo --sort-by=.lastTimestamp
kubectl logs pod-level-resource-demo -c worker
kubectl logs pod-level-resource-demo -c telemetry-sidecar
请注意,示例中的 2 个 CPU 和 2Gi 内存只是演示值。若目标是验证独占 CPU、内存 NUMA 对齐或 Guaranteed 行为,需要结合节点可用 CPU、NUMA 拓扑、Pod 中其他容器的资源声明以及实际 kubelet 策略进行测试。不能仅凭 YAML 中出现了 Pod 级 limits 就推断一定获得了指定物理核心。
落地时要重点验证的边界
先确认节点策略,再设计 Pod
Pod-Level Resource Managers 并不会绕过现有的 CPU Manager、Memory Manager 和 Topology Manager。建议先确定节点采用的策略,再决定哪些资源放在 Pod 级别、哪些容器需要显式声明资源。
尤其要关注:
- CPU Manager 是否使用
static策略; - Topology Manager 的 scope 是否按 Pod 工作;
- Topology Manager 是否采用
single-numa-node或其他适合业务的策略; - Memory Manager 是否启用了静态策略;
- 节点是否真的存在满足请求的连续、NUMA 对齐资源。
监控系统需要升级资源模型
如果监控程序仍然只观察容器级 CPU ID,可能看不到 Pod 级独占分配,或者把同一份资源计算两次。使用 PodResources API 的组件应测试 v1 响应中的顶层字段,并兼容不同 kubelet 版本返回的数据。
Beta 不等于生产环境无需验证
该功能进入 Beta 代表 API 与实现已经比 Alpha 阶段更适合试用,但 v1.37 中仍默认关闭。生产引入时建议采用小范围节点池和明确的回滚方案:
- 先在少量专用节点上打开 feature gate;
- 使用真实的延迟敏感工作负载进行 NUMA 与尾延迟测试;
- 对比启用前后的 CPU 利用率、调度失败率和内存访问延迟;
- 验证节点重启、kubelet 重启和 Pod 重建后的资源分配是否稳定;
- 确认设备插件、监控组件和运维脚本不会重复计算 Pod 与容器资源。
采用检查清单
如果你的集群运行的是 Kubernetes v1.37,可以按下面的顺序评估:
- [ ] 节点 kubelet 已升级到支持该 Beta 能力的版本;
- [ ] 已明确通过
PodLevelResourceManagersfeature gate opt in; - [ ] CPU、Memory、Topology Manager 的策略已经配套验证;
- [ ] 主容器与 Sidecar 的资源角色已经区分;
- [ ] 已检查 PodResources API 消费方是否支持顶层
cpu_ids与memory; - [ ] 已在真实节点拓扑上验证独占资源与 NUMA 对齐结果;
- [ ] 已准备关闭 feature gate 和回滚节点配置的方案。
Pod-Level Resource Managers 的价值不在于让所有 Pod 自动拥有更多资源,而在于让资源管理粒度更贴近实际工作负载:主业务获得需要的硬件确定性,辅助容器则使用受保护但不浪费专用核心的共享空间。对于高性能计算、低延迟服务和 NUMA 敏感型应用,这种拆分比“每个容器一刀切地分配独占资源”更有现实意义。