调整分配给容器的 CPU 和内存资源的大小
功能状态:Kubernetes v1.33 [beta]
(默认启用:true)
本页介绍如何在不重新创建 Pod 的情况下更改分配给容器的 CPU 和内存资源请求和限制。
传统上,更改 Pod 的资源需求需要删除现有的 Pod 并创建一个替代 Pod,通常由工作负载控制器管理。
就地 Pod 大小调整允许更改正在运行的 Pod 中容器的 CPU/内存分配,同时可能避免应用程序中断。
Key Concepts: 关键概念:
- 所需资源: 容器的
spec.containers[*].resources
表示容器所需的资源,并且对于 CPU 和内存是可变的。 - 实际资源: 该
status.containerStatuses[*].resources
字段反映当前为正在运行的容器配置的资源。对于尚未启动或已重启的容器,它反映了下次启动时分配的资源。 - 触发调整大小: 您可以通过更新所需的
请求
来请求调整大小 和Pod
规范中的限制。这通常使用kubectl patch
、kubectl apply
或kubectl edit
来完成 以 Pod 的resize
子资源为目标。当所需的资源与分配的资源不匹配时,Kubelet 将尝试调整容器的大小。 - 分配的资源(高级): 该
status.containerStatuses[*].allocatedResources
字段跟踪 Kubelet 确认的资源值,主要用于内部调度逻辑。对于大多数监视和验证目的,请重点关注status.containerStatuses[*].resources
。
如果节点的 Pod 具有待处理或未完成的调整大小(请参阅下面的 Pod 调整大小状态),则调度器在做出调度决策时使用状态中容器的所需请求数、已分配请求数和实际请求数中的最大值 。
Before you begin 准备工作
您的 Kubernetes 服务器必须为 1.33 或更高版本。
要检查版本,请输入 kubectl version
。
InPlacePodVerticalScaling
特性门控 必须启用 对于您的控制平面和集群中的所有节点。
The kubectl
client version must be at least v1.32 to use the --subresource=resize
flag.
kubectl
客户端版本必须至少为 v1.32 才能使用 --subresource=resize
标志。
Pod resize status Pod 大小调整状态
The Kubelet updates the Pod's status conditions to indicate the state of a resize request:
Kubelet 更新 Pod 的状态条件以指示调整大小请求的状态:
-
type: PodResizePending
: Kubelet 无法立即授予请求。message
字段提供了原因的说明。reason: Infeasible
:原因:不可行
:请求的大小调整在当前节点上是不可能的(例如,请求的资源超过节点拥有的资源)。reason: Deferred
:原因:延迟
:请求的调整大小目前是不可能的,但以后可能会变得可行(例如,如果删除了另一个 pod)。Kubelet 将重试调整大小。
-
type: PodResizeInProgress
: Kubelet 已接受调整大小并分配资源,但更改仍在应用中。这通常很简短,但可能需要更长的时间,具体取决于资源类型和运行时行为。启动期间的任何错误都会在message
字段中报告(以及原因:Error
)。
Container resize policies 容器大小调整策略
您可以通过在容器规范中设置 resizePolicy
来控制在调整大小时是否应重新启动容器。这允许根据资源类型 (CPU 或内存) 进行精细控制。
yaml
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired
- resourceName: memory
restartPolicy: RestartContainer
NotRequired
:(默认)将资源更改应用于正在运行的容器,而无需重新启动它。RestartContainer
:重启容器以应用新的资源值。这对于内存更改通常是必需的,因为许多应用程序和运行时无法动态调整其内存分配。
如果未为资源指定 resizePolicy[*].restartPolicy
,则默认为 NotRequired
。
注意:
如果 Pod 的整体 restartPolicy
为 Never
,则所有资源的任何容器 resizePolicy
都必须为 NotRequired
。你不能在此类 Pod 中配置需要重启的 resize 策略。
示例场景:
考虑一个为 CPU 和 restartPolicy: RestartContainer
内存配置了 restartPolicy: NotRequired
的容器。
- 如果仅更改 CPU 资源,则会就地调整容器的大小。
- 如果仅更改内存资源,则重新启动容器。
- 如果 CPU 和内存资源同时更改,则容器将重新启动(由于内存策略)。
局限性
对于 Kubernetes 1.33,就地调整 Pod 资源的大小具有以下限制:
-
Resource Types: 资源类型: 只能调整 CPU 和内存资源的大小。
-
Memory Decrease: 内存减少: 除非内存的
resizePolicy
为RestartContainer
, 否则无法降低内存限制。通常可以减少内存请求。 -
QoS Class: QoS 等级: Pod 的原始服务质量 (QoS) 类 (Guaranteed、Burstable 或 BestEffort)在创建时确定, 不能通过调整大小来更改。调整大小的资源值仍必须遵循原始 QoS 类的规则:
- Guaranteed : 保证 :调整大小后,请求必须继续等于 CPU 和内存的限制。
- Burstable : 可突增 :CPU 和内存的请求和限制不能同时相等(因为这会将其更改为 Guaranteed)。
- BestEffort :无法添加资源要求 (
请求
或限制
) (因为这会将其更改为 Burstable 或 Guaranteed) 。
-
Container Types: 集装箱类型: 不可重启的 init 容器和 临时容器无法调整大小。 可以调整 sidecar 容器的大小。
-
Resource Removal: 资源移除: 资源请求和限制一旦设置就无法完全删除;它们只能更改为不同的值。
-
Operating System: 操作系统: Windows Pod 不支持就地调整大小。
-
Node Policies: 节点策略: 由静态 CPU 或内存管理器策略管理的 Pod 无法就地调整大小。
-
Swap: 交换: 除非内存的
resizePolicy
是RestartContainer
,否则使用交换内存的 Pod 无法调整内存请求的大小。
这些限制可能会在未来的 Kubernetes 版本中放宽。
Example 1: Resizing CPU without restart 示例 1:在不重新启动的情况下调整 CPU 大小
First, create a Pod designed for in-place CPU resize and restart-required memory resize.
首先,创建一个专为就地调整 CPU 大小和需要重启的内存大小而设计的 Pod。
less
apiVersion: v1
kind: Pod
metadata:
name: resize-demo
spec:
containers:
- name: pause
image: registry.k8s.io/pause:3.8
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired # Default, but explicit here
- resourceName: memory
restartPolicy: RestartContainer
resources:
limits:
memory: "200Mi"
cpu: "700m"
requests:
memory: "200Mi"
cpu: "700m"
Create the pod: 创建 Pod:
css
kubectl create -f pod-resize.yaml
此 Pod 从 Guaranteed QoS 类开始。验证其初始状态:
ini
# Wait a moment for the pod to be running
kubectl get pod resize-demo --output=yaml
观察 spec.containers[0].resources
和 status.containerStatuses[0].resources
.它们应与清单匹配(700M CPU,200Mi 内存)。请注意 status.containerStatuses[0].restartCount
(应为 0)。
现在,将 CPU 请求和限制增加到 800m
。您可以使用带有 --subresource resize
命令行参数的 kubectl patch
。
css
kubectl patch pod resize-demo --subresource resize --patch \
'{"spec":{"containers":[{"name":"pause", "resources":{"requests":{"cpu":"800m"}, "limits":{"cpu":"800m"}}}]}}'
# Alternative methods:
# kubectl -n qos-example edit pod resize-demo --subresource resize
# kubectl -n qos-example apply -f <updated-manifest> --subresource resize
注意:
--subresource resize
命令行参数需要 kubectl
客户端版本 v1.32.0 或更高版本。旧版本将报告 invalid subresource
错误。
patching 后再次检查 Pod 状态:
css
kubectl get pod resize-demo --output=yaml --namespace=qos-example
You should see: 您应该会看到:
spec.containers[0].resources
现在显示cpu: 800m
。status.containerStatuses[0].resources
还显示CPU: 800M
,表示节点上的调整大小成功。status.containerStatuses[0].restartCount
保持0
,因为 CPUresizePolicy
为NotRequired
。
Example 2: Resizing memory with restart 示例 2:通过重启调整内存大小
现在,通过将同一 Pod 的内存增加到 300Mi
来调整其 大小。由于内存 resizePolicy
是 RestartContainer
,因此容器应重新启动。
css
kubectl patch pod resize-demo --subresource resize --patch \
'{"spec":{"containers":[{"name":"pause", "resources":{"requests":{"memory":"300Mi"}, "limits":{"memory":"300Mi"}}}]}}'
patching 后不久检查 Pod 状态:
css
kubectl get pod resize-demo --output=yaml
您现在应该观察到:
spec.containers[0].resources
显示内存:300Mi
。status.containerStatuses[0].resources
还显示内存:300Mi
。status.containerStatuses[0].restartCount
已增加到1
(如果之前发生过重启,则为更多),表示容器已重启以应用内存更改。
Troubleshooting: Infeasible resize request 疑难解答:不可行的大小调整请求
接下来,尝试请求不合理的 CPU 数量,例如 1000 个完整内核(对于毫核,则写为 "1000"
而不是 "1000m"
),这可能会超出节点容量。
css
# Attempt to patch with an excessively large CPU request
kubectl patch pod resize-demo --subresource resize --patch \
'{"spec":{"containers":[{"name":"pause", "resources":{"requests":{"cpu":"1000"}, "limits":{"cpu":"1000"}}}]}}'
查询 Pod 的详细信息:
css
kubectl get pod resize-demo --output=yaml
您将看到指示问题的更改:
spec.containers[0].resources
反映了所需的 状态 (cpu: "1000")。
- 已将
类型为 PodResizePending
且原因为 Infeasible
的条件添加到 Pod 中。 - 条件
的消息
将解释原因 (Node didn't have enough capacity: cpu, requested: 800000, capacity: ...
) - 至关重要的是,
status.containerStatuses[0].resources
它仍然会显示以前的值 (cpu:800m,memory``:300Mi
),因为 Kubelet 没有应用不可行的调整大小。 restartCount
不会因为这次失败的尝试而改变。
要解决此问题,您需要使用可行的资源值再次修补 Pod。
Clean up
Delete the pod: 删除 Pod:
arduino
kubectl delete pod resize-demo