To use this feature, you (or a cluster administrator) will need to enable the PodLevelResourceManagers feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
现有的资源管理器(拓扑、CPU 和内存)对 Pod 级资源的支持将其扩展为能够处理
Pod 级资源规约。当启用时(通过 PodLevelResources 和 PodLevelResourceManagers
特性门控),资源管理器可以直接使用 .spec.resources 作为分配决策的基础,从严格的按容器分配模型演进为以
Pod 为中心的模型。
这种分区方案引入了一种更灵活、更强大的资源管理模型,
尤其适用于对性能敏感的工作负载。它允许你定义混合分配模型,
其中 Pod 中的某些容器获得独占的、NUMA 对齐的资源,
而其他容器共享 Pod 级共享池中剩余的资源。
要练习使用 Pod 级资源设置 kubelet 资源管理器并亲身体验分配行为,
请遵循使用 Pod 级资源与 kubelet 资源管理器教程。
为了理解 Pod 级资源管理器,将它们与传统的以容器为中心的模型进行对比会很有帮助。
此前,kubelet 资源分配是严格的"全有或全无":
要为工作负载获得独占的 NUMA 对齐资源,Pod 中的每个容器都必须是
Guaranteed(为 CPU 和内存指定相等的 requests 和 limits)。
Pod 级资源管理器使用 .spec.resources,根据配置的拓扑管理器范围启用灵活的分区:
pod 范围: kubelet 基于 .spec.resources 为整个 Pod 分配并 NUMA 对齐一个单一的
Pod 资源单元(Pod bubble)。请求独占分配的容器会从此 Pod 资源泡中划分出专属的切片,
而所有其他容器在 Pod 隔离的共享池中共享剩余的资源泡容量。container 范围: 启用混合分配模型。kubelet 允许各个容器直接从节点的
可分配池中获得独占的、NUMA 对齐的资源,同时使用 Pod 的 .spec.resources
上限来限制总体消耗 —— 允许边车在常规节点共享池中运行,
而无需 Pod 中的每个容器都为 Guaranteed。标准 Init 容器和可重启 Init 容器(边车)都完全受支持。 它们可以获得独占的资源切片或使用 Pod 的共享池, 并且 Pod 级资源管理器会遵守它们的生命周期规则 (例如,标准 Init 容器的可重用资源与边车的持久保留)。
.spec.resources 中定义的资源预算,
用于指定整个 Pod 的总体 requests 和 limits。kubelet 行为一致,
这使容器有资格从资源管理器获得独占资源分配。CPU 和内存资源管理器的运行方式因配置的拓扑管理器范围不同而异。
当拓扑管理器范围设置为 pod 时,kubelet 基于 .spec.resources
中定义的资源预算为整个 Pod 执行单次 NUMA 对齐。
得到的 NUMA 对齐资源池随后被划分为:
Guaranteed 资源(CPU 和内存的 requests 与
limits 相等,且 CPU request 为正整数)的容器从 Pod 的总分配中获得独占切片。请注意,当标准 Init 容器运行完成时,它们的资源会进入每个 Pod 的可重用集合, 而不是返回到节点的资源池。由于它们是按顺序运行的, 后续的应用容器可以重用这些资源(用于自己的独占切片或共享池)。
这允许你将需要独占资源的容器(例如高性能主应用)与不需要独占资源的容器 (例如日志或监控边车)放在同一个 NUMA 对齐的 Pod 中。
考虑以下 Pod 规约中的容器,其中拓扑管理器范围为 pod,Pod 的总预算为 4 个 CPU。
main-app 请求独占的 2 个 CPU 切片,而边车在 Pod 的共享池中共享剩余的
2 个 CPU:
apiVersion: v1
kind: Pod
metadata:
name: pod-scope-mixed
annotations:
kubernetes.io/description: "A pod demonstrating pod-level scope where one container gets exclusive resources and others share the remaining pod resources in a shared pool."
spec:
# At Pod level, the Pod has CPU request equal to limits and memory request
# also equal to memory limits. The main-app container meets the requirements
# for the Guaranteed QoS class at container level, and the sidecar containers
# don't specify any resource request. Under pod scope, this means that the
# kubelet could statically assign 4 CPUs to the overall Pod, of which 2 are
# assigned exclusively to the main-app container, and the remaining 2 are
# shared by the sidecars in the pod's shared pool.
resources:
requests:
cpu: "4"
memory: "4Gi"
limits:
cpu: "4"
memory: "4Gi"
initContainers:
- name: metrics-sidecar
# Note: This is a placeholder image for demonstration purposes, not an
#actual metrics helper.
image: registry.k8s.io/pause:3.9
restartPolicy: Always
- name: logging-sidecar
# Note: This is a placeholder image for demonstration purposes, not an
# actual logging agent.
image: registry.k8s.io/pause:3.9
restartPolicy: Always
containers:
- name: main-app
# Note: This is a placeholder image for demonstration purposes.
image: registry.k8s.io/pause:3.9
resources:
requests:
cpu: "2"
memory: "2Gi"
limits:
cpu: "2"
memory: "2Gi"
重要注意事项:
当将 Pod 级资源与拓扑管理器的 pod 范围一起使用时,有一些重要注意事项:
空共享池限制: 如果存在需要共享池的容器,此配置不允许会产生空的
Pod 共享池的 Pod 规约。如果所有 Guaranteed 容器的 resource requests
之和恰好等于总资源预算,并且至少有一个其他容器需要共享池,
kubelet 会在准入时拒绝该 Pod。
例如,以下 Pod 请求的 Pod 级预算为 4 个 CPU。main-app 需要独占的 3 个
CPU,metrics-sidecar 需要独占的 1 个 CPU。
由于共享池中没有剩余的 CPU 可供 logging-sidecar 使用,
kubelet 会拒绝此 Pod(相同的验证也适用于内存):
pod 范围时超量分配的任何资源
(所有容器的 requests 总和小于 Pod 级预算且没有共享池容器,
或共享池容器未完全使用剩余量)仍保持分配并为 Pod 保留,
在整个 Pod 执行期间实际上被浪费。当拓扑管理器范围设置为 container 时,kubelet 会逐个评估每个容器以进行独占分配。
如果整个 Pod 达到 Guaranteed
QoS 类
(通过在 Pod 级别的 .spec.resources 中指定适当的值),
你可以混合搭配容器:
Guaranteed requests 的容器获得独占的 NUMA 对齐资源。Guaranteed requests 的容器在节点的共享池中运行。.spec.resources limits 强制执行。当你有一个基础设施边车需要为设备访问对齐到特定 NUMA 节点, 而主工作负载可以在常规节点共享池中运行时,此范围非常有用。
考虑以下 Pod 规约中的容器,其中拓扑管理器范围为 container,
Pod 代表一个包含基础设施边车和两个应用工作器的工作负载,总预算为 4 个 CPU。
infrastructure-sidecar 获得独占的、NUMA 对齐的 2 个 CPU 切片。
两个应用工作器(worker-1 和 worker-2)在常规的节点级共享池中运行:
apiVersion: v1
kind: Pod
metadata:
name: container-scope-mixed
annotations:
kubernetes.io/description: "A pod demonstrating container-level scope where one container gets exclusive resources and others run in the node's shared pool."
spec:
# At Pod level, the Pod has CPU request equal to limits and memory request
# also equal to memory limits. The infrastructure-sidecar container meets the
# requirements for the Guaranteed QoS class at container level, and the worker
# containers don't specify any resource request. Under container scope, the
# kubelet evaluates containers individually for exclusive allocation. This
# means the infrastructure-sidecar gets an exclusive 2 CPU slice, while the
# worker containers run in the node's general shared pool, all while bounded
# by the overall pod limits.
resources:
requests:
cpu: "4"
memory: "4Gi"
limits:
cpu: "4"
memory: "4Gi"
initContainers:
- name: infrastructure-sidecar
# Note: This is a placeholder image for demonstration purposes, not an
# actual infrastructure helper.
image: registry.k8s.io/pause:3.9
restartPolicy: Always
resources:
requests:
cpu: "2"
memory: "2Gi"
limits:
cpu: "2"
memory: "2Gi"
containers:
- name: worker-1
# Note: This is a placeholder image for demonstration purposes.
image: registry.k8s.io/pause:3.9
- name: worker-2
# Note: This is a placeholder image for demonstration purposes.
image: registry.k8s.io/pause:3.9
在 Pod 内运行混合工作负载时,kubelet 根据分配方式以不同方式强制执行隔离:
Pod 的总资源池(NUMA 对齐和总保留容量)是持久的。 如果 Pod 共享池中的容器崩溃并重启,Pod 的整体资源保留仍安全地锚定在节点上。 只有当整个 Pod 终止时,节点才会将资源释放回其常规池。
kubelet 降级和状态检查点在 Kubernetes 1.36 中,启用 PodLevelResourceManagers 会将内部
kubelet 状态检查点文件(cpu_manager_state 和 memory_manager_state)
更新为旧版 kubelet 无法加载的格式。
如果你在活跃使用后降级 1.36 的 kubelet,旧版 kubelet 将无法启动;
你必须腾空节点、删除这些检查点文件并重启 kubelet。
在 Kubernetes 1.37 中,检查点文件使用前向兼容的格式来防止降级期间的启动失败,
尽管 1.36 版本的 kubelet 不会恢复活跃的 Pod 级资源分配。
有关检查点格式和恢复的完整详细信息,请参阅
Pod 级资源管理器参考。
你可以使用以下 kubelet 指标(通过 PodLevelResourceManagers 特性门控启用)
监控容器级和 Pod 级分配中资源管理器的行为和健康状况:
resource_manager_allocations_total:统计管理器执行的独占资源分配总数。
source 标签("pod" 或 "node")区分了从节点级池与从预分配的 Pod 级池中提取的分配。resource_manager_allocation_errors_total:统计在独占资源分配期间遇到的错误,
按预期分配的 source("pod" 或 "node")区分。resource_manager_container_assignments:跟踪将被授予特定类型资源分配的容器累积数量。
assignment_type 标签("node_exclusive"、"pod_exclusive"、
"pod_shared")提供了对有多少容器使用(来自节点或 Pod 池的)
独占资源与 Pod 级共享池运行的可见性。在 Kubernetes 1.37 中,当启用 PodLevelResourceManagers 时,
kubelet 的节点本地 PodResources gRPC API 包含 Pod 级资源分配。
节点本地监控代理和设备插件可以查询顶级 Pod 分配(cpu_ids 和 memory),
同时避免重复计算容器级分配。
有关完整的 API 模式、字段掩码和各范围报告表,请参阅 Pod 级资源管理器参考。
static CPU 管理器策略和 Static 内存管理器策略实现。
请注意,BestEffort 策略不受内存管理器支持。kubelet 资源管理器教程。