kubernetes - 作业完成后,K8s 作业(容器)中指定的内存请求/限制会发生什么情况?
问题描述
我有多环境 k8s 集群 ( EKS ),我正在尝试为 ResourceQuotas 设置准确的值。
我注意到的一件有趣的事情是,当作业成功完成并有效地释放它正在使用的 cpu/内存资源时,指定的 CPU/内存请求/限制在 k8s 集群中保持“占用” 。
由于我希望在环境中执行很多作业,这给我带来了问题。当然,我已经为成功执行的作业添加了对运行 cleanup cronjob 的支持,但这只是解决方案的一部分。
我知道k8s 上的 TTL 功能:https ://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/#ttl-mechanism-for-finished-jobs 仍处于 alpha阶段状态,因此在 EKS k8s 集群上不可用。
我希望在该特定 pod(容器/s)上指定的请求/限制也被“释放”,但是在查看 Grafana 上的 k8s 指标时,我发现这不是真的。
这是一个示例(绿线标记当前资源使用情况,黄色标记资源请求,而蓝色标记资源限制):
我的问题是:
- 这是预期的行为吗?
- 如果是,在作业(pod)执行完成后请求/限制没有释放的技术原因是什么?
解决方案
我已经对我的环境进行了“负载”测试,以测试在已完成作业(pod)上分配的请求/限制是否确实会对我设置的 ResourceQuota 产生影响。
这就是我的 ResourceQuota 的样子:
apiVersion: v1
kind: ResourceQuota
metadata:
name: mem-cpu-quota
spec:
hard:
requests.cpu: "1"
requests.memory: 2Gi
limits.cpu: "2"
limits.memory: 3Gi
这是每个 k8s 作业上存在的 cpu/内存的请求/限制(准确地说是在由作业启动的 Pod 中运行的容器上):
resources:
limits:
cpu: 250m
memory: 250Mi
requests:
cpu: 100m
memory: 100Mi
测试结果:
- 当前运行的作业数:66
- CPU 请求的预期总和(如果问题的假设是正确的)~= 6.6m
- 内存请求的预期总和(如果问题的假设是正确的)~= 6.6Mi
- CPU 限制的预期总和(如果问题的假设是正确的)~= 16.5
- 内存限制的预期总和(如果问题的假设是正确的)~= 16.5
我创建了显示以下内容的 Grafana 图表:
一个命名空间中作业的 CPU 使用率/请求/限制
sum(rate(container_cpu_usage_seconds_total{namespace="${namespace}", container="myjob"}[5m]))
sum(kube_pod_container_resource_requests_cpu_cores{namespace="${namespace}", container="myjob"})
sum(kube_pod_container_resource_limits_cpu_cores{namespace="${namespace}", container="myjob"})
一个命名空间中作业的内存使用/请求/限制
sum(rate(container_memory_usage_bytes{namespace="${namespace}", container="myjob"}[5m]))
sum(kube_pod_container_resource_requests_memory_bytes{namespace="${namespace}", container="myjob"})
sum(kube_pod_container_resource_limits_memory_bytes{namespace="${namespace}", container="myjob"})
根据该图,请求/限制会累积并远远超出 ResourceQuota 阈值。但是,我仍然可以毫无问题地运行新工作。
此时,我开始怀疑显示的指标是什么,并选择检查指标的其他部分。具体来说,我使用了以下一组指标:
中央处理器:
sum (rate(container_cpu_usage_seconds_total{namespace="$namespace"}[1m]))
kube_resourcequota{namespace="$namespace", resource="limits.cpu", type="hard"}
kube_resourcequota{namespace="$namespace", resource="requests.cpu", type="hard"}
kube_resourcequota{namespace="$namespace", resource="limits.cpu", type="used"}
kube_resourcequota{namespace="$namespace", resource="requests.cpu", type="used"}
记忆:
sum (container_memory_usage_bytes{image!="",name=~"^k8s_.*", namespace="$namespace"})
kube_resourcequota{namespace="$namespace", resource="limits.memory", type="hard"}
kube_resourcequota{namespace="$namespace", resource="requests.memory", type="hard"}
kube_resourcequota{namespace="$namespace", resource="limits.memory", type="used"}
kube_resourcequota{namespace="$namespace", resource="requests.memory", type="used"}
结论:
从这个屏幕截图中可以清楚地看出,一旦负载测试完成并且作业进入完成状态,即使 pod 仍然存在(with READY: 0/1 and STATUS: Completed),cpu/memory request/limits 将被释放并且没有更长的表示需要计算到 ResourceQuota 阈值中的约束。这可以通过观察图表上的以下数据来看出:
CPU allocated requests
CPU allocated limits
Memory allocated requests
Memory allocated limits
当系统上发生负载并创建新作业时,所有这些都会增加,但一旦作业完成就会恢复到以前的状态(即使它们没有从环境中删除)
换句话说,只有当作业(及其对应的 Pod)处于 RUNNING 状态时,才会考虑 CPU/内存的资源使用/限制/请求
推荐阅读
- sql - Truncating part of a postgres table
- javascript - 你可以在 nodejs 控制器的变量中使用 mongodb 表名吗?
- bash - 如何从多个文件中删除多个第一列?
- javascript - JavaScript onMouseOver 适用于 Chrome,但不适用于桌面 Safari
- c++ - 如何使用函数参数设置数组大小?
- python - 为什么我的模型的准确性会根据它是从泡菜加载还是新训练的而改变?
- c# - 将 Dapper IDictionary 转换为类?
- netty - netty 如何处理未回复或丢失的 SYN 数据包?
- wordpress - htaccess,rewriteurl 到子文件夹中 WordPress 站点的页面
- ios - 链接 ktor 和 kotlinx.coroutines 会导致未定义的符号