系统资源可分为两类:可抢占资源(CPU)和不可抢占资源(memory、storage)。可抢占资源比如CPU在系统满负荷时会划分时间片分时运行进程,系统整体会变慢(一般不会导致太大的问题)。但不可抢占资源如Memory在系统满负荷时,除了会导致系统变慢,还会进一步导致系统OOM,最终导致某些进程被Linux系统的OOM killer机制杀掉。
在Kubernetes平台,默认情况下Pod能够使用节点全部可用资源。如果节点上的pod负载较大,那么这些pod可能会与节点上的系统守护进程和k8s组件争夺资源并导致节点资源短缺,甚至引发系统OOM而杀进程,假如被杀掉的进程是系统进程或K8S组件,会导致比较严重的问题。
针对这种问题,主要有两种解决方案(两种也可以结合使用):
启用kubelet的Node Allocatable特性,为系统守护进程和k8s组件预留资源。 官方文档:https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources
设置pod的驱逐策略,在pod使用资源到一定程度时进行pod驱逐。官方文档:https://kubernetes.io/docs/tasks/administer-cluster/out-of-resource/#eviction-policy
本篇文章主要介绍如何正确配置资源预留,Pod的驱逐以后介绍。
kubelet的启动配置中有一个Node Allocatable特性,来为系统守护进程和k8s组件预留计算资源,使得即使节点满负载运行时,也不至于出现pod去和系统守护进程以及k8s组件争抢资源,导致节点挂掉的情况。目前支持对CPU, memory, ephemeral-storage三种资源进行预留。kubernetes官方建议根据各个节点的负载情况来具体配置相关参数。
节点计算资源的分配如下图所示:
Node Capacity
---------------------------| kube-reserved ||-------------------------|| system-reserved ||-------------------------|| eviction-threshold ||-------------------------|| || allocatable || (available for pods) || || |
---------------------------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
其中各个部分的含义如下:
- Node Capacity:Node的硬件资源总量
- kube-reserved:给k8s系统进程预留的资源(包括kubelet、container runtime、node problem detector等,但不会给以pod形式起的k8s系统进程预留资源)
- system-reserved:给linux系统守护进程预留的资源
- eviction-threshold:通过--eviction-hard参数为节点预留内存,当节点可用内存值低于此值时,kubelet会进行pod的驱逐
- allocatable:是真正可供节点上Pod使用的容量,kube-scheduler调度Pod时的参考此值(kubectl describe node可以看到,Node上所有Pods的request量不超过Allocatable)
节点可供Pod使用资源总量的计算公式如下:
allocatable=NodeCapacity-[kube-reserved] - [system-reserved] - [eviction-threshold]
1
从公式可以看出,默认情况下(不设置kube-reserved、system-reserved、eviction-threshold)节点上默认可以让Pod使用的资源总量等于节点的总容量,会导致Pod与系统进程和k8s组件争抢资源的情况发生。
kubelet的启动参数中涉及资源预留的主要有如下几个:
--cgroups-per-qos
--cgroup-driver
--cgroup-root
--enforce-node-allocatable=pods[,][system-reserved][,][kube-reserved]
--kube-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=1Gi]
--kube-reserved-cgroup
--system-reserved=[cpu=100mi][,][memory=100Mi][,][ephemeral-storage=1Gi]
--system-reserved-cgroup
--eviction-hard
--cgroups-per-qos
可选,默认开启。开启这个参数后,kubelet会将所有的pod创建在kubelet管理的cgroup层次结构下(这样才有了限制所有Pod使用资源总量的基础)。要想启用Node Allocatable特性,这个参数必须开启。
--cgroup-driver
可选。指定kubelet使用的cgroup driver。默认为cgroupfs,还可以是systemd,但是这个值需要和docker runtime所使用的cgroup driver保持一致。
--cgroup-root
可选。指定给pod使用的根cgroup,容器运行时会尽量将pod的资源限制在这个根cgroup下面。默认为空,即使用容器运行时作为根cgroup。
--enforce-node-allocatable
指定kubelet为哪些进程做硬限制,可选的值有:pods,kube-reserved,system-reserve。
这个参数开启并指定pods后kubelet会为所有pod的总cgroup做资源限制
作者:清风_d587
链接:https://www.jianshu.com/p/bf9672e14f42