Kubernetes版本:v1.8.6
问题:默认情况下pod能够使用节点全部可用资源。如果用户pod中的应用存在异常,例如疯狂占用内存,那么这些pod将与node上的系统守护进程和k8s组件争夺资源并导致节点资源短缺,从而产生node not ready问题。
解决方案:
1. 启用kubelet的Node Allocatable特性参考,为k8s组件和系统守护进程预留资源。 官方文档:https://v1-8.docs.kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources
2. 设置pod的驱逐策略,官方文档:https://v1-8.docs.kubernetes.io/docs/tasks/administer-cluster/out-of-resource/#eviction-policy
Node Capacity
---------------------------
| kube-reserved |
|-------------------------|
| system-reserved |
|-------------------------|
| eviction-threshold |
|-------------------------|
| |
| allocatable |
| (available for pods) |
| |
| |
---------------------------
NodeAllocatable = [NodeCapacity] - [kube-reserved] - [system-reserved] - [eviction-threshold]
--enforce-node-allocatable=pods,kube-reserved,system-reserved
--kube-reserved-cgroup=/system.slice/kubelet.service
--system-reserved-cgroup=/system.slice
--kube-reserved=cpu=200m,memory=250Mi
--system-reserved=cpu=200m,memory=250Mi
--eviction-hard=memory.available<5%,nodefs.available<10%,imagefs.available<10%
--eviction-soft=memory.available<10%,nodefs.available<15%,imagefs.available<15%
--eviction-soft-grace-period=memory.available=2m,nodefs.available=2m,imagefs.available=2m
--eviction-max-pod-grace-period=30
--eviction-minimum-reclaim=memory.available=0Mi,nodefs.available=500Mi,imagefs.available=500Mi
(1)开启为kube组件和系统守护进程预留资源的功能
--enforce-node-allocatable=pods,kube-reserved,system-reserved
(2)设置k8s组件的cgroup
--kube-reserved-cgroup=/system.slice/kubelet.service
(3)设置系统守护进程的cgroup
--system-reserved-cgroup=/system.slice
(4)配置为k8s组件预留资源的大小,CPU、Mem。(ephemeral storage是a’lpha特性,需要kubelet开启feature-gates,预留的是临时存储空间(log,EmptyDir),生产环境建议先不使用)
--kube-reserved=cpu=200m,memory=250Mi
(5)配置为系统守护进程预留资源的大小(预留的值需要根据机器上容器的密度做一个合理的值)
--system-reserved=cpu=200m,memory=250Mi
当系统内存不足时,就有可能触发系统 OOM,这时候根据 oom score 来确定优先杀死哪个进程,而 oom_score_adj 又是影响 oom score 的重要参数,其值越低,表示 oom 的优先级越低。在计算节点中,进程的 oom_score_adj 如下:
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 |
所以,很大概率上,OOM 的优先级如下:
best effort pod > 其它进程 > guarantee pod > kubelet/docker 等 > sshd 等。
如果节点没有 best effort 类型的 pod,那么其它进程就有可能被 OOM,包括系统进程等。
(6)驱逐pod的配置:硬阈值(保证95%的内存利用率)
--eviction-hard=memory.available<5%,nodefs.available<10%,imagefs.available<10%
(7)驱逐pod的配置:软阈值
--eviction-soft=memory.available<10%,nodefs.available<15%,imagefs.available<15%
(8)定义达到软阈值之后,持续时间超过多久才进行驱逐
--eviction-soft-grace-period=memory.available=2m,nodefs.available=2m,imagefs.available=2m
(9)驱逐pod前最大等待时间=min(pod.Spec.TerminationGracePeriodSeconds, eviction-max-pod-grace-period),单位秒
--eviction-max-pod-grace-period=30
(10)至少回收
--eviction-minimum-reclaim=memory.available=0Mi,nodefs.available=500Mi,imagefs.available=500Mi
在Kubernetes 1.8版本,kubelet启动会检查以下cgroup subsystem的存在:cpu、cpuacct、cpuset、memory、systemd。所以需要确保这些cgroup目录的存在。
mkdir -p /sys/fs/cgroup/cpu/system.slice/kubelet.service
mkdir -p /sys/fs/cgroup/cpuacct/system.slice/kubelet.service
mkdir -p /sys/fs/cgroup/cpuset/system.slice/kubelet.service
mkdir -p /sys/fs/cgroup/memory/system.slice/kubelet.service
mkdir -p /sys/fs/cgroup/systemd/system.slice/kubelet.service
【1】http://docs.kubernetes.org.cn/723.html
【2】https://v1-8.docs.kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/
【3】https://my.oschina.net/jxcdwangtao/blog/1629059
【4】https://www.cnblogs.com/ssss429170331/p/7685163.html