本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
Kubernetes 1.27:Kubernetes Pod 的原地资源调整(Alpha)
如果你部署过指定了 CPU 和/或内存资源的 Kubernetes Pod,你可能已经注意到更改资源值需要重启 Pod。这对正在运行的工作负载来说一直是一个破坏性的操作……直到现在。
在 Kubernetes v1.27 中,我们增加了一个新的 Alpha 特性,允许用户在不重启容器的情况下调整分配给 Pod 的 CPU/内存资源。为了实现这一点,Pod 的容器中的 resources
字段现在允许变更 cpu
和 memory
资源。只需通过更新正在运行的 Pod 的规约即可更改它们。
这也意味着 Pod 规约中的 resources
字段再也不能作为 Pod 实际资源的指标。监控工具和其他此类应用程序现在必须查看 Pod 状态中的新字段。Kubernetes 通过 CRI(容器运行时接口)API 调用运行时(如 containerd,它负责运行容器),查询运行中容器上强制执行的实际 CPU 和内存请求及限制。来自容器运行时的响应会反映在 Pod 的状态中。
此外,还增加了一个新的用于调整大小的 restartPolicy
。它让用户可以控制在资源调整大小时如何处理他们的容器。
v1.27 有哪些新内容?
除了在 Pod 的规约中增加了调整大小策略外,Pod 状态的 containerStatuses
中还增加了一个名为 allocatedResources
的新字段。该字段反映了分配给 Pod 容器的节点资源。
此外,容器的状态中还增加了一个名为 resources
的新字段。该字段反映了由容器运行时报告的、在运行中容器上配置的实际资源请求和限制。
最后,Pod 的状态中增加了一个名为 resize
的新字段,以显示上次请求的调整大小的状态。值为 Proposed
表示对请求的调整大小的确认,并表明请求已通过验证和记录。值为 InProgress
表示节点已接受调整大小请求,并且正在将调整大小请求应用于 Pod 的容器。值为 Deferred
意味着请求的调整大小目前无法被批准,节点将继续重试。当其他 Pod 离开并释放节点资源时,调整大小可能会被批准。值为 Infeasible
是一个信号,表示节点无法满足请求的调整大小。如果请求的调整大小超出了节点可以为 Pod 分配的最大资源,就会发生这种情况。
何时使用此功能
以下是此功能可能有用的一些示例
- Pod 正在节点上运行,但资源过多或过少。
- 由于集群中 CPU 或内存不足,Pod 无法被调度,而该集群中运行的 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://: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 支持,从而实现了完整的端到端实现。
- @wangchen615 实现了全面的端到端测试并推动了调度程序的修复。
- @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 无处不在,并在关键时刻帮助实现合并。
- 发布团队确保了项目的健康发展。
还要特别感谢我非常支持的管理层 丁晓宁博士 和 熊鹰博士 的耐心和鼓励。