kubernetes 集群中的 node 上为啥需要资源预留?
kubernetes 的节点可以按照 Capacity 调度。默认情况下 Pod 能够使用节点全部可用容量。这是个问题,因为节点通常情况下还运行不少驱动操作系统和kubernetes 集群系统的守护进程(system daemons)。除非为这些系统守护进程留出资源,否则它们将会与 pod 争夺资源并导致节点资源短缺问题。按照是否为 Pod,可以把计算节点的进程分为两类:没有预留的情况下,也就是我
1 Node 节点生产环境为啥需要资源提前的预留?
kubernetes 的节点可以按照 Capacity 调度。默认情况下 Pod 能够使用节点全部可用容量。这是个问题,因为节点通常情况下还运行不少驱动操作系统和kubernetes 集群系统的守护进程(system daemons)。除非为这些系统守护进程留出资源,否则它们将会与 pod 争夺资源并导致节点资源短缺问题。
按照是否为 Pod,可以把计算节点的进程分为两类:
- Pod 类进程:容器内部的进程,这些容器由 k8s 创建的
- 非 Pod 类进程:系统进程,如内核、systemd等;k8s管理进程,如 Docker、kubelet、kube-proxy等
没有预留的情况下,也就是我们使用kubeadm 工具默认部署好的请求下
Capacity:
cpu: 24
ephemeral-storage: 71682Mi
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 131861444Ki
pods: 110
Allocatable:
cpu: 24
ephemeral-storage: 67647622237
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 131759044Ki
pods: 110
如果没有资源预留,k8s 默认认为宿主机上所有的资源(RAM、CPU)都是可以分配给 Pod 类进程。因为非 Pod 类进程也需要占用一定的资源,当 Pod 创建很多时,就有可能出现资源不足的情况。宿主机中kubelet、kube-proxy 等进程被 kill 掉,最后导致整个 Node 节点不可用。
我们知道,当 Pod 创建很多时,就有可能出现资源不足的情况。宿主机中 kubelet、kube-proxy 等进程被kill掉,最后导致整个 Node 节点不可用。
我们知道,当 Pod 里面内存不足时,会触发 Cgroup 把 Pod 里面的进程杀死;当系统内存不足时,就有可能触发系统OOM,这时候根据 oom score 来确定优先杀死哪个进程,而 oom_score_adj 又是影响 oom score 的重要参数,其值越低,表示 oom 的优先级越低。在计算节点中,进程的 oom_score_adj 如下:
sshd 等 | K8S 管理进程 | Guaranteed Pod | 其它进程 | BestEffort Pod | |
---|---|---|---|---|---|
具体进程 | sshd、systemd-udevd等 | kubelet、docker、kube-proxy等 | Guaranteed Pod 等 | systemd-logind、systemd-jouranl | BestEffort |
所以很大概率上,OOM的优先级如下:
BestEffort Pod > 其他进程 >Guarantee Pod > kubelet\docker\kube-proxy等> sshd 等
那么问题来了,如果节点没有 BestEffort 类型的 pod,那么其他进程就有可能被 OOM,包括系统进程等,后果可想而知,所以,预留一定的资源给系统和 k8s 基础管理服务是必须而紧要的。
2 预留多少资源
K8S 1.5 支持 CPU 和 RAM 两种资源的预留,更高版本支持 Disk 资源的预留
以下参考设置是个人建议:
- CPU:作为可压缩资源,超出配额的后果是运行变慢,影响较小,为了充分发挥节点性能,CPU 不预留。
- RAM:8GB < RAM <= 16GB 预留 3GB;RAM > 16G 预留 4GB;(以上机器只跑k8s服务,没有额外应用服务)
- Disk:磁盘可预留 5% 至 10% 左右
如何预留
kubelet 公开了一个名为 Node Allocatable 的特性,有助于为系统守护进程预留计算资源。kubernetes 推荐集群管理员按照每个节点上的工作负载密度配置 Node Allocatable
。
更多推荐
所有评论(0)