kubernetes集群节点资源预留
问题
默认kubelet
没有配置资源预留,host
上所有的资源(cpu
, 内存, 磁盘) 都是可以给 pod
使用的。而当一个节点上的 pod
将资源吃满时,系统层面可能会干掉 k8s
核心组件进程, 从而导致改节点 not ready
,此时 k8s
会将改节点的所有 pod
调度到其他节点重建,如果其他节点资源也不够,那么其他节点也会 not ready
,进而引起集群雪崩效应。
如何避免
通过为 k8s
设置 kube
组件资源预留和 system
系统资源预留,保证节点的 pod
不会吃满节点资源
目前支持cpu
, memory
, ephemeral-storage
三种资源预留。
cpu
:cpu
是配置cpu shares
,实际上对应的是cpu
的优先级,简单来说,这个在cpu
繁忙时,它能有更高优先级获取更多cpu
资源。memory
:k8s
默认不使用swap
,这里指的就是实际的内存ephemeral-storage
是kubernetes1.8
开始引入的一个资源限制的对象,kubernetes 1.10
版本中kubelet
默认已经打开的了,到目前1.11
还是beta
阶段,主要是用于对本地临时存储使用空间大小的限制,如对pod
的empty dir
、/var/lib/kubelet
、日志、容器可读写层的使用大小的限制。
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
Node Capacity
---------------------------
| kube-reserved |
|-------------------------|
| system-reserved |
|-------------------------|
| eviction-threshold |
|-------------------------|
| |
| allocatable |
| (available for pods) |
| |
| |
---------------------------
eviction-threshold
实际上是对pod
limit_resource
的补充,因为limit_resource
只能针对单个pod
做资源限制,当这个pod
达到限制的阀值后,kubelet
便会oom_killer
掉这个pod
,而eviction-threshold
根据事先设定的Eviction Thresholds
来触发Eviction
,调用算法筛选出合适的几个pod
,kill
掉一个或多个pod
回收资源,被eviction
掉的pod
会被kube-scheduler
在其他节点重新调度起来
eviction-threshold
分为两类:
Soft Eviction Thresholds
达到触发值后,发送信号给 pod
, 并不是马上去驱逐pod
,而是等待一个缓冲时间 grace period
,
配置 eviction-soft
必须指定 grace period
Hard Eviction Thresholds
达到触发值后,直接筛选出对应的pod
kill
掉
配置
--enforce-node-allocatable
,默认为pods
,要为kube
组件和System
进程预留资源,则需要设置为pods,kube-reserved,system-reserve
--cgroups-per-qos
,Enabling QoS and Pod level cgroups
,默认开启。开启后,kubelet
将会管理所有workload Pods
的cgroups
。--cgroup-driver
,默认为cgroupfs
,另一可选项为systemd
。取决于容器运行时使用的cgroup driver
,kubelet
与其保持一致。比如你配置docker
使用systemd cgroup driver
,那么kubelet
也需要配置--cgroup-driver=systemd
--kube-reserved
,用于配置为kube
组件(kubelet
,kube-proxy
,dockerd
等)预留的资源量,比如--kube-reserved=cpu=1000m,memory=8Gi,ephemeral-storage=16Gi
。--kube-reserved-cgroup
,如果你设置了--kube-reserved
,那么请一定要设置对应的cgroup
,并且该cgroup
目录要事先创建好,否则kubelet
将不会自动创建导致kubelet
启动失败。比如设置为kube-reserved-cgroup=/system.slice/kubelet.service
--system-reserved
,用于配置为System
进程预留的资源量,比如--system-reserved=cpu=500m,memory=4Gi,ephemeral-storage=4Gi
--system-reserved-cgroup
,如果你设置了--system-reserved
,那么请一定要设置对应的cgroup
,并且该cgroup
目录要事先创建好,否则kubelet
将不会自动创建导致kubelet
启动失败。比如设置为system-reserved-cgroup=/system.slice
--eviction-hard
,用来配置kubelet
的hard eviction
条件,只支持memory
和ephemeral-storage
两种不可压缩资源。当出现MemoryPressure
时,Scheduler
不会调度新的Best-Effort QoS Pods
到此节点。当出现DiskPressure
时,Scheduler
不会调度任何新Pods到此节点。
配置示例
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/var/lib/kubelet
# CPUAccounting=true
# MemoryAccounting=true
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/pids/system.slice/kubelet.service
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/cpu/system.slice/kubelet.service
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/cpuacct/system.slice/kubelet.service
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/cpuset/system.slice/kubelet.service
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/memory/system.slice/kubelet.service
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/systemd/system.slice/kubelet.service
ExecStart=/usr/local/bin/kubelet \--cgroup-driver=systemd \--enforce-node-allocatable=pods,kube-reserved,system-reserved \--kube-reserved-cgroup=/system.slice/kubelet.service \--system-reserved-cgroup=/system.slice \--kube-reserved=cpu=1000m,memory=2Gi,ephemeral-storage=1Gi \--system-reserved=cpu=1000m,memory=2Gi,ephemeral-storage=1Gi \--max-pods=100 \--eviction-hard=imagefs.available<15%,memory.available<300Mi,nodefs.available<10%,nodefs.inodesFree<3% \--eviction-max-pod-grace-period=40 \--eviction-minimum-reclaim=memory.available=1Gi,nodefs.available=5Gi,imagefs.available=5Gi \--eviction-soft-grace-period=memory.available=30s,nodefs.available=2m,imagefs.available=2m,nodefs.inodesFree=2m \--eviction-soft=imagefs.available<20%,memory.available<1Gi,nodefs.available<15%,nodefs.inodesFree<5% \--experimental-bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig \--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \--rotate-certificates \--cert-dir=/etc/kubernetes/ssl \--cluster_dns=10.96.0.2 \--cluster_domain=cluster.local. \--hairpin-mode=promiscuous-bridge \--allow-privileged=true \--fail-swap-on=false \--serialize-image-pulls=false \--logtostderr=true \--network-plugin=cni \--cni-conf-dir=/etc/cni/net.d \--cni-bin-dir=/opt/cni/bin \--v=1
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
注意: 如果设置完资源预留,重启 kubelet
之后,发现 node
变成 not ready
,kubectl describe node
查看, 报错为:
failed to write 6442450944 to memory.limit_in_bytes: write /sys/fs/cgroup/memory/system.slice/memory.limit_in_bytes: device or resource busy
是因为实际系统内存使用量大于 --system-reserved=cpu=1000m,memory=6Gi
的配置,将 6g
改大之后重启kubelet
即可,当然具体改为多少,要看节点上实际系统占用内存(笔者测试机上装有 ceph
, 所以系统部分所需内存较大)
测试
环境
hostname | role | cpu | memory | –kube-reserved=cpu | –kube-reserved=memory | –system-reserved=cpu | –system-reserved=memory |
---|---|---|---|---|---|---|---|
k8s1 | master | 12 | 47G | 1000m | 2Gi | 1000m | 15Gi |
k8s2 | master | 32 | 31G | 1000m | 2Gi | 1000m | 8Gi |
k8s3 | node | 16 | 62G | 1000m | 2Gi | 1000m | 8Gi |
describe node
# k8s1
Addresses:InternalIP: 10.10.1.223Hostname: k8s1
Capacity:cpu: 12ephemeral-storage: 574727312Kihugepages-1Gi: 0hugepages-2Mi: 0memory: 49425780Ki # k8s1 实际总内存: 47Gpods: 110
Allocatable:cpu: 10ephemeral-storage: 523226238919hugepages-1Gi: 0hugepages-2Mi: 0memory: 31292788Ki # k8s1 节点可以分配给 pod 的总内存: 30Gpods: 110
...
Allocated resources:(Total limits may be over 100 percent, i.e., overcommitted.)Resource Requests Limits-------- -------- ------cpu 8023m (80%) 35643m (356%)memory 32389500928 (101%) 75199505664 (234%)ephemeral-storage 0 (0%) 0 (0%)# k8s2
Capacity:cpu: 32ephemeral-storage: 459378800Kihugepages-1Gi: 0hugepages-2Mi: 0memory: 32906916Kipods: 110
Allocatable:cpu: 30ephemeral-storage: 416921050436hugepages-1Gi: 0hugepages-2Mi: 0memory: 22113956Kipods: 110
...
Allocated resources:(Total limits may be over 100 percent, i.e., overcommitted.)Resource Requests Limits-------- -------- ------cpu 8123m (27%) 30203m (100%)memory 22098028Ki (99%) 60566922496 (267%)ephemeral-storage 0 (0%) 0 (0%)# k8s3
Capacity:cpu: 16ephemeral-storage: 575257712Kihugepages-1Gi: 0hugepages-2Mi: 0memory: 65916188Kipods: 110
Allocatable:cpu: 14ephemeral-storage: 523715055558hugepages-1Gi: 0hugepages-2Mi: 0memory: 55123228Kipods: 110
...
Allocated resources:(Total limits may be over 100 percent, i.e., overcommitted.)Resource Requests Limits-------- -------- ------cpu 12785m (91%) 71410m (510%)memory 54820406Ki (99%) 155630527744 (275%)ephemeral-storage 0 (0%) 0 (0%)
k8s1
节点实际总内存 47G
,减去 --kube-reserved=memory=2Gi
, 再减去 --system-reserved=memory=15Gi
, 为 k8s1
可以分配给 pod
的总内存 30G
,并且该 30G
就是节点 resource requests
的上限
可以看到为 kube
和系统配置的资源预留确实生效了
再看下节点 pod
的requests
而 kube-scheduler
根据 pod
设置的 resource requests
为 pod
选取合适的节点,现在 3台节点上requests
都满了,故无法再为新的 pod
调度,这时候新建 pod
会处于 Pending
状态,describe pod
会显示
Events:Type Reason Age From Message---- ------ ---- ---- -------Warning FailedScheduling <unknown> default-scheduler 0/3 nodes are available: 3 Insufficient memory.
而实际上各节点的 free -h
输出如下:
# k8s1
root@k8s1:~# free -htotal used free shared buff/cache available
Mem: 47G 25G 14G 13M 7.7G 21G
Swap: 0B 0B 0B# k8s2
root@k8s2:~# free -htotal used free shared buff/cache available
Mem: 31G 27G 210M 13M 4.2G 5.1G
Swap: 0B 0B 0B# k8s3
root@k8s3:~# free -htotal used free shared buff/cache available
Mem: 62G 36G 12G 134M 14G 29G
Swap: 0B 0B 0B
会发现实际上,除去 --kube-reserved=memory
和 --system-reserved=memory
,还有可用内存。
所以我们将上图中那些resource requests
设置不合理的pod
的requests memory
设置小一点,就可以调度新的 pod
了
所以这里要清楚,k8s
通过 pod
配置的 resource requests
值来调度 pod
到资源有余的合适的节点,而节点可用的总资源就是节点实际总资源减去为 kube
和 system
预留的资源
使用 kubectl top pod -A
查看 pod
实际资源使用,这里面显示的值就是 resource limit
oom killer
依据的值
root@k8s1:/opt/kubespray# kubectl top pod
NAME CPU(cores) MEMORY(bytes)
whoami-5b4bb9c787-m2vdt 0m 3Mi
注意:kubectl top node
显示的资源值,并不是节点上所有pod
所使用资源的总和
参考
从一次集群雪崩看Kubelet资源预留的正确姿势
kubernetes集群节点资源预留
为系统守护进程预留计算资源
Configure Out of Resource Handling
从kubectl top看K8S监控
kubernetes集群节点资源预留相关推荐
- Promethus搭建 K8S 集群节点资源监控系统
对于集群的监控一般我们需要考虑以下几个方面: Kubernetes 节点的监控:比如节点的 cpu.load.disk.memory 等指标 内部系统组件的状态:比如 kube-scheduler.k ...
- 零停机给Kubernetes集群节点打系统补丁
点击上方 "编程技术圈"关注, 星标或置顶一起成长 后台回复"大礼包"有惊喜礼包! 每日英文 A person who knows how to laugh a ...
- 如何利用Kubernetes集群提升资源利用率?
导语 | 近日,云+社区技术沙龙"高效智能运维"圆满落幕.本期沙龙围绕运维展开了一场技术盛宴,从AIOps.Serverless DevOps.蓝鲸PaaS平台.K8S等分享关于业 ...
- kubelet 配置节点资源预留
kubelet 配置节点资源预留 Kubernetes 的节点可以按照节点的资源容量进行调度,默认情况下 Pod 能够使用节点全部可用容量.这样就会造成一个问题,因为节点自己通常运行了不少驱动 OS ...
- 如何部署一个Kubernetes集群
来源 | 无敌码农 责编 | 寇雪芹 头图 | 下载于视觉中国 在上一篇文章<Kubernetes和Docker的关系是什么?>中,和大家分享了关于Kubernetes的基本系统架构以及关 ...
- 中通快递关键业务和复杂架构挑战下的 Kubernetes 集群服务暴露实践
本文是上海站 Meetup 讲师王文虎根据其分享内容整理的文章. KubeSphere 社区的小伙伴们,大家好.我是中通快递容器云平台的研发工程师王文虎,主要负责中通快递容器云平台开发.应用容器化推广 ...
- 初试 Kubernetes 集群使用 CephFS 文件存储
目录 Kubernetes PersistentVolumes 介绍 环境.软件准备 单节点使用 CephFS Kubernetes PV & PVC 方式使用 CephFS 测试跨节点使用 ...
- 云原生第4课:Kubernetes 集群管理
本篇文章来自<华为云云原生王者之路训练营>黄金系列课程第4课,由华为云Kubernetes容器平台技术专家Alan主讲,详细介绍Kubernetes集群和Kubernetes节点的生命周期 ...
- vivo AI计算平台 Kubernetes集群Ingress网关实践
1.背景 vivo 人工智能计算平台小组从 2018 年底开始建设 AI 计算平台至今,已经在 kubernetes 集群.以及离线的深度学习模型训练等方面,积累了众多宝贵的开发.运维经验,并逐步打造 ...
最新文章
- 手动创建servlet
- 文件内容、关键字匹配,split 和 indexOf 均可实现
- python rest 框架_python-更新用户REST框架Django
- c语言继承与派生作用,C++中继承与派生是如何实现的?
- android全方位性能优化方法
- iOS 基础 第五天(0811)
- 广播接收者的特点和版本差异
- You need to use a Theme.AppCompat theme (or descendant) with this activity
- 谷歌浏览器如何长截屏
- Excel表VLOOKUP多个条件匹配数据
- 无人车之美——技术要点速览
- office365打开服务器文件出错,Microsoft Office 365个人版打开显示错误
- 路由器怎么连接台式电脑
- android 监听本机网络请求_前端系列课程(2)-网络基础概念(URL)
- 人工智能,机器学习,深度学习(笔记)
- 基于京东云GPU云主机搭建TensorFlow深度学习环境
- 算法与数据结构入门一篇就搞定
- 乙腈和水共沸_常用有机溶剂共沸点
- Sql Server级联操作
- python中累加函数_对Python实现累加函数的方法详解
热门文章
- 计算机硬件的漏洞,震惊了硬件圈子的CPU漏洞,到底是个什么鬼?
- 修理电脑笔记 -- 驱动的问题(如触摸屏 指纹解锁之类的驱动在重装系统之后无法使用)
- win7 pe 修改服务器地址,pe下修改win7服务器地址
- python+Linux centos7搭建服务器
- 搭建项目-快速搭建电商平台后台管理系统及逆向生成微服务基本功能
- pip使用163源(linux)
- 【论文-笔记】软件化雷达显控终端的研究
- 五子棋AI - 局面状态
- linux的dev中有video,为啥我的/dev/video0打不开!
- EXCEL中合并同列中连续相同内容的单元格