前言
默认kubelet没配置资源预留应用没做应用资源限制情况下,那host上所有资源都是可以给pod调配使用的,这样很容易引起集群雪崩效应,比如集群内有一台上跑的pod没做resource limt导致占用资源过大导致将宿主机压死了,此时这个节点在kubernetes内就是一个no ready的状态了,kubernetes会将这台host上所有的pod在其他节点上重建,也就意味着那个有问题的pod重新跑在其他正常的节点上,将另外正常的节点压跨。循怀下去直到集群内所有主机都挂了,这就是集群雪崩效应。
零、查看节点的Capacity和Allocatable
1 | kubectl describe <node> |
一、CGroup
1. 概念了解
cgroup 是control group的缩写,是linux内核提供的一种可以限制,记录,隔离进程组所使用的物力资源的机制,其中物力资源包含(cpu/memory/io等等). cgroup是将任意进程进行分组化管理的linux内核功能,CGroup 本身是提供将进程进行分组化管理的功能和接口的基础结构,I/O 或内存的分配控制等具体的资源管理功能是通过这个功能来实现的。这些具体的资源管理功能称为 CGroup 子系统或控制器。CGroup 子系统有控制内存的 Memory 控制器、控制进程调度的 CPU 控制器等。
2. Docker 中的CGroup 驱动
- systemd cgroup driver
systemd cgroup driver 是systemd本身提供了一个cgroup的管理方式,使用systemd做cgroup驱动的话,所有的cgroup操作都必须通过systemd的接口来完成,不能手动更改cgroup的文件
- cgroupfs cgroup driver
cgroupfs 比较好理解。比如说要限制内存是多少、要用 CPU share 为多少?其实直接把 pid 写入对应的一个 cgroup 文件,然后把对应需要限制的资源也写入相应的 memory cgroup 文件和 CPU 的 cgroup 文件就可以了
二、配置docker和kubelet的cgroup驱动
默认kubeadm安装的kubernetes集群 cgroup驱动为systemd,这样是开启不了Kubelet Node Allocatable
- docker 配置cgroup驱动为cgroupfs
修改”exec-opts”: [“native.cgroupdriver=systemd”]为”exec-opts”: [“native.cgroupdriver=cgroupfs”]
1 | vim /etc/docker/daemon.json |
1 | { |
- 修改kubelet cgroup 驱动systemd为cgroupfs
/var/lib/kubelet/kubeadm-flags.env``` 1
2```ini
KUBELET_KUBEADM_ARGS="--cgroup-driver=cgroupfs --network-plugin=cni --pod-infra-container-image=nexus.10010sh.cn/pause:3.1
三、Kubelet Node Allocatable
- 概念
- Kubelet Node Allocatable用来为Kube组件和System进程预留资源,从而保证当节点出现满负荷时也能保证Kube和System进程有足够的资源。
- 目前支持cpu, memory, ephemeral-storage三种资源预留。
- Node Capacity是Node的所有硬件资源,kube-reserved是给kube组件预留的资源,system-reserved是给System进程预留的资源, eviction-threshold是kubelet eviction的阈值设定,allocatable才是真正scheduler调度Pod时的参考值(保证Node上所有Pods的request resource不超过Allocatable)。
- Node Allocatable Resource = Node Capacity - Kube-reserved - system-reserved - eviction-threshold
- 配置 修改/var/lib/kubelet/kubeadm-flags.env
1 | KUBELET_KUBEADM_ARGS="--cgroup-driver=cgroupfs --network-plugin=cni --pod-infra-container-image=nexus.10010sh.cn/pause:3.1 \ |
- 配置解析
开启为kube组件和系统守护进程预留资源的功能
1
--enforce-node-allocatable=pods,kube-reserved,system-reserved
设置k8s组件的cgroup
1
--kube-reserved-cgroup=/system.slice/kubelet.service
设置系统守护进程的cgroup
1
--system-reserved-cgroup=/system.slice
配置为k8s组件预留资源的大小,CPU、MEM
1
--kube-reserved=cpu=1,memory=1G
配置为k8s组件预留资源的大小,CPU、MEM
1
--system-reserved=cpu=1,memory=1Gi
驱逐pod的配置:硬阈值(保证95%的内存利用率)
1
--eviction-hard=memory.available<5%,nodefs.available<10%,imagefs.available<10%
驱逐pod的配置:软阈值
1
--eviction-soft=memory.available<10%,nodefs.available<15%,imagefs.available<15%
定义达到软阈值之后,持续时间超过多久才进行驱逐
1
--eviction-soft-grace-period=memory.available=2m,nodefs.available=2m,imagefs.available=2m
驱逐pod前最大等待时间=min(pod.Spec.TerminationGracePeriodSeconds, eviction-max-pod-grace-period),单位秒
1
-eviction-max-pod-grace-period=30
至少回收多少资源,才停止驱逐
1
--eviction-minimum-reclaim=memory.available=0Mi,nodefs.available=500Mi,imagefs.available=500Mi
四、修改Kubelet启动service文件 /lib/systemd/system/kubelet.service
1 | [Unit] |
五、重启kubelet 和docker服务,再次查看节点的Capacity和Allocatable
可以看到配置已经生效
1
2
3
4
5
6
7
8
9
10
11
12
13
14 systemctl restart docker && systemctl restart kubelet
kubectl describe <node>
Capacity:
cpu: 8
ephemeral-storage: 102106104Ki
hugepages-2Mi: 0
memory: 32909464Ki
pods: 110
Allocatable:
cpu: 6
ephemeral-storage: 94100985291
hugepages-2Mi: 0
memory: 30709912Ki
pods: 110
- 本文作者: ChuLinx
- 本文链接: http://yoursite.com/2019/12/15/Kubernetes1.16配置节点资源预留/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!