本文发布已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes 1.27:Kubernetes Pod 的原地资源调整(Alpha)

如果您已部署指定了CPU和/或内存资源的Kubernetes Pod,您可能已经注意到更改资源值涉及重新启动Pod。对于正在运行的工作负载来说,这曾经是一个破坏性的操作……直到现在。

在Kubernetes v1.27中,我们添加了一个新的alpha功能,允许用户调整分配给Pod的CPU/内存资源大小,而无需重新启动容器。为了方便起见,Pod容器中的resources字段现在允许对cpumemory资源进行修改。只需修补正在运行的Pod规范即可更改它们。

这也意味着Pod规范中的resources字段不能再作为Pod实际资源的指标。监控工具和其他此类应用程序现在必须查看Pod状态中的新字段。Kubernetes通过CRI(容器运行时接口)API调用运行时(例如containerd),查询对正在运行的容器强制执行的实际CPU和内存请求和限制,而containerd负责运行容器。来自容器运行时的响应将反映在Pod的状态中。

此外,还添加了一个新的用于调整大小的restartPolicy。它使用户可以控制在调整资源大小时如何处理其容器。

v1.27中的新功能是什么?

除了在Pod的规范中添加调整大小策略外,还在Pod状态的containerStatuses中添加了一个名为allocatedResources的新字段。此字段反映了分配给Pod容器的节点资源。

此外,还在容器的状态中添加了一个名为resources的新字段。此字段反映了容器运行时报告的正在运行的容器上配置的实际资源请求和限制。

最后,在Pod的状态中添加了一个名为resize的新字段,以显示上次请求的调整大小的状态。Proposed值是对请求的调整大小的确认,表示请求已验证并已记录。InProgress值表示节点已接受调整大小的请求,并且正在将调整大小的请求应用于Pod的容器。Deferred值表示此时无法授予请求的调整大小,并且节点将不断重试。当其他Pod离开并释放节点资源时,可能会授予调整大小。Infeasible值表示节点无法满足请求的调整大小。如果请求的调整大小超出了节点可以为Pod分配的最大资源,则可能会发生这种情况。

何时使用此功能

以下是一些可能用到此功能的示例

  • Pod正在节点上运行,但资源过多或过少。
  • 由于群集中运行的Pod过度配置导致CPU或内存不足,Pod无法被调度。
  • 当可以缩小或移动节点中其他优先级较低的Pod时,驱逐某些需要更多资源才能将其调度到更大的节点上的有状态Pod是一种昂贵或破坏性的操作。

如何使用此功能

为了在v1.27中使用此功能,必须启用InPlacePodVerticalScaling功能门。可以使用如下所示的方式启动启用此功能的本地群集

root@vbuild:~/go/src/k8s.io/kubernetes# FEATURE_GATES=InPlacePodVerticalScaling=true ./hack/local-up-cluster.sh
go version go1.20.2 linux/arm64
+++ [0320 13:52:02] Building go targets for linux/arm64
    k8s.io/kubernetes/cmd/kubectl (static)
    k8s.io/kubernetes/cmd/kube-apiserver (static)
    k8s.io/kubernetes/cmd/kube-controller-manager (static)
    k8s.io/kubernetes/cmd/cloud-controller-manager (non-static)
    k8s.io/kubernetes/cmd/kubelet (non-static)
...
...
Logs:
  /tmp/etcd.log
  /tmp/kube-apiserver.log
  /tmp/kube-controller-manager.log

  /tmp/kube-proxy.log
  /tmp/kube-scheduler.log
  /tmp/kubelet.log

To start using your cluster, you can open up another terminal/tab and run:

  export KUBECONFIG=/var/run/kubernetes/admin.kubeconfig
  cluster/kubectl.sh

Alternatively, you can write to the default kubeconfig:

  export KUBERNETES_PROVIDER=local

  cluster/kubectl.sh config set-cluster local --server=https://127.0.0.1:6443 --certificate-authority=/var/run/kubernetes/server-ca.crt
  cluster/kubectl.sh config set-credentials myself --client-key=/var/run/kubernetes/client-admin.key --client-certificate=/var/run/kubernetes/client-admin.crt
  cluster/kubectl.sh config set-context local --cluster=local --user=myself
  cluster/kubectl.sh config use-context local
  cluster/kubectl.sh

