k8s 节点压力驱逐(Node Pressure Eviction)默认配置带来的影响
k8s 节点压力驱逐(Node Pressure Eviction)默认配置带来的影响
—— 导读 ——
本文将详细介绍 k8s 下节点压力驱逐相关内容。包括1、什么是节点压力驱逐;2、节点压力驱逐的配置示例;3、驱逐配置详解;4、kubelet 如何选择要驱逐哪些 pod;5、触发驱逐后节点状态更新;6、节点压力驱逐默认配置带来的影响。一、什么是节点压力驱逐?
节点压力驱逐(Node Pressure Eviction)是 Kubernetes 的一种机制,用于帮助集群维持稳定性和可靠性。kubelet 会监控集群节点的内存、 磁盘空间和文件系统的 inode 等资源,当这些资源的使用到达指定阈值(固定值或百分比)的时候,kubelet 将主动终止 Pod 以回收节点上资源。节点压力驱逐是 kubelet 主动终止 Pod 以回收节点上资源的过程。
二、配置示例
如下所示为腾讯云 K8S 集群中默认的驱逐配置。
[root@worker-02 ~]# cat /etc/kubernetes/kubelet |grep eviction
EVICTION_HARD="--eviction-hard=nodefs.available<10%,nodefs.inodesFree<5%,imagefs.available<15%,memory.available<100Mi"
[root@worker-02 ~]#
上面的配置只有硬驱逐策略,无软驱逐策略。具体作用如下:
- nodefs.available<10%:当节点的文件系统的可用空间低于 10% 时触发驱逐。
- nodefs.inodesFree<5%:当节点的文件系统的可用 inode 比例低于 5% 时触发驱逐。
- imagefs.available<15%:当容器镜像文件系统的可用空间低于 15% 时触发驱逐。
- memory.available<100Mi:当节点的内存可用空间低于 100Mi 时触发驱逐。
三、驱逐配置详解
kubelet 基于 驱逐信号、驱逐条件、检测间隔 等参数来定义完整的驱逐策略。驱逐信号可以理解为不同的监控指标,例如内存使用量、磁盘使用量;驱逐条件则为判断是否到达驱逐要求的条件,例如内存使用率大于多少、可用的内存比例小于多少;检测检测指检查驱逐条件的频率,例如每隔1分钟检查一次内存使用率是否大于多少。3.1、驱逐信号
Linux 系统中,kubelet 使用如下驱逐信号,值可以是百分比值或者是固定值。
kubelet 支持以下文件系统分区:
-
nodefs:节点的根文件系统,用于本地磁盘卷、emptyDir、日志存储等。例如 nodefs 包含 /var/lib/kubelet/。
-
imagefs:节点的镜像文件系统,将容器和镜像存储到单独的数据盘(可选的)。如果没有配置镜像文件系统但使用了 imagefs 相关驱逐信号则会复用根文件系统,例如前面示例驱逐策略配置同时定义了 nodefs.available<10% 和 imagefs.available<15% ,当节点本身没有配置将容器目录存放在独立数据盘而使用根文件系统空间时,则当磁盘使用率到达 85% 时就会触发驱逐,而不是 nodefs.available 定义的使用率到达 90% 再驱逐。
3.2、驱逐条件
你可以为 k8s 节点压力驱逐自定义驱逐条件,分为软驱逐和硬驱逐条件。格式为:[eviction-signal][operator][quantity] 。其中:
-
eviction-signal 是要使用的驱逐信号。
-
operator 是要使用的关系运算符, 比如 <(小于)。
-
quantity 是驱逐条件的阈值,例如 1Gi。你可以使用明确值或百分比(%)。
软驱逐配置参数示例(可以看到相比硬驱逐多了两个选项)
--eviction-soft=nodefs.available<45%,nodefs.inodesFree<45%
--eviction-soft-grace-period=nodefs.available=1m30s
--eviction-max-pod-grace-period=100
硬驱逐配置参数示例
--eviction-soft=nodefs.available<45%,nodefs.inodesFree<45%
kubelet 具有以下默认硬驱逐条件:
-
memory.available<100Mi
-
nodefs.available<10%
-
imagefs.available<15%
-
nodefs.inodesFree<5%(Linux 节点)
3.3、检测间隔
kubectl 根据 --housekeeping-interval 选项的值来设置检测间隔(默认为 10 秒)。
四、kubelet 如何选择要驱逐哪些 pod
kubelet 使用以下参数来确定 Pod 驱逐顺序:
-
Pod 的资源使用是否超过其请求
-
Pod 优先级
-
Pod 相对于请求的资源使用情况
因此,kubelet 按以下顺序排列和驱逐 Pod:
- 首先考虑资源使用量超过其请求的 BestEffort 或 Burstable Pod。这些 Pod 会根据它们的优先级以及它们的资源使用级别超过其请求的程度被逐出。
-
资源使用量少于请求量的 Guaranteed Pod 和 Burstable Pod 根据其优先级被最后驱逐。
并且kubelet 还根据节点是否具有专用的 imagefs 文件系统对 Pod 进行不同的排序:有 imagefs
-
如果 nodefs 触发驱逐, kubelet 会根据 nodefs 使用情况(本地卷 + 所有容器的日志)对 Pod 进行排序。
-
如果 imagefs 触发驱逐,kubelet 会根据所有容器的可写层使用情况对 Pod 进行排序。
没有 imagefs
-
如果 nodefs 触发驱逐, kubelet 会根据磁盘总用量(本地卷 + 日志和所有容器的可写层)对 Pod 进行排序。
五、触发驱逐后节点状态更新
kubelet 在满足驱逐触发条件后,会更新对应的节点状态以反馈自身处于压力之下。根据下表将驱逐信号映射为节点状态:
控制平面还会将这些节点状态映射为其污点。
kubelet 根据配置的 --node-status-update-frequency 更新节点状态,默认为 10s。
在节点触发驱逐后我们也可以使用 kubectl describe pod <pod_name> 命令查看相关 pod 的详细信息:
Status: Failed
Reason: Evicted
Message: Pod The node had condition: [DiskPressure].
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Evicted 42s kubelet The node had condition: [DiskPressure].
六、节点压力驱逐默认配置带来的影响
由于硬驱逐条件存在默认值,所以哪怕我们没有显式配置相关参数,如果存在 k8s 节点资源使用高的情况下,也会面临正在运行的 pod 被驱逐直接终止的情况。为了避免对业务造成影响,所以我们要明确需要关注哪些资源的使用情况避免 pod 被驱逐。
根据上面提到的k8s硬驱逐的默认配置,可以得出如下:
-
节点可用内存低于100MB。
-
节点的根文件系统空间(磁盘)使用率大于 90% 。
-
节点的容器镜像文件系统空间使用率大于85%(如果没有imagefs则节点的根文件系统空间使用率不能大于85%)。
- 节点的根文件系统inode使用率大于95%。
本文整理自 k8s 官方文档:
https://v1-25.docs.kubernetes.io/docs/concepts/scheduling-eviction/node-pressure-eviction/
以上内容仅代表个人观点,不足之处还请指正交流。