为k8s集群的节点预留计算资源

一、问题

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

二、方案细节

2.1 预留计算公式

      Node Capacity
---------------------------
|     kube-reserved       |
|-------------------------|
|     system-reserved     |
|-------------------------|
|    eviction-threshold   |
|-------------------------|
|                         |
|      allocatable        |
|   (available for pods)  |
|                         |
|                         |
---------------------------

NodeAllocatable = [NodeCapacity] - [kube-reserved] - [system-reserved] - [eviction-threshold]

  • Node Capacity:Node的所有硬件资源
  • kube-reserved:给kube组件预留的资源
  • system-reserved:给System进程预留的资源
  • eviction-threshold:kubelet eviction的阈值设定
  • Allocatable:真正scheduler调度Pod时的参考值(保证Node上所有Pods的request resource不超过Allocatable)

2.2 kubelet添加额外启动参数

--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

2.3 添加cgroup subsystem

在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

三、Ref

【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

你可能感兴趣的:(Kubernetes)