Pod开销
FEATURESTATE:Kubernetesv1.24[stable]
在节点上运行Pod时,Pod本身占用大量系统资源。这些是运行Pod内容器所需资源之外的资源。在Kubernetes中,POD开销是一种方法,用于计算Pod基础设施在容器请求和限制之上消耗的资源。
在Kubernetes中,Pod的开销是根据与Pod的RuntimeClass相关联的开销在准入时设置的。
如果启用了PodOverhead,在调度Pod时,除了考虑容器资源请求的总和外,还要考虑Pod开销。类似地,kubelet将在确定Podcgroups的大小和执行Pod驱逐排序时也会考虑Pod开销。
配置Pod开销
你需要确保使用一个定义了字段的
RuntimeClass
。
使用示例
要使用Pod开销,你需要一个定义了字段的RuntimeClass。作为例子,下面的RuntimeClass定义中包含一个虚拟化所用的容器运行时,RuntimeClass如下,其中每个Pod大约使用120MiB用来运行虚拟机和寄宿操作系统:
APIVersion: node.k8s.io/v1kind: RuntimeClassmetadata:name: kata-fchandler: kata-fcoverhead:podFixed:memory: "120Mi"cpu: "250m"
通过指定RuntimeClass处理程序创建的工作负载会将内存和CPU开销计入资源配额计算、节点调度以及Podcgroup尺寸确定。
假设我们运行下面给出的工作负载示例test-pod:
apiVersion: v1kind: Podmetadata:name: test-podspec:runtimeClassName: kata-fccontainers:- name: busybox-ctrimage: busybox:1.28stdin: truetty: trueresources:limits:cpu: 500mmemory: 100Mi- name: nginx-ctrimage: nginxresources:limits:cpu: 1500mmemory: 100Mi
在准入阶段RuntimeClass准入控制器更新工作负载的PodSpec以包含RuntimeClass中定义的。如果PodSpec中已定义该字段,该Pod将会被拒绝。在这个例子中,由于只指定了RuntimeClass名称,所以准入控制器更新了Pod,使之包含。
在RuntimeClass准入控制器进行修改后,你可以查看更新后的PodSpec:
kubectl get pod test-pod -o jsonpath='{.spec.overhead}'
输出:
map[cpu:250m memory:120Mi]
如果定义了ResourceQuata,则容器请求的总量以及字段都将计算在内。

当kube-scheduler决定在哪一个节点调度运行新的Pod时,调度器会兼顾该Pod的以及该Pod的容器请求总量。在这个示例中,调度器将资源请求和开销相加,然后寻找具备2.25CPU和320MiB内存可用的节点。
一旦Pod被调度到了某个节点,该节点上的kubelet将为该Pod新建一个cgroup。底层容器运行时将在这个Pod中创建容器。
如果该资源对每一个容器都定义了一个限制(定义了限制值的GuaranteedQoS或者BurstableQoS),kubelet会为与该资源(CPU的
cpu.cfs_quota_us
以及内存的
memory.limit_in_bytes
)相关的Podcgroup设定一个上限。该上限基于PodSpec中定义的容器限制总量与之和。
对于CPU,如果Pod的QoS是Guaranteed或者Burstable,kubelet会基于容器请求总量与PodSpec中定义的之和设置
cpu.shares
。
请看这个例子,验证工作负载的容器请求:
kubectl get pod test-pod -o jsonpath='{.spec.containers[*].resources.limits}'
容器请求总计2000mCPU和200MiB内存:
map[cpu: 500m memory:100Mi] map[cpu:1500m memory:100Mi]
对照从节点观察到的情况来检查一下:
kubectl describe node | grep test-pod -B2
该输出显示请求了2250mCPU以及320MiB内存。请求包含了Pod开销在内:
NamespaceNameCPU RequestsCPU LimitsMemory RequestsMemory LimitsAGE------------------------------------------------------------------defaulttest-pod2250m (56%)2250m (56%)320Mi (1%)320Mi (1%)36m
验证Podcgroup限制
在工作负载所运行的节点上检查Pod的内存cgroups。在接下来的例子中,将在该节点上使用具备CRI兼容的容器运行时命令行工具。这是一个显示Pod开销行为的高级示例,预计用户不需要直接在节点上检查cgroups。首先在特定的节点上确定该Pod的标识符:
# 在该 Pod 被调度到的节点上执行如下命令:POD_ID="$(sudo crictl pods --name test-pod -q)"
可以依此判断该Pod的cgroup路径:
# 在该 Pod 被调度到的节点上执行如下命令:sudo crictl inspectp -o=json $POD_ID | grep cgroupsPath
执行结果的cgroup路径中包含了该Pod的容器。Pod级别的cgroup在即上一层目录。
"cgroupsPath": "/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/7ccf55aee35dd16aca4189c952d83487297f3cd760f1bbf09620e206e7d0c27a"
在这个例子中,该Pod的cgroup路径是
kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2
。验证内存的Pod级别cgroup设置:
# 在该 Pod 被调度到的节点上执行这个命令。# 另外,修改 cgroup 的名称以匹配为该 Pod 分配的 cgroup。 cat /sys/fs/cgroup/memory/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/memory.limit_in_bytes
和预期的一样,这一数值为320MiB。
可观察性
在kube-state-metrics中可以通过
kube_pod_overhead_*
指标来协助确定何时使用Pod开销,以及协助观察以一个既定开销运行的工作负载的稳定性。该特性在kube-state-metrics的1.9发行版本中不可用,不过预计将在后续版本中发布。在此之前,用户需要从源代码构建kube-state-metrics。
发表评论