Kubernetes 节点会基于 Pod 的 requests 为 Pod 分配资源, 并基于 Pod 的容器中指定的 limits 限制 Pod 的资源使用。本篇教程详细说明如何在不重启 Pod 或其容器的情况下调整分配给运行中 Pod 容器的 CPU 和内存资源。
对于原地调整 Pod 资源而言:
1、针对 CPU 和内存资源的容器的 requests 和 limits 是可变更的;
2、Pod 状态中 containerStatuses 的 allocatedResources 字段反映了分配给 Pod 容器的资源;
3、Pod 状态中 containerStatuses 的 resources 字段反映了如同容器运行时所报告的、针对正运行的容器配置的实际资源 requests 和 limits;
4、Pod 状态中 resize 字段显示上次请求待处理的调整状态。此字段可以具有以下值:
- Proposed:此值表示请求调整已被确认,并且请求已被验证和记录;
- InProgress:此值表示节点已接受调整请求,并正在将其应用于 Pod 的容器;
- Deferred:此值意味着在此时无法批准请求的调整,节点将继续重试。 当其他 Pod 退出并释放节点资源时,调整可能会被真正实施;
- Infeasible:此值是一种信号,表示节点无法承接所请求的调整值。 如果所请求的调整超过节点可分配给 Pod 的最大资源,则可能会发生这种情况。
一、准备
必须拥有一个 Kubernetes 的集群,同时必须配置 kubectl 命令行工具与集群通信。 建议在至少有两个不作为控制平面主机的节点的集群上运行本教程。 如果还没有集群,可以通过 Minikube 构建一个自己的集群,或者可以使用下面的 Kubernetes 练习环境之一:
- Killercoda
- 玩转 Kubernetes
Kubernetes 服务器版本必须不低于版本 1.27. 要获知版本信息,请输入 kubectl version.
二、容器调整策略
调整策略允许更精细地控制 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 和内存请求或限制已更改,则容器将被重启以调整其内存。
三、具有资源请求和限制的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 ... allocatedResources: cpu: 700m memory: 200Mi 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 --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: ... allocatedResources: cpu: 800m memory: 200Mi resources: limits: cpu: 800m memory: 200Mi requests: cpu: 800m memory: 200Mi restartCount: 0 started: true
观察到 allocatedResources 的值已更新,反映了新的预期 CPU 请求。 这表明节点能够容纳提高后的 CPU 资源需求。
在 Container 状态中,更新的 CPU 资源值显示已应用新的 CPU 资源。 Container 的 restartCount 保持不变,表示已在无需重启容器的情况下调整了容器的 CPU 资源。
五、清理
删除名字空间:
kubectl delete namespace qos-example