「技术干货」kubelet cgroup分析 kubelet主要功能
suiw9 2024-10-31 16:04 25 浏览 0 评论
作者/李逸锋
cgroup简介
控制组cgroup(control group)是Linux kernel的一项功能,它用来控制进程对资源的分配,包括CPU、内存、网络带宽等。
Linux kernel提供一系列资源管控器,由systemd自动挂载。Red Hat Enterprise Linux 7下默认挂载了如下子系统:
blkio:对输入/输出访问存取块设备设定权限。
cpu:使用CPU调度程序让cgroup的任务可以存取CPU。它与cpuacct管控器一起挂载在同一mount上。
cpuacct:自动生成cgroup中任务占用CPU资源的报告。它与CPU管控器一起挂载在同一mount上。
cpuset:给cgroup中的任务分配独立CPU(在多芯系统中)和内存节点。
devices:允许或禁止cgroup中的任务存取设备。
freezer:暂停或恢复cgroup中的任务。
memory:对cgroup中的任务可用内存做出限制,并且自动生成任务占用内存资源报告。
net_cls:使用等级识别符(classid)标记网络数据包,这让Linux流量控制器(tc指令)可以识别来自特定cgroup任务的数据包。
perf_event:允许使用perf工具来监控cgroup。
hugetlb:允许使用大篇幅的虚拟内存页,并且给这些内存页强制设定可用资源量。
kubelet中用到了下面这些子系统(除systemd)
下面列举一些常用的cgroup参数:
cpu.cfs_period_us:此参数可以设定重新分配cgroup可用CPU资源的时间间隔。
cpu.cfs_quota_us:此参数可以设定在某一阶段(由cpu.cfs_period_us规定)某个cgroup中所有任务可运行的时间总量。
cpu.shares:此参数用一个整数来设定cgroup中任务CPU可用时间的相对比例。
memory.limit_in_bytes:设定用户内存(包括文件缓存)的最大用量。
memory.oom_control:当触发oom时oom-killer的行为。
cgroup的详细配置参考红帽文档:
https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/7/html/resource_management_guide/sec-cpu
kubelet配置
kubelet的详细配置参考k8s文档:
https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/#kubelet-config-k8s-io-v1beta1-KubeletConfiguration
cgroup相关参数
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,否则kubelet启动会报错。
kube-reserved:为Kubernetes组件保留的计算资源,例如docker daemon、kubelet、kube-proxy等,比如—kube-reserved=cpu=1000m,memory=8Gi,ephemeral-storage=16Gi。
kube-reserved-cgroup:如果你设置了–kube-reserved,那么请一定要设置对应的cgroup,并且该cgroup目录要事先创建好(/sys/fs/cgroup/{subsystem}/kubelet.slice),否则kubelet将不会自动创建导致kubelet启动失败。比如设置为kube-reserved-cgroup=/kubelet.slice,需要在每个subsystem的根目录下创建kubelet.slice目录。
system-reserved:用于配置为System进程预留的资源量,比如—system-reserved=cpu=500m,memory=4Gi,ephemeral-storage=4Gi。
system-reserved-cgroup:如果你设置了–system-reserved,那么请一定要设置对应的cgroup,并且该cgroup目录要事先创建好(/sys/fs/cgroup/{subsystem}/system.slice),否则kubelet将不会自动创建导致kubelet启动失败。比如设置为system-reserved-cgroup=/system.slice,需要在每个subsystem的根目录下创建system.slice目录。
cgroup-root:kubelet中所有的cgroup层级都会在该root路径下,默认是/,如果开启--cgroups-per-qos=true,则在kubelet containerManager中会调整为/kubepods。
驱逐相关参数
eviction-minimum-reclaim:表示每一次eviction必须至少回收多少资源。
eviction-pressure-transition-period:默认为5分钟,脱离pressure condition的时间,超过阈值时,节点会被设置为memory pressure或者disk pressure,然后开启pod eviction。
eviction-hard:一系列的阈值,比如memory.available<1Gi,即当节点可用内存低于1Gi时,会立即触发一次pod eviction。
eviction-soft:与hard相对应,也是一系列法制,比如memory.available<1.5Gi。但它不会立即执行pod eviction,而会等待eviction-soft-grace-period时间,假如该时间过后,依然还是达到了eviction-soft,则触发一次pod eviction。
eviction-soft-grace-period:默认为90秒
eviction-max-pod-grace-periopd:eviction-soft时,终止pod的grace时间。
k8s推荐的cgroup配置参考:
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/node-allocatable.md#recommended-cgroups-setup
我的节点配置
# 我的节点cn-hangzhou.i-bp10p1cp6vlexdnt67vf上的/var/lib/kubelet/config.yaml
https://gitee.com/liyifeng1026908346/k8s-learning/blob/master/k8s%E8%8A%82%E7%82%B9%E9%85%8D%E7%BD%AE/config.yaml
配置如下参数:
# cgroup相关
--cgroup-driver = systemd // cgroup驱动为systemd
--cgroup-root = / // 根cgroup
--cgroups-per-qos = true // 启用qos pod cgroup
--enforce-node-allocatable = [“pods”,“kube-reserved”,“system-reserved”]//开启kube、system资源预留
--kube-reserved-cgroup: /kubelet.slice // kube cgroup路径
--system-reserved-cgroup: /system.slice // system cgroup路径
--kube-reserved: cpu=100m,memory=200Mi // 为kube组件预留的资源
--system-reserved: cpu=200m,memory=1000Mi // 为系统daemon预留的资源
# 驱逐相关
--eviction-minimum-reclaim:... // 每次驱逐必须回收多少资源
--eviction-pressure-transition-period:5m // 脱离pressure condition的时间
--eviction-hard:memory.available<15%,nodefs.available<15%,nodefs.inodesFree<10%,imagefs.available<10% // 硬驱逐阈值
--eviction-soft:imagefs.available<20%,nodefs.available<20% // 软驱逐阈值
--eviction-soft-grace-period:默认90秒 // 软驱逐的死缓时间
--eviction-max-pod-grace-period:600 // pod最大的grace时间
节点Allocatable资源计算公式为:
[Allocatable] = [Node Capacity] - [Kube-Reserved] - [System-Reserved] - [Hard-Eviction-Threshold]
该配置下,当前节点2u8G可分配资源Allocatable为:
Allocatable (cpu) = 2 - 0.1 - 0.2 - 2*15% = 1.4u
Allocatable (memory) = 8 - 0.2 - 1 - 8*15% = 5.6G
源码分析
分析kubelet对node、pod做了哪些cgroup配置:
node的cgroup配置
当前节点kubelet配置如图:
kubelet启动后,会根据kubelet配置参数,设置cgroup限制kube组件、系统进程的资源使用。
中间包含一些内部结构的转化,flag--- > &CgroupConfig{...} ---> &libcontainerconfigs.Cgroup{...},libcontainer这个库就是docker贡献的,封装了包括对cgroup的操作,结构描述如下:
&libcontainerconfigs.Cgroup{..}。
&Resources{...},包含了所有的cgroup配置参数。
最终写到文件系统上表现为:
/sys/fs/cgroup/kubelet.slice
.
├── cpu
│ ├── cpu.cfs_period_us 100000
│ ├── cpu.cfs_quota_us -1
│ ├── cpu.rt_period_us 1000000
│ ├── cpu.rt_runtime_us 0
│ └── cpu.shares 102
├── memory
│ ├── memory.kmem.limit_in_bytes 9223372036854771712
│ ├── memory.kmem.tcp.limit_in_bytes 9223372036854771712
│ ├── memory.limit_in_bytes 209715200
│ ├── memory.memsw.limit_in_bytes 9223372036854771712
│ ├── memory.oom_control 始终开启oom-killer
│ └── memory.soft_limit_in_bytes 9223372036854771712
└── ...
/sys/fs/cgroup/system.slice
.
├── cpu
│ ├── cpu.cfs_period_us 100000
│ ├── cpu.cfs_quota_us -1
│ ├── cpu.rt_period_us 1000000
│ ├── cpu.rt_runtime_us 0
│ └── cpu.shares 204
├── memory
│ ├── memory.kmem.limit_in_bytes 9223372036854771712
│ ├── memory.kmem.tcp.limit_in_bytes 9223372036854771712
│ ├── memory.limit_in_bytes 1048576000
│ ├── memory.memsw.limit_in_bytes 9223372036854771712
│ ├── memory.oom_control 始终开启oom-killer
│ └── memory.soft_limit_in_bytes 9223372036854771712
└── ...
该配置表示:
kube进程最多可用的CPU时间不受限制,cpu.cfs_quota_us = -1。
kube进程最低可用的CPU时间为1CPU02/sum(其它进程cpu.shares),当发CPU竞争时生效(kube-reserved: cpu=100m)。
kube进程最多可用内存为209715200,即200M(kube-reserved: memory=200Mi)。
kube进程最低可用内存不对应任何cgroup配置。
system进程最多可用的CPU时间不受限制,cpu.cfs_quota_us = -1。
system进程最低可用的CPU时间为204/sum(其它进程cpu.shares),当发CPU竞争时生效(system-reserved: cpu=200m)。
system进程最多可用内存为1048576000,即1000M(system-reserved: memory=1000Mi)。
system进程最低可用内存不对应任何cgroup配置。
qos pods的cgroup配置
创建一个pod,资源限制如下:
pod创建前,会对其做cgroup配置:
相关的子系统包括CPU、memory、hugelb:
限制每个qos等级的pods资源:
这里,会去设置pod的cgroup:
最终写到文件系统上的cgroup配置如下:
.
├── cpu
│ ├── cpu.cfs_period_us 100000
│ ├── cpu.cfs_quota_us 20000
│ ├── cpu.rt_period_us 1000000,指定在某个时间段内对cpu资源访问重新分配的频率
│ ├── cpu.rt_runtime_us 0 ,指定某个时间段中cgroup中的任务对cpu资源的最长连续访问时间
│ └── cpu.shares 102
├── memory
│ ├── memory.kmem.limit_in_bytes 9223372036854771712
│ ├── memory.kmem.tcp.limit_in_bytes 9223372036854771712
│ ├── memory.limit_in_bytes 314572800
│ ├── memory.memsw.limit_in_bytes 9223372036854771712
│ ├── memory.oom_control 始终开启oom-killer
│ └── memory.soft_limit_in_bytes 9223372036854771712
├── pids
│ ├── pids.max 需kubelet启用特性SupportPodPidsLimit
└── ...
该配置表示:
该pod最多可用的CPU时间为20000/100000 = 0.2,即200m(limits.cpu)。
该pod最低可用的CPU时间权重为102/sum(其它进程cpu.shares),当发CPU竞争时生效(requests.cpu)。
该pod最多可用内存为314572800,即300M(limit.memory)。
该pod最低可用内存不对应任何cgroup配置。
问题记录
kubele启动失败,/system.slice cgroup does not exis
对于Centos系统,cpuset和hugetlb subsystem是默认没有初始化system.slice,因此需要手动创建,否则会报Failed to start ContainerManager Failed to enforce System Reserved Cgroup Limits on “/system.slice”: “/system.slice” cgroup does not exist的错误日志。
kubelet启动失败,device or resource busy
配置的system-reserved过低,导致cgroup配置无法写入,报错提示”device or resource busy”。
其原因为:若写入的memory.limit_in_bytes值小于当前已使用的内存,将触发os内存回收。若系统无法将内存无法回收至阈值以下,则会报这个错。
kubelet cgroup参数配置步骤整理
# 修改kubelet配置文件/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf,启动kubelet前先创建下面几个cgroup目录:
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/cpu,cpuacct/kubelet.slice
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/memory/kubelet.slice
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/systemd/kubelet.slice
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/pids/kubelet.slice
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/cpu,cpuacct/kubelet.slice
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/cpuset/kubelet.slice
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/hugetlb/kubelet.slice
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/cpuset/system.slice
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/hugetlb/system.slice
# 修改/var/lib/kubelet/config.yaml,增加下面几项配置:
enforceNodeAllocatable:
- pods
- kube-reserved #开启kube资源预留
- system-reserved #开启system资源预留
kubeReserved:
cpu: 200m
memory: 500Mi
kubeReservedCgroup: /kubelet.slice # 指定kube资源预留的 cgroup
systemReserved:
cpu: 300m
memory: 1000Mi # 此处配置的内存要大于系统已使用内存,否则kubelet无法启动
systemReservedCgroup: /system.slice # 指定system资源预留的 cgroup
# 部署一个应用测试做CPU、内存压力测试
# deploy-stress.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: liyifeng-stress
spec:
selector:
matchLabels:
app.kubernetes.io/component: stress
template:
metadata:
labels:
app.kubernetes.io/component: stress
spec:
nodeSelector:
kubernetes.io/hostname: 6448bb57-6bb3-4c89-b806-3a3656ef349e
containers:
- args:
- stress
- --cpu
- "2"
- --vm
- "1"
- --vm-bytes
- "100M"
image: polinux/stress
imagePullPolicy: IfNotPresent
name: stress
# 增加用户进程CPU、内存的申请量,观察kubelet不同配置情况下的节点健康情况。
参考文档
https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/7/html/resource_management_guide/sec-cpu(红帽cgroup配置)
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/node-allocatable.md#recommended-cgroups-setup(k8s官方建议cgroup配置)
https://github.com/rootsongjc/qa/issues/3(device or resource busy)
相关推荐
- 俄罗斯的 HTTPS 也要被废了?(俄罗斯网站关闭)
-
发布该推文的ScottHelme是一名黑客,SecurityHeaders和ReportUri的创始人、Pluralsight作者、BBC常驻黑客。他表示,CAs现在似乎正在停止为俄罗斯域名颁发...
- 如何强制所有流量使用 HTTPS一网上用户
-
如何强制所有流量使用HTTPS一网上用户使用.htaccess强制流量到https的最常见方法可能是使用.htaccess重定向请求。.htaccess是一个简单的文本文件,简称为“.h...
- https和http的区别(https和http有何区别)
-
“HTTPS和HTTP都是数据传输的应用层协议,区别在于HTTPS比HTTP安全”。区别在哪里,我们接着往下看:...
- 快码住!带你十分钟搞懂HTTP与HTTPS协议及请求的区别
-
什么是协议?网络协议是计算机之间为了实现网络通信从而达成的一种“约定”或“规则”,正是因为这个“规则”的存在,不同厂商的生产设备、及不同操作系统组成的计算机之间,才可以实现通信。简单来说,计算机与网络...
- 简述HTTPS工作原理(简述https原理,以及与http的区别)
-
https是在http协议的基础上加了一层SSL(由网景公司开发),加密由ssl实现,它的目的是为用户提供对网站服务器的身份认证(需要CA),以至于保护交换数据的隐私和完整性,原理如图示。1、客户端发...
- 21、HTTPS 有几次握手和挥手?HTTPS 的原理什么是(高薪 常问)
-
HTTPS是3次握手和4次挥手,和HTTP是一样的。HTTPS的原理...
- 一次安全可靠的通信——HTTPS原理
-
为什么HTTPS协议就比HTTP安全呢?一次安全可靠的通信应该包含什么东西呢,这篇文章我会尝试讲清楚这些细节。Alice与Bob的通信...
- 为什么有的网站没有使用https(为什么有的网站点不开)
-
有的网站没有使用HTTPS的原因可能涉及多个方面,以下是.com、.top域名的一些见解:服务器性能限制:HTTPS使用公钥加密和私钥解密技术,这要求服务器具备足够的计算能力来处理加解密操作。如果服务...
- HTTPS是什么?加密原理和证书。SSL/TLS握手过程
-
秘钥的产生过程非对称加密...
- 图解HTTPS「转」(图解http 完整版 彩色版 pdf)
-
我们都知道HTTPS能够加密信息,以免敏感信息被第三方获取。所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议。...
- HTTP 和 HTTPS 有何不同?一文带你全面了解
-
随着互联网时代的高速发展,Web服务器和客户端之间的安全通信需求也越来越高。HTTP和HTTPS是两种广泛使用的Web通信协议。本文将介绍HTTP和HTTPS的区别,并探讨为什么HTTPS已成为We...
- HTTP与HTTPS的区别,详细介绍(http与https有什么区别)
-
HTTP与HTTPS介绍超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的...
- 一文让你轻松掌握 HTTPS(https详解)
-
一文让你轻松掌握HTTPS原文作者:UC国际研发泽原写在最前:欢迎你来到“UC国际技术”公众号,我们将为大家提供与客户端、服务端、算法、测试、数据、前端等相关的高质量技术文章,不限于原创与翻译。...
- 如何在Spring Boot应用程序上启用HTTPS?
-
HTTPS是HTTP的安全版本,旨在提供传输层安全性(TLS)[安全套接字层(SSL)的后继产品],这是地址栏中的挂锁图标,用于在Web服务器和浏览器之间建立加密连接。HTTPS加密每个数据包以安全方...
- 一文彻底搞明白Http以及Https(http0)
-
早期以信息发布为主的Web1.0时代,HTTP已可以满足绝大部分需要。证书费用、服务器的计算资源都比较昂贵,作为HTTP安全扩展的HTTPS,通常只应用在登录、交易等少数环境中。但随着越来越多的重要...
你 发表评论:
欢迎- 一周热门
-
-
Linux:Ubuntu22.04上安装python3.11,简单易上手
-
宝马阿布达比分公司推出独特M4升级套件,整套升级约在20万
-
MATLAB中图片保存的五种方法(一)(matlab中保存图片命令)
-
别再傻傻搞不清楚Workstation Player和Workstation Pro的区别了
-
Linux上使用tinyproxy快速搭建HTTP/HTTPS代理器
-
如何提取、修改、强刷A卡bios a卡刷bios工具
-
Element Plus 的 Dialog 组件实现点击遮罩层不关闭对话框
-
日本组合“岚”将于2020年12月31日停止团体活动
-
SpringCloud OpenFeign 使用 okhttp 发送 HTTP 请求与 HTTP/2 探索
-
tinymce 号称富文本编辑器世界第一,大家同意么?
-
- 最近发表
- 标签列表
-
- dialog.js (57)
- importnew (44)
- windows93网页版 (44)
- yii2框架的优缺点 (45)
- tinyeditor (45)
- qt5.5 (60)
- windowsserver2016镜像下载 (52)
- okhttputils (51)
- android-gif-drawable (53)
- 时间轴插件 (56)
- docker systemd (65)
- slider.js (47)
- android webview缓存 (46)
- pagination.js (59)
- loadjs (62)
- openssl1.0.2 (48)
- velocity模板引擎 (48)
- pcre library (47)
- zabbix微信报警脚本 (63)
- jnetpcap (49)
- pdfrenderer (43)
- fastutil (48)
- uinavigationcontroller (53)
- bitbucket.org (44)
- python websocket-client (47)