引发Pod驱逐的原因
最近在处理一个项目的k8s集群时,频繁遇到pod在不同节点驱逐的现象。
如此频繁的驱逐引发了"节点状态振荡",是某node节点或多个Node节点出发了"驱逐信号"造成的。
集群由1个master和4台node组成,经仔细检查发现存在如下问题:
- 其中master-node节点和另外3台node节点内核为3.10版本,只有一台node节点为5.4的新版内核
- 其中一台node节点文件句柄数没有修改为,1024
- 五台的磁盘空间均比较小,但是经查有3台可以通过逻辑卷扩容
-
磁盘占用率,已经发现有2台出现磁盘占用率超过80%的现象
kubelet 有如下所示的默认硬驱逐阈值:memory.available<100Mi nodefs.available<10% nodefs.inodesFree<5% imagefs.available<15%
由上可见,文件句柄数过小和磁盘空间使用过高都会触发阈值,内核版本过低可能造成资源分配不平衡及内存占用高(内存泄漏风险)也会引发驱逐。
如上逐一解决后,观察一周时间,至今还没有发生驱逐现象
总结:在集群规模较小的情况下,要充分保障各资源情况,否则发生驱逐后到其它节点仍然无法满足资源需求,会引起节点震荡。集群机器数量较多,被驱逐到其它节点上的pod,在多台机器上资源不满足的概率较小。
以下是一些相关说明:
驱逐信号
什么是驱逐信号呢?简单理解就是,kubelet什么时候什么场景下开始驱逐pod呢?总的有几个参考值吧,这就是驱逐信号,k8s提供了以下几种驱逐信号
驱逐信号 描述
memory.available node.status.capacity[memory] - node.stats.memory.workingSet nodefs.available node.stats.fs.available nodefs.inodesFree node.stats.fs.inodesFree imagefs.available node.stats.runtime.imagefs.available imagefs.inodesFree node.stats.runtime.imagefs.inodesFree memory.available是针对内存资源,其余4个驱逐信号都是针对磁盘空间的。
上面的每个信号都支持字面值或百分比的值。基于百分比的值的计算与每个信号对应的总容量相关。
memory.available 的值从 cgroupfs 获取,而不是通过类似 free -m 的工具。 这很重要,因为 free -m 不能在容器中工作
kubelet 只支持两种文件系统分区。
nodefs 文件系统,kubelet 将其用于卷和守护程序日志等。
imagefs 文件系统,容器运行时用于保存镜像和容器可写层。
imagefs 可选。kubelet 使用 cAdvisor 自动发现这些文件系统。 kubelet 不关心其它文件系统。当前不支持配置任何其它类型。 例如,在专用 filesytem 中存储卷和日志是 不可以 的。
我们可以想想worker节点中什么最耗磁盘空间,无非也就下面几项 镜像文件:有的很大,几百M。每次更新deployment,都会拉取新的镜像,长此以往,不通版本的镜像肯定要消耗很大磁盘空间的。imagefs文件系统正是管理这些镜像的,如果我们配置的驱逐信号中有imagefs.available或者imagefs.inodesFree,且触发驱逐阀值后,k8s将会主动清理一些没有使用的版本镜像,以此来释放更多的磁盘空间。 日志:随着应用的长时间运行,日志会越来越庞大,volume不管你使用的是emptyDir,hostPath,还是nfs,clustersfs,都会将日志存储在节点上的,占用worker节点的磁盘空间也将会越来越大。docker中的日志分为俩种,docker主进程的标准输出日志和项目中用户产生的文件日志,正好对应nodefs文件系统中的卷和守护程序日志。如果我们配置的驱逐信号中有nodefs.available或者nodefs.inodesFree且触发驱逐阀值后,k8s将会清理这些日志,清理这些的日志的方式只能是驱逐pod了。
软驱逐阈值
使用一对由驱逐阈值和宽限期组成的配置对。在宽限期内持续超过阀值则进行驱逐。比如下面这俩行配置,表示的意义是当节点的memory.available小于500Mi,且在1分30内持续小于500Mi时,开启触发驱逐。下面这俩行是成对出现的。
软驱逐阈值使用关键字eviction-soft
--eviction-soft=memory.available<500Mi --eviction-soft-grace-period=memory.available=1m30s
硬驱逐阈值
相对于软驱逐阈值,区别就是没有缓冲时间,只要触发驱逐信号,就立即开始驱逐而不是优雅的终止。
硬驱逐阈值使用关键字eviction-hard。比如下面例子
--eviction-hard=memory.available<500Mi,nodefs.available<20%
- 引发Pod驱逐的原因
- Oracle12c ora-28040报错及修改字符集
- rbd空间扩容失败问题
- centos进入dracut模式修复grub启动
- java oom堆栈分析
- jvm参数说明
- go自定义函数
- 生产环境centos7 openssh与ssl升级
- 无法启动的docker容器镜像内mysql数据恢复
- Kubectl证书过期更新
- MySQL load导入大数据
- ceph 运维常用指令
- 重启pod发现有pod无法挂在pvc
- K8s污点和容忍度
- ceph rbd扩容
- centos升级内核
- k8s 节点优化
- k8s 选择版本时注意cgroup问题(内存泄漏)
- k8s 创建用户及rbac授权