有时,我们的Kubernetes集群(GKE上的1.12.7)发出类似以下的事件:
1 OOMKilling: Memory cgroup out of memory: Kill process 605624 (pause) score 0 or sacrifice child
Killed process 605624 (pause) total-vm:1024kB, anon-rss:4kB, file-rss:0kB, shmem-rss:0kB
在同一时间,我们看到了来自Docker的事件:
datadog/agent@sha256:904c18135ec534fc81c29a42537725946b23ba19ac3c0a8b2e942fe39981af20 1 oom 1 kill 1 die 1 stop 1 destroy 1 create 1 start on gke-prod-pool-1-dc20d284-sjwm...
OOM k8s_datadog-agent_datadog-agent-76v8c_default_bf678779-c318-11e9-b064-42010a9a0059_7
KILL k8s_datadog-agent_datadog-agent-76v8c_default_bf678779-c318-11e9-b064-42010a9a0059_7
...
datadog-agent
Pane 也将重新启动。此特定的Pod配置有保证的QoS。根据Node OOM Behaviour on this page下的表,有保证的 pod 的分数应为-998。
为什么暂停容器在这里被杀死?而且由于它似乎是
datadog-agent
pod的暂停容器,所以为什么oom得分为0,而不是-998? 最佳答案
Kubernetes有其机制来指定容器的最小和最大需求;例如,您可以拥有:
resources:
limits: 150M
requests:
memory: 50M
当您的Pod越过最大“限制”线时,Pod将被杀死并报告为OOM-Killed,是否有足够的内存并不重要。因为您已经通过给OOM Killer过程提供分数来调查此饲料,所以分数越高,该过程将最有可能终止;反之,分数越低,将其发送到屠宰场的可能性就越小(因此对要保留的进程使用负值);由于这还不是全部,内核还需要调整和控制一些oom_score_adj,比如说,得分,保留或不说进程。
为Pod设置内存限制后,K8s将根据您正确声明的QoS(可突发性)发出OOM_SCORE_ADJ值,以确保此类特定的容器被OOMK选择并杀死。
最后,要解决分数问题,为什么要获得这样的分数,此“表格”可能对您有用:
+------------------+------------------------+
| QoS | Score |
| (Setting) | (Value or formula) |
+-------------------------------------------+
| Guaranteed | -998 |
+-------------------------------------------+
| Best effort | 1000 |
+-------------------------------------------+
| Burstable | Formula |
+------------------+------------------------+
其中Burstable es的得分公式等于:
min( max(2, 1000 - (1000 * mRB) / mMCB), 999)
mRB = Memory Request Bytes.
mMCB = Machine Memory Capacity Bytes
而且,由于GKE / Kubernetes的QoS是可爆发的,因此,这就是杀伤室的方式。
我相信这些信息对您有用,但我建议您也查看以下链接:
[1] OOR节点OOM行为(Kubernetes.io)
[2]容器和容器的内存分配
问候!
[1] https://kubernetes.io/docs/tasks/administer-cluster/out-of-resource/#node-oom-behavior
[2] https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/#exceed-a-containers-memory-limit