这篇文章已经一年多了,较旧的文章可能包含过时的内容。请检查从发表以来,页面中的信息是否变得不正确。
作者: Vinay Kulkarni (Kubescaler Labs)
译者:Paco Xu (Daocloud)
如果你部署的 Pod 设置了 CPU 或内存资源,你就可能已经注意到更改资源值会导致 Pod 重新启动。 以前,这对于运行的负载来说是一个破坏性的操作。
在 Kubernetes v1.27 中,我们添加了一个新的 alpha 特性,允许用户调整分配给 Pod 的
CPU 和内存资源大小,而无需重新启动容器。 首先,API 层面现在允许修改 Pod 容器中的
resources 字段下的 cpu 和 memory 资源。资源修改只需 patch 正在运行的 pod
规约即可。
这也意味着 Pod 定义中的 resource 字段不能再被视为 Pod 实际资源的指标。监控程序必须
查看 Pod 状态中的新字段来获取实际资源状况。Kubernetes 通过 CRI(Container Runtime
Interface,容器运行时接口)API 调用运行时(例如 containerd)来查询实际的 CPU 和内存
的请求和限制。容器运行时的响应会反映在 Pod 的状态中。
此外,Pod 中还添加了对应于资源调整的新字段 restartPolicy。这个字段使用户可以控制在资
源调整时容器的行为。
除了在 Pod 规范中添加调整策略之外,还在 Pod 状态中的 containerStatuses 中添加了一个名为
allocatedResources 的新字段。该字段反映了分配给 Pod 容器的节点资源。
此外,容器状态中还添加了一个名为 resources 的新字段。该字段反映的是如同容器运行时所报告的、
针对正运行的容器配置的实际资源 requests 和 limits。
最后,Pod 状态中添加了新字段 resize。resize 字段显示上次请求待处理的调整状态。
此字段可以具有以下值:
以下是此功能可能有价值的一些示例:
在 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://localhost: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(内存不足)Killer 终止其进程。
KubeCon North America 2022 会议演讲中详细介绍了上述用例。
某些 Java 应用程序在初始化期间 CPU 资源使用量可能比正常进程操作期间所需的 CPU 资源多很多。 如果此类应用程序指定适合正常操作的 CPU 请求和限制,会导致程序启动时间很长。这样的 pod 可以在创建 pod 时请求更高的 CPU 值。在应用程序完成初始化后,降低资源配置仍然可以正常运行。
该功能在 v1.27 中仍然是 alpha 阶段. 以下是用户可能会遇到的一些已知问题:
InProgress 状态,并且 Pod 状态中的 resources
字段永远不会更新,即使新资源配置可能已经在正在运行的容器上生效了。此功能是 Kubernetes 社区高度协作努力的结果。这里是对在这个功能实现过程中,贡献了很多帮助的一部分人的一点点致意。
非常感谢我非常支持的管理层 Xiaoning Ding 博士 和 Ying Xiong 博士,感谢他们的耐心和鼓励。