一旦本地群集启动并运行,Kubernetes用户可以使用资源调度Pod,并通过kubectl调整Pod的大小。以下演示视频演示了如何使用此功能。

示例用例

基于云的开发环境

在这种情况下,开发人员或开发团队在本地编写代码,但在具有反映生产用途的一致配置的Kubernetes Pod中构建和测试他们的代码。当开发人员编写代码时,此类Pod需要最少的资源,但在构建代码或运行一系列测试时,则需要更多的CPU和内存。此用例可以利用就地Pod调整大小功能(在eBPF的一点帮助下),以快速调整Pod的资源大小,并避免内核OOM(内存不足)终止其进程。

KubeCon北美2022会议演讲说明了该用例。

Java进程初始化CPU要求

某些Java应用程序在初始化期间可能需要比正常进程运行时间多得多的CPU。如果此类应用程序指定了适合正常操作的CPU请求和限制,则它们的启动时间可能会非常长。此类Pod可以在创建Pod时请求较高的CPU值,并且一旦应用程序完成初始化,就可以将其大小缩小到正常的运行需求。

已知问题

此功能在v1.27中进入alpha阶段。以下是用户可能遇到的一些已知问题

  • 低于v1.6.9的containerd版本没有此功能的完整端到端操作所需的CRI支持。调整Pod大小的尝试似乎会InProgress状态,并且Pod状态中的resources字段永远不会更新,即使新资源可能已在正在运行的容器上生效。
  • Pod调整大小可能会遇到与其他Pod更新的竞争条件,从而导致Pod调整大小的延迟生效。
  • 在Pod状态中反映调整大小的容器资源可能需要一段时间。
  • 此功能不支持静态CPU管理策略。

鸣谢

此功能是Kubernetes社区协同努力的结果。在这里,我们要向为实现这一目标贡献了无数时间并提供了帮助的许多人中的一小部分人致谢。

  • @thockin,感谢他对细节导向的API设计和严格的代码审查。
  • @derekwaynecarr,感谢他简化了设计以及彻底的API和节点审查。
  • @dchen1107,感谢他从Borg带来了丰富的知识,并帮助我们避免了陷阱。
  • @ruiwen-zhao,感谢他添加了containerd支持,从而实现了完整的E2E实现。
  • @wangchen615,感谢他实现了全面的E2E测试并推动了调度程序修复。
  • @bobbypage,感谢他在我休假期间为CI做好准备并迅速调查问题提供了宝贵的帮助。
  • @Random-Liu,感谢他彻底的kubelet审查并发现了有问题的竞争条件。
  • @Huang-Wei@ahg-g@alculquicondor,感谢他们帮助完成调度程序更改。
  • @mikebrow @marosset,感谢他们在短时间内进行的审查,从而帮助CRI更改进入了v1.25。
  • @endocrimes@ehashman,感谢他们帮助确保经常被忽视的测试状态良好。
  • @mrunalp,感谢他对cgroupv2更改的审查,并确保干净地处理v1和v2。
  • @liggitt@gjkim42,感谢他们在合并后跟踪并找到了重要的遗漏问题。
  • @SergeyKanzhelev,感谢他在最后阶段对各种问题的支持和引导。
  • @pdgetrf,感谢他使第一个原型成为现实。
  • @dashpole,感谢他让我了解了“Kubernetes方式”的工作方式。
  • @bsalamat@kgolab,感谢他们在早期阶段提供的非常有见地的见解和建议。
  • @sftim@tengqm,感谢他们确保文档易于理解。
  • @dims,感谢他无处不在,并帮助在关键时刻进行合并。
  • 感谢发布团队确保项目的健康。

并非常感谢我非常支持的管理者丁晓宁博士熊鹰博士的耐心和鼓励。

参考资料

面向应用程序开发人员

面向集群管理员