k8s Vertical Pod Autoscaler

调整分配给容器的 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 patchkubectl applykubectl 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 的整体 restartPolicyNever,则所有资源的任何容器 resizePolicy 都必须为 NotRequired。你不能在此类 Pod 中配置需要重启的 resize 策略。

示例场景:

考虑一个为 CPU 和 restartPolicy: RestartContainer 内存配置了 restartPolicy: NotRequired 的容器。

  • 如果仅更改 CPU 资源,则会就地调整容器的大小。
  • 如果仅更改内存资源,则重新启动容器。
  • 如果 CPU 和内存资源同时更改,则容器将重新启动(由于内存策略)。

局限性

对于 Kubernetes 1.33,就地调整 Pod 资源的大小具有以下限制:

  • Resource Types: 资源类型: 只能调整 CPU 和内存资源的大小。

  • Memory Decrease: 内存减少: 除非内存的 resizePolicyRestartContainer否则无法降低内存限制。通常可以减少内存请求。

  • 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: 交换: 除非内存的 resizePolicyRestartContainer,否则使用交换内存的 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。

pods/resource/pod-resize.yaml

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].resourcesstatus.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,因为 CPU resizePolicyNotRequired

Example 2: Resizing memory with restart 示例 2:通过重启调整内存大小

现在,通过将同一 Pod 的内存增加到 300Mi 来调整 大小。由于内存 resizePolicyRestartContainer,因此容器应重新启动。

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
相关推荐
烛阴3 小时前
自动化测试、前后端mock数据量产利器:Chance.js深度教程
前端·javascript·后端
.生产的驴3 小时前
SpringCloud 分布式锁Redisson锁的重入性与看门狗机制 高并发 可重入
java·分布式·后端·spring·spring cloud·信息可视化·tomcat
攒了一袋星辰3 小时前
Spring @Autowired自动装配的实现机制
java·后端·spring
我的golang之路果然有问题3 小时前
快速了解GO+ElasticSearch
开发语言·经验分享·笔记·后端·elasticsearch·golang
love530love4 小时前
Windows 下部署 SUNA 项目:虚拟环境尝试与最终方案
前端·人工智能·windows·后端·docker·rust·开源
元闰子4 小时前
走技术路线需要些什么?
后端·面试·程序员
元闰子4 小时前
AI Agent需要什么样的数据库?
数据库·人工智能·后端
知初~4 小时前
SpringCloud
后端·spring·spring cloud
希望20174 小时前
go语言基础|slice入门
后端·golang