订阅博客
收藏博客
微博分享
QQ空间分享

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

频道:Kubernetes 标签: 时间:2018年07月26日 浏览:1352次 评论:0条

一、问题

Kubernetes版本:v1.10.2
问题:默认情况下pod能够使用节点全部可用资源。如果用户pod中的应用存在异常,例如疯狂占用内存,那么这些pod将与node上的系统守护进程和k8s组件争夺资源并导致节点资源短缺,从而产生node not ready问题。 
解决方案 
1. 启用kubelet的Node Allocatable特性参考,为k8s组件和系统守护进程预留资源。 官方文档:https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/

2. 设置pod的驱逐策略,官方文档:https://kubernetes.io/docs/tasks/administer-cluster/out-of-resource/

二、方案细节

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-udevdkubelet / docker / journalctlguarantee pod内核 init 进程等best effort pod
oom_score_adj-1000-999-9980大于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
mkdir -p /sys/fs/cgroup/hugetlb/system.slice/kubelet.service


◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。