合理分配容器计算资源
只要节点有足够的内存资源,那容器就可以使用超过其申请的内存,但是不允许容器使用超过其限制的资源。如果容器分配了超过限制的内存,这个容器将会被优先结束。如果容器持续使用超过限制的内存,这个容器就会被终结。如果一个结束的容器允许重启,kubelet就会重启它,但是会出现其他类型的运行错误。
场景一
节点的内存超过了节点内存预留的上限,导致触发OOMkill。
解决方法:
可扩容节点或迁移节点中的pod至其他节点。
场景二
pod的内存的limit设置较小,实际使用率超过limit,导致容器触发了OOMkill。
解决方法:
扩大工作负载内存的limit设置。
示例
本例将创建一个Pod尝试分配超过其限制的内存,如下这个Pod的配置文档,它申请50M的内存, 内存限制设置为100M。
memory-request-limit-2.yaml,此处仅为示例:
apiVersion: v1 kind: Pod metadata: name: memory-demo-2 spec: containers: - name: memory-demo-2-ctr image: vish/stress resources: requests: memory: 50Mi limits: memory: "100Mi" args: - -mem-total - 250Mi - -mem-alloc-size - 10Mi - -mem-alloc-sleep - 1s
在配置文件里的args段里,可以看到容器尝试分配250M的内存,超过了限制的100M。
创建Pod:
kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/memory-request-limit-2.yaml --namespace=mem-example
查看Pod的详细信息:
kubectl get pod memory-demo-2 --namespace=mem-example
这时候,容器可能会运行,也可能会被关闭。如果容器还没被关闭,重复之前的命令直至您看到这个容器被关闭:
NAME READY STATUS RESTARTS AGE memory-demo-2 0/1 OOMKilled 1 24s
查看容器更详细的信息:
kubectl get pod memory-demo-2 --output=yaml --namespace=mem-example
这个输出显示了容器被关闭因为超出了内存限制。
lastState: terminated: containerID: docker://7aae52677a4542917c23b10fb56fcb2434c2e8427bc956065183c1879cc0dbd2 exitCode: 137 finishedAt: 2020-02-20T17:35:12Z reason: OOMKilled startedAt: null
本例中的容器可以自动重启,因此kubelet会再去启动它。输入多几次这个命令看看它是怎么被关闭又被启动的:
kubectl get pod memory-demo-2 --namespace=mem-example
这个输出显示了容器被关闭,被启动,又被关闭,又被启动的过程:
$ kubectl get pod memory-demo-2 --namespace=mem-example NAME READY STATUS RESTARTS AGE memory-demo-2 0/1 OOMKilled 1 37s $ kubectl get pod memory-demo-2 --namespace=mem-example NAME READY STATUS RESTARTS AGE memory-demo-2 1/1 Running 2 40s
查看Pod的历史详细信息:
kubectl describe pod memory-demo-2 --namespace=mem-example
这个输出显示了Pod一直重复着被关闭又被启动的过程:
... Normal Created Created container with id 66a3a20aa7980e61be4922780bf9d24d1a1d8b7395c09861225b0eba1b1f8511 ... Warning BackOff Back-off restarting failed container