Kubernetes v1.36 [beta](默认启用)本页面介绍了如何在不重新创建 Pod 的情况下,更改在 Pod 级别设置的 CPU 和内存资源。
就地 Pod 调整大小(In-place Pod Resize)特性允许修改正在运行的 Pod 的资源分配,从而避免应用中断。调整单个容器资源的过程涵盖在 调整分配给容器的 CPU 和内存资源 中。
本页面重点介绍就地 Pod 级资源调整。Pod 级资源定义在 spec.resources 中,它们充当 Pod 中所有容器消耗的聚合资源上限。就地 Pod 级资源调整特性允许您直接更改正在运行的 Pod 的这些聚合 CPU 和内存分配。
你需要有一个 Kubernetes 集群,并且必须配置 kubectl 命令行工具以与你的集群通信。建议在至少有两个节点的集群上运行本教程,且这些节点不能作为控制平面主机。如果你还没有集群,可以通过 minikube 创建一个,或者使用以下 Kubernetes 演练场之一。
您的 Kubernetes 服务器版本必须在 1.35 或更高版本。要检查版本,请输入 kubectl version。
必须为控制平面和集群中的所有节点启用以下 特性门控(feature gates)
InPlacePodLevelResourcesVerticalScalingPodLevelResourcesInPlacePodVerticalScalingNodeDeclaredFeatures使用 --subresource=resize 标志时,kubectl 客户端版本必须至少为 v1.32。
kubelet 用于跟踪和重试资源更改的机制在容器级和 Pod 级调整大小请求之间是共享的。
其状态、原因和重试优先级与为容器调整大小定义的定义完全相同
状态条件:kubelet 使用 PodResizePending(带有诸如 Infeasible 或 Deferred 之类的原因)和 PodResizeInProgress 来传达请求的状态。
重试优先级:延迟的调整大小请求会根据 PriorityClass、然后 QoS 类(Guaranteed 优于 Burstable),最后按其被延迟的时长进行重试。
跟踪:您可以使用 observedGeneration 字段来跟踪哪个 Pod 规范(metadata.generation)对应于最新处理的调整大小请求的状态。
有关这些条件和重试逻辑的完整描述,请参阅容器调整大小文档中的 Pod 调整大小状态 部分。
Pod 级资源调整不需要也不支持其自身的重启策略。
无 Pod 级策略:对 Pod 聚合资源(spec.resources)的更改始终就地应用,而无需触发重启。这是因为 Pod 级资源充当了 Pod cgroup 的整体约束,并不直接管理容器内的应用程序运行时。
容器策略依然有效:resizePolicy 必须仍在容器级别(spec.containers[*].resizePolicy)进行配置。此策略控制单个容器在资源请求或限制发生变化时是否重启,无论该更改是由直接容器级调整大小启动的,还是由对整体 Pod 级资源包的更新启动的。
对于 Kubernetes 1.36,就地调整 Pod 级资源受容器级资源调整的所有限制约束,您可以在此处找到:调整分配给容器的 CPU 和内存资源:限制。
此外,以下约束是 Pod 级资源调整所特有的
容器请求验证:仅当生成的 Pod 级资源请求(spec.resources.requests)大于或等于 Pod 内所有单个容器的相应资源请求之和时,才允许进行调整。这保持了 Pod 的最低资源可用性保证。
容器限制验证:如果单个容器限制小于或等于 Pod 级资源限制(spec.resources.limits),则允许进行调整。Pod 级限制作为任何单个容器不得超过的边界,但允许容器限制的总和超过 Pod 级限制,从而实现在 Pod 内跨容器的资源共享。
首先,创建一个设计用于就地 CPU 调整和需要重启的内存调整的 Pod。
apiVersion: v1
kind: Pod
metadata:
name: pod-level-resize-demo
spec:
containers:
- name: pause
image: registry.k8s.io/pause:3.9
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired # Default, but explicit here
- resourceName: memory
restartPolicy: RestartContainer
resources:
requests:
cpu: 100m
memory: 100Mi
- name: nginx-server
image: registry.k8s.io/nginx:latest
resizePolicy:
- resourceName: cpu
restartPolicy: RestartContainer
- resourceName: memory
restartPolicy: RestartContainer
resources: # Pod-level resources
requests:
cpu: 200m
memory: 200Mi
limits:
cpu: 200m
memory: 200Mi创建 Pod
kubectl create -f pod-level-resize.yaml
此 pod 以 Guaranteed QoS 类启动,因为 pod 级请求等于限制。验证其初始状态
# Wait a moment for the pod to be running
kubectl get pod pod-level-resize-demo --output=yaml
观察 spec.resources(200m CPU,200Mi 内存)。注意 status.containerStatuses[0].restartCount(应为 0)和 status.containerStatuses[1].restartCount(应为 0)。
现在,将 pod 级 CPU 请求和限制增加到 300m。您可以使用带有 --subresource resize 命令行参数的 kubectl patch 命令。
kubectl patch pod resize-demo --subresource resize --patch \
'{"spec":{"resources":{"requests":{"cpu":"300m"}, "limits":{"cpu":"300m"}}}}'
# Alternative methods:
# kubectl -n qos-example edit pod resize-demo --subresource resize
# kubectl -n qos-example apply -f <updated-manifest> --subresource resize --server-side
--subresource resize 命令行参数需要 kubectl 客户端版本 v1.32.0 或更高。旧版本将报告 invalid subresource 错误。打补丁后再次检查 pod 状态
kubectl get pod pod-level-resize-demo --output=yaml
你应该看到
spec.resources.requests 和 spec.resources.limits 现在显示 cpu: 300m。status.containerStatuses[0].restartCount 保持为 0,因为 CPU resizePolicy 为 NotRequired。status.containerStatuses[1].restartCount 增加到 1,表明容器已被重启以应用 CPU 更改。尽管调整是在 Pod 级别应用的,但容器 1 中仍发生了重启,这是由于 Pod 级限制与容器级策略之间存在错综复杂的关系。由于容器 1 没有指定明确的 CPU 限制,其底层资源配置(例如 cgroups)隐式采用了 Pod 的整体 CPU 限制作为其有效的最大消耗边界。当 Pod 级 CPU 限制从 200m 调整为 300m 时,此操作随即更改了强制应用在容器 1 上的隐式限制。由于容器 1 的 CPU resizePolicy 明确设置为 RestartContainer,kubelet 必须重启容器以正确地在底层资源强制机制中应用此更改,从而证实了更改 Pod 级限制即使在未直接定义容器限制的情况下,也可能触发容器重启策略。删除 pod
kubectl pod-level-resize-demo