调整分配给容器的 CPU 和内存资源
Kubernetes v1.27 [alpha]
(enabled by default: false)本页假定你已经熟悉了 Kubernetes Pod 的服务质量。
本页说明如何在不重启 Pod 或其容器的情况下调整分配给运行中 Pod 容器的 CPU 和内存资源。
Kubernetes 节点会基于 Pod 的 requests
为 Pod 分配资源,
并基于 Pod 的容器中指定的 limits
限制 Pod 的资源使用。
要为正在运行的 Pod 更改资源分配量,需要启用 InPlacePodVerticalScaling
特性门控。
并让工作负载控制器创建一个具有不同资源需求的新 Pod。
resize 请求通过 Pod 的 /resize
子资源发出,
它会通过已完整更新的 Pod 来发出 update 请求,或对此 Pod 对象打补丁发出 patch 请求。
对于原地调整 Pod 资源而言:
- 针对 CPU 和内存资源的容器的
requests
和limits
是可变更的。 这些字段表示容器所用的预期资源。 - Pod 状态中
containerStatuses
的resources
字段反映了分配给 Pod 容器的资源。 对于正运行的容器,这反映了基于容器运行时的报告所配置的实际资源requests
和limits
。 对于未运行的容器,这些是启动时为容器分配的资源。
- Pod 状态中
resize
字段显示上次请求待处理的调整状态。此字段可以具有以下值:Proposed
:此值表示 Pod 大小已被调整,但 kubelet 还未处理此调整请求。InProgress
:此值表示节点已接受调整请求,并正在将其应用于 Pod 的容器。Deferred
:此值意味着在此时无法批准请求的调整,节点将继续重试。 当其他 Pod 被移除并释放节点资源时,调整可能会被真正实施。Infeasible
:此值是一种信号,表示节点无法承接所请求的调整值。 如果所请求的调整超过节点可分配给 Pod 的最大资源,则可能会发生这种情况。""
:留空或不设置,表示上一次调整已完成。 只有容器规约中的资源与容器状态中的资源相匹配时,才会是这种情况。
如果节点有一些 Pod 还未完成调整,调度器将基于容器的预期资源请求的最大值来计算 Pod 请求, 它是状态中所报告的实际请求。
准备开始
你必须拥有一个 Kubernetes 的集群,且必须配置 kubectl 命令行工具让其与你的集群通信。 建议运行本教程的集群至少有两个节点,且这两个节点不能作为控制平面主机。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面的 Kubernetes 练习环境之一:
你的 Kubernetes 服务器版本必须不低于版本 1.27. 要获知版本信息,请输入kubectl version
.你必须在控制平面和集群中的所有节点上启用 InPlacePodVerticalScaling
特性门控。
容器调整策略
调整策略允许更精细地控制 Pod 中的容器如何针对 CPU 和内存资源进行调整。 例如,容器的应用程序可以处理 CPU 资源的调整而不必重启, 但是调整内存可能需要应用程序重启,因此容器也必须重启。
为了实现这一点,容器规约允许用户指定 resizePolicy
。
针对调整 CPU 和内存可以设置以下重启策略:
NotRequired
:在运行时调整容器的资源。RestartContainer
:重启容器并在重启后应用新资源。
如果未指定 resizePolicy[*].restartPolicy
,则默认为 NotRequired
。
说明:
如果 Pod 的 restartPolicy
为 Never
,则 Pod 中所有容器的调整重启策略必须被设置为 NotRequired
。
下面的示例显示了一个 Pod,其中 CPU 可以在不重启容器的情况下进行调整,但是内存调整需要重启容器。
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-5
namespace: qos-example
spec:
containers:
- name: qos-demo-ctr-5
image: nginx
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired
- resourceName: memory
restartPolicy: RestartContainer
resources:
limits:
memory: "200Mi"
cpu: "700m"
requests:
memory: "200Mi"
cpu: "700m"
说明:
在上述示例中,如果所需的 CPU 和内存请求或限制已更改,则容器将被重启以调整其内存。
限制
- 仅 CPU 和内存资源可以被更改。
- Pod QoS 类不能更改。这意味着 Guaranteed Pod 的 requests 必须继续等于其 limits, Burstable Pod 对于 CPU 和内存的 requests 不能设为等于其 limits, 并且你不能给 BestEffort Pod 添加资源要求。
- Init 容器和临时容器不能调整大小。
- 资源请求和限制一旦被设置就不能移除。
- 容器的内存限制不可以低于其使用量。如果某请求将容器置于此状态,
调整的状态将停留在
InProgress
,直到预期的内存限制成为可行为止。 - Windows Pod 不能被调整大小。
创建具有资源请求和限制的 Pod
你可以通过为 Pod 的容器指定请求和/或限制来创建 Guaranteed 或 Burstable 服务质量类的 Pod。
考虑以下包含一个容器的 Pod 的清单。
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-5
namespace: qos-example
spec:
containers:
- name: qos-demo-ctr-5
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "700m"
requests:
memory: "200Mi"
cpu: "700m"
在 qos-example
名字空间中创建该 Pod:
kubectl create namespace qos-example
kubectl create -f https://k8s.io/examples/pods/qos/qos-pod-5.yaml --namespace=qos-example
此 Pod 被分类为 Guaranteed QoS 类,请求 700m CPU 和 200Mi 内存。
查看有关 Pod 的详细信息:
kubectl get pod qos-demo-5 --output=yaml --namespace=qos-example
另请注意,resizePolicy[*].restartPolicy
的值默认为 NotRequired
,
表示可以在容器运行的情况下调整 CPU 和内存大小。
spec:
containers:
...
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired
- resourceName: memory
restartPolicy: NotRequired
resources:
limits:
cpu: 700m
memory: 200Mi
requests:
cpu: 700m
memory: 200Mi
...
containerStatuses:
...
name: qos-demo-ctr-5
ready: true
...
resources:
limits:
cpu: 700m
memory: 200Mi
requests:
cpu: 700m
memory: 200Mi
restartCount: 0
started: true
...
qosClass: Guaranteed
更新 Pod 的资源
假设要求的 CPU 需求已上升,现在需要 0.8 CPU。这可以手动指定,或由如 VerticalPodAutoscaler (VPA) 这样的实体确定并可能以编程方式应用。
说明:
尽管你可以更改 Pod 的请求和限制以表示新的期望资源, 但无法更改 Pod 创建时所归属的 QoS 类。
现在对 Pod 的 Container 执行 patch 命令,将容器的 CPU 请求和限制均设置为 800m
:
kubectl -n qos-example patch pod qos-demo-5 --subresource resize --patch '{"spec":{"containers":[{"name":"qos-demo-ctr-5", "resources":{"requests":{"cpu":"800m"}, "limits":{"cpu":"800m"}}}]}}'
在 Pod 已打补丁后查询其详细信息。
kubectl get pod qos-demo-5 --output=yaml --namespace=qos-example
以下 Pod 规约反映了更新后的 CPU 请求和限制。
spec:
containers:
...
resources:
limits:
cpu: 800m
memory: 200Mi
requests:
cpu: 800m
memory: 200Mi
...
containerStatuses:
...
resources:
limits:
cpu: 800m
memory: 200Mi
requests:
cpu: 800m
memory: 200Mi
restartCount: 0
started: true
观察到 allocatedResources
的值已更新,反映了新的预期 CPU 请求。
这表明节点能够容纳提高后的 CPU 资源需求,而且新的 CPU 资源已经被应用。
Container 的 restartCount
保持不变,表示已在无需重启容器的情况下调整了容器的 CPU 资源。
清理
删除你的名字空间:
kubectl delete namespace qos-example