(1)内存不足

当 Pod 里面内存不足时,会触发 Cgroup 把 Pod 里面的进程杀死;但当系统内存不足时,就有可能触发系统 OOM,导致整个虚拟机宕机。这时候根据 oom score 来确定优先杀死哪个进程,而 oom_score_adj 又是影响 oom score 的重要参数,其值越低,表示 oom 的优先级越低。

OOM 的优先级如下:

sshd 等 K8S 管理进程 guarantee pod 其它进程 best effort pod
具体进程 sshd/dmevented / systemd-udevd kubelet / docker / journalctl guarantee pod 内核 init 进程等 best effort pod
oom_score_adj -1000 -999 -998 0 >0

best effort pod > 其它进程 > guarantee pod > kubelet/docker 等 > sshd 等,如果节点没有 best effort 类型的 pod,那么其它进程就有可能被 OOM,包括系统进程等,后果可想而知。所以,预留一定的资源给系统和 K8S 管理服务。

解决办法:

机器配置要高。(8核64G起)

CPU:作为可压缩资源,超配的后果是运行变慢,影响较小,为了充分发挥节点性能,CPU 不预留RAM:预留 4 GB,这是经验得出一个较为合理的值

kubelet --system-reserved=memory=4Gi

(2)pid耗尽

集群初始node节点较少,启动pod过多,pod request设置的较小,导致大量pod调度到单个节点上,打满了节点pid,docker异常,kubelet无法工作,节点也无法登陆。当服务器重启之后,有多余的pid被释放,此时节点可以登陆,但是docker已经挂掉,问题节点无法恢复正常工作,此时新加节点,会导致原节点上的pod集体迁移到新节点,导致新节点也因同样原因挂掉,造成集群雪崩效应,需要手动重启组件或节点才可恢复。

低版本内核可能报错: Cannot allocate memory,这个报错信息不准确,在内核 4.1 以后改进了--> https://github.com/torvalds/linux/commit/35f71bc0a09a45924bed268d8ccd0d3407bc476f

解决办法:

机器配置要高;(8核64G起)同时调大PID 和线程数限制。

临时调大 PID 和线程数限制:

echo 65535 > /proc/sys/kernel/pid_maxecho 65535 > /proc/sys/kernel/threads-max永久调大 PID 和线程数限制:

echo "kernel.pid_max=65535 " >> /etc/sysctl.conf && sysctl -pecho "kernel.threads-max=65535 " >> /etc/sysctl.conf && sysctl -p