调整分配给容器的 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 子资源处理的。 对于 update 请求,请求体是更新后的完整 Pod; 对于 patch 请求,请求体是对 Pod 对象的补丁。

对于原地调整 Pod 资源而言:

  • 针对 CPU 和内存资源的容器的 requestslimits可变更的。 这些字段表示容器所预期使用的资源。
  • Pod 状态中 containerStatusesresources 字段反映了分配给 Pod 容器的资源。 对于正运行的容器,这个字段反映了实际配置的资源 requestslimits, 字段值是容器运行时所报告的。对于未运行的容器,字段值是容器启动时为其分配的资源。
  • 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,其中 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"

限制

目前就地调整 Pod 资源大小存在以下限制:

  • 只能更改 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 的 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

接下来

对于应用开发人员

对于集群管理员

最后修改 December 20, 2024 at 3:48 PM PST: [zh] Update resize-container-resources.md (2d1db15ca1)