GCP容器中可能的OOM - 如何调试?

时间:2017-08-12 20:20:13

标签: linux docker celery kubernetes google-cloud-platform

我在GCP上用Kubernetes在一个码头工人的容器中运行芹菜。它的工作人员最近开始获得kill -9 - 这看起来与OOMKiller有关。 kubectl get events中没有OOM事件,如果这些事件仅在广告连播已超过resources.limits.memory值时出现,则会出现这种情况。

所以,我的理论是芹菜过程被杀死是linux的一项工作。自己的OOMKiller。但这并没有意义:如果OOMKiller进入舞台消耗了大量内存,那么该pod最初是如何安排的呢? (假设如果resources.limits.memory的总和超过系统可用的内存量,Kubernetes不允许安排新的pod。

然而,我不知道这些SIGKILL的任何其他合理的理由而不是OOMKiller。

芹菜错误的一个例子(每个工人都有一个):

[2017-08-12 07:00:12,124: ERROR/MainProcess] Process 'ForkPoolWorker-7' pid:16 exited with 'signal 9 (SIGKILL)'
[2017-08-12 07:00:12,208: ERROR/MainProcess] Task handler raised error: WorkerLostError('Worker exited prematurely: signal 9 (SIGKILL).',)

1 个答案:

答案 0 :(得分:1)

容器可能因OOMKilled而有两个原因。

  1. 如果超过了为他们设置的内存限制。限制是基于每个容器指定的,如果容器使用的内存超过限制,则它将被OOMKilled。从流程的角度来看,这与系统内存不足的情况相同。
  2. 如果系统内存不足。 Kubernetes中有两种资源规范:requests and limits。限制指定容器在被OOMKilled之前可以使用的最大内存量。请求用于计划Pod,如果未指定,则默认为限制。请求必须小于或等于容器限制。这意味着如果多个容器同时使用的内存多于其各自的请求,则容器上的容器可能会过度使用而OOMKilled。

    例如,如果进程A和进程B都有1GB的请求和2GB的限制,则它们都可以在具有2GB内存的节点上进行调度,因为请求是用于调度的。请求低于限制通常意味着容器可以突然增加到2GB,但通常使用不到1GB。现在,如果两者同时突然超过1GB,系统可能会耗尽内存,并且一个容器将获得OOMKilled,同时仍低于容器上设置的限制。

  3. 您可以通过检查Pod上的containerStatuses字段来调试容器是否被OOMKILL。

    $ kubectl get pod X -o json | jq '.status.containerStatuses'
    

    如果吊舱是OOMKILL,它通常会在lastState字段中说出相应的效果。在您的情况下,根据针对芹菜的问题(如this one),它看起来可能是OOM错误。