Kubernetes 原位 Pod 调整大小

发布: (2025年12月29日 GMT+8 17:00)
6 min read
原文: Dev.to

Source: Dev.to

Kubernetes 原位 Pod 调整的封面图片

Alik Khilazhev

背景

大约六年前,在 Kubernetes 上运行一个大型基于 Java 的平台时,我注意到一个反复出现的问题:我们的服务在应用启动期间需要显著更高的 CPU 和内存。大量使用 Spring Bean 和 AutoConfiguration 迫使我们为生存启动阶段设置夸大的资源请求和上限,即使这些资源在之后大多未被使用。

这种变通办法从未让人感觉正确。作为工程师,我希望有一种解决方案能够反映应用的实际生命周期,而不是其最糟糕的时刻。

我在 Kubernetes 仓库中打开了一个issue,描述了这个问题并提出了一种在不重启的情况下动态调整 Pod 资源的思路。该 issue 讨论不多,但悄悄地积累了兴趣(13 个 👍 表情)。每隔几个月,自动化机器人就会尝试将其标记为陈旧,每次我都会移除该标签。这种情况持续了将近六年……

直到 Kubernetes 1.35 发行,In‑Place Pod Resize 功能被标记为稳定

什么是原地 Pod 调整大小

原地 Pod 调整大小允许 Kubernetes 在安全的情况下更新 CPU 和内存 请求限制,而无需重启 Pod。这显著减少了因资源变更导致的不必要重启,降低了中断并提升了工作负载的可靠性。

对于资源需求随时间演变的应用——尤其是在启动后——此功能提供了长期缺失的构建块。

对 VerticalPodAutoscaler 的影响

新的 resizePolicy 字段在 pod‑spec 级别进行配置。虽然技术上可以手动更改 pod 资源,但这样并不会触发扩缩容。实际上,这一功能应由工作负载控制器来驱动。

目前唯一支持原地 pod 调整的控制器是 Vertical Pod Autoscaler(VPA)

有两个增强提案实现了此行为:

  1. AEP‑4016:在 VPA 中支持原地更新 – 引入 InPlaceOrRecreate 更新模式。
  2. AEP‑7862:CPU 启动加速 – 在启动期间临时为 pod 提供更多 CPU,以实现加速。这在概念上与我最初 issue 中提出的方法相似。

示例:使用两个 AEP 功能的 Deployment + VPA

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example
spec:
  replicas: 1
  selector:
    matchLabels:
      app: example
  template:
    metadata:
      labels:
        app: example
    spec:
      containers:
        - name: app
          image: my-heavy-java-app:stable
          ports:
            - containerPort: 80
          resources:
            requests:
              cpu: 1000m
              memory: 1024Mi
            limits:
              cpu: 2000m
              memory: 2048Mi
---
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: example-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: example
  updatePolicy:
    updateMode: InPlaceOrRecreate
  resourcePolicy:
    containerPolicies:
      - containerName: app
        minAllowed:
          cpu: "250m"
          memory: "512Mi"
        maxAllowed:
          cpu: "3000m"
          memory: "8192Mi"
        # The CPU boosted resources can go beyond maxAllowed.
        startupBoost:
          cpu:
            type: Factor
            quantity: "2"

使用此配置后,pod 在启动期间的 CPU 请求和限制将翻倍。在加速期间不会进行任何重新调整。pod 达到 Ready 状态后,VPA 控制器会将 CPU 缩减至当前推荐的数值。此后,VPA 将继续正常工作,关键区别在于资源更新将在可能的情况下 原地 应用。

限制

此功能是否完全解决了上述问题?仅部分解决。

  1. 运行时约束 – Java 和 Python 运行时目前不支持在不重启的情况下调整内存限制。此限制存在于 Kubernetes 之外,并在 OpenJDK 项目中通过一个未解决的工单进行跟踪。

    OpenJDK 工单示意图

  2. 内存限制的降低 – 即使启用了 In‑Place Pod Resize,Kubernetes 仍未支持降低内存限制。这是一个已知限制,已在针对内存限制降低的增强提案中记录。

    就地 Pod Resize – 内存限制降低

因此,虽然就地 Pod Resize 能有效解决 CPU 相关的启动峰值问题,但内存大小的动态调整仍是一个未解决的问题。

最终思考

就地 Pod 调整为诸如 StartupBoost 等酷炫新特性奠定了基础,并使 VPA 的使用更加可靠。虽然仍存在重要的缺口——例如 memory‑decrease supportscheduling race condition——此更改代表了一个有意义的前进步伐。

对于具有明显启动阶段和稳态阶段的工作负载,Kubernetes 终于开始更贴近现实地建模。

Back to Blog

相关文章

阅读更多 »

我对 Kubernetes 的看法

文章 URL: https://garnaudov.com/writings/how-i-think-about-kubernetes/ 评论 URL: https://news.ycombinator.com/item?id=46396043 点赞数: 31 评论数: 13