每天都有成千上万的 Pod 从节点中被驱逐。它们“无家可归、困惑不已”,不得不放弃之前的生活方式。其中一些甚至变成无节点状态。
在 Kubernetes 中 Pod 被驱逐意味着什么?我们常常能看到 Pod 因为资源不足被终止。但为什么会发生这种情况呢?
驱逐(Eviction) 是指终止已分配到某个节点的 Pod。Kubernetes 中最常见的情况是抢占,是指为了将新的 Pod 调度到资源有限的节点上,需要终止另一个 Pod 以释放资源。
此外,Kubernetes 会不断检查资源在必要时驱逐 Pod,这个过程称为节点压力驱逐。
Pod 被驱逐的原因:抢占和节点压力
Kubernetes 中 Pod 驱逐现象发生的最主要原因如下:
抢占驱逐
抢占(Preemption) 是指如果需要调度一个新的 Pod,但没有合适的节点有足够的资源,
kube-scheduler
就会检查是否可以通过驱逐(终止)一些优先级较低的 Pod,来确保新的 Pod 可以调度到该节点。
首先,我们来理解下 Kubernetes 调度的工作原理。
Kubernetes 调度是指 Pod 被分配到节点的过程。
默认情况下,一个名为
kube-scheduler
的 Kubernetes 实体负责调度,它在控制面中运行。Pod 在找到合适的节点前会一直处于 Pending 状态。
将 Pod 分配到节点的过程包含 过滤和 评分两个步骤:
在过滤步骤中,
kube-scheduler 将选出所有适合放置当前 Pod 的节点。该步骤会考虑污点、容忍度等特性。过滤完成后,将会列出适合该 Pod 的节点列表。
评分
在评分步骤中,
kube-scheduler 将使用上一步筛选出的候选节点列表,并为每个节点打分。这样就可以按照合适程度对候选节点进行排序。如果存在两个节点得分相同,
kube-scheduler 会随机排序。
但是,如果没有合适的节点可以运行 Pod,该怎么办?这时,Kubernetes 就会开始 抢占,试图 驱逐优先级较低的 Pod,并将此节点分配给新 Pod。
但如何防止特定 Pod 在抢占过程中被驱逐?可能有一些重要的 Pod 不应被终止。
这正是 Kubernetes 提供 优先级类的原因。
Pod 优先级是一种 Kubernetes 对象,允许我们将 优先级值映射到特定的 Pod。系统会将更重视优先级较高的 Pod,该 Pod 被驱逐的可能性更低。
您可以使用以下命令查询当前 Pod 的优先级:
kubectl get priorityclasses
kubectl get pc
NAME VALUE GLOBAL-DEFAULT AGE
system-cluster-critical 2000000000
false 2d
system-node-critical 2000001000
false 2dCode language: Shell Session (shell)
这里我们用 Lovenstein 的 Berry Club 漫画做个演示:
以下三个 Pod 分别代表蓝莓、树莓和草莓:
NAME READY STATUS RESTARTS AGE
blueberry 1/1 Running 0 4h41m
raspberry 1/1 Running 0 58m
strawberry 1/1 Running 0 5h22m
Code language: JavaScript (javascript)
且存在两个优先级类:trueberry 和 falseberry。前者的值更高,表示更高的优先级。
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: trueberry
value: 1000000
globalDefault:
false
description:
"This fruit is a true berry"
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: falseberry
value: 5000
globalDefault:
false
description:
"This fruit is a false berry"Code language: Shell Session (shell)
这意味着抢占发生时,树莓和草莓更可能被驱逐,给更高优先级的 Pod 腾出空间。
可在 Pod 定义中添加以下内容来分配优先级:
priorityClassName: trueberryCode language: Shell Session (shell)
现在我们尝试添加三个新水果,但有一个小的改动。新添加的水果都设置了
trueberry,具有更高优先级。
由于这三个新水果对内存或 CPU 的需求超出了节点的能力,
kubelet 会驱逐所有优先级低于新水果的 Pod。由于蓝莓优先级更高,它仍保持运行状态。
NAME READY STATUS RESTARTS AGE
banana 0/1 ContainerCreating 0 2s
blueberry 1/1 Running 0 4h42m
raspberry 0/1 Terminating 0 59m
strawberry 0/1 Terminating 0 5h23m
tomato 0/1 ContainerCreating 0 2s
watermelon 0/1 ContainerCreating 0 2sCode language: Shell Session (shell)
这是最终的 Pod 运行结果:
NAME READY STATUS RESTARTS AGE
banana 1/1 Running 0 3s
blueberry 1/1 Running 0 4h43m
tomato 1/1 Running 0 3s
watermelon 1/1 Running 0 3sCode language: Shell Session (shell)
对于 Berry Club 来说,这真是艰难的时期...
节点压力驱逐
除了抢占外,Kubernetes 还会不断检查节点资源,如磁盘压力、CPU 或内存溢出(OOM)。
如果节点上的某种资源(如
CPU 或
内存)的使用
达到一定阈值,
kubelet 就会开始驱逐 Pod 以
释放资源。系统也会根据服务质量(QoS)确定驱逐顺序。
在 Kubernetes 中,如果 Pod 被赋予了以下三种 QoS 之一,这意味着它们在资源短缺情况下被驱逐的可能性等级,以下按照被驱逐的可能性从低到高排序:
如何将这些 QoS 分配给 Pod 取决于 CPU 和 内存的 限制和请求值。
保证型
如果满足以下条件,Pod 将被赋予 保证型 QoS:
在正常情况下,保证型 Pod 不会被驱逐。
如果满足以下条件,Pod 将被赋予 突发型 QoS:
突发型 Pod 可能会被驱逐,但相较于比尽力就好型,其被驱逐的可能性更低。
如果满足以下条件,Pod 将被赋予 尽力就好型 QoS:
在节点压力发生时,尽力就好型 Pod 最有可能被驱逐。
重要提示:限制值和请求值中可能还有其他可用资源,如 ephemeral-storage,但它们不用于 QoS 类计算。
如前所述,节点压力驱逐会将 QoS 考虑在内。以下是内部发生的过程:
kubelet 按以下顺序对要驱逐的 Pod 进行排名:
尽力就好型 Pod 或使用量超过请求值的
突发型 Pod突发型 Pod 或
保证型 PodKubernetes 将尝试先驱逐第 1 组中的 Pod,然后再驱逐第 2 组。
可以关注以下要点:
保证型 Pod 通常不会被驱逐:
kubelet 不会为了调度其他 Pod 而驱逐保证型 Pod。但如果某些系统服务需要更多资源,
kubelet 将在必要时终止
保证型 Pod,并始终给予最低优先级。
其他类型的驱逐
本节重点关注抢占和节点压力驱逐,但 Pod 也可能会以其他方式被驱逐。例如:
您可以使用 Kubernetes 的驱逐 API 请求对某个节点上的 Pod 进行即时驱逐。
借助 Kubernetes 污点和容忍,您可以指定如何将 Pod 分配到节点。但是,如果您对一个现有节点应用了
NoExecute 污点,所有未设置容忍该污点 Pod 都将立即被驱逐。
有时节点可能会无法使用,或者您不想再继续使用这些节点。
kubectl cordon 命令可以防止新的 Pod 被调度到该节点,但您也可以一次性清空该节点上的所有当前 Pod。执行
kubectl drain nodename 后,该节点上的所有 Pod 都将被驱逐,并遵守其优雅终止期。
使用 Prometheus 监控 Kubernetes Pod 驱逐监 控
您可以在云解决方案中使用 Prometheus 轻松监控 Pod 驱逐情况:
kube_pod_status_reason{reason=
"Evicted"} > 0Code language: JavaScript (javascript)
执行这一命令后,将显示集群中所有被驱逐的 Pod。您还可以将其与
kube_pod_status_phase{phase="Failed"} 配对,可以在 Pod 因失败而被驱逐时收到告警。
总结
驱逐只是 Kubernetes 的一个功能,可让您控制有限的资源,即 Pod 将使用的节点资源。
在 抢占期间,Kubernetes 会尝试通过驱逐优先级较低的 Pod 来释放资源,以调度新的 Pod。您可以使用优先级类驱逐,控制哪些 Pod 在抢占后更有可能继续运行,因为设置特定优先级的 Pod 被驱逐的可能性更小。
在执行过程中,Kubernetes 也将检查 节点压力,并在需要时驱逐 Pod。您也可以在节点压力情况下,使用 QoS 类驱逐,控制哪些 Pod 更可能被驱逐。
内存和 CPU 是节点中重要的资源,您需要给 Pod、容器和节点配置恰当的使用量。如果您相应地管理这些资源,不仅可以节省成本,还可以确保无论发生什么情况,重要的流程都能保持运行。
原文链接:
https://sysdig.com/blog/kubernetes-pod-evicted/
End
KubeBlocks 已发布 v0.8.0!KubeBlocks v0.8.0 推出了 Component API,让数据库引擎的组装变得更加简单。Addon 机制也有了重大改进,数据库引擎的 helm chart 从 KubeBlocks repo 中拆分出去,从此数据库引擎或者版本的变动已与 KubeBlocks 发版解绑。v0.8.0 还支持多版本的数据库引擎定义。Pika、ClickHouse、OceanBase、MySQL、PostgreSQL、Redis 等均有功能更新,快来试试看!
小猿姐诚邀各位体验 KubeBlocks,也欢迎您成为产品的使用者和项目的贡献者。跟我们一起构建云原生数据基础设施吧!
💻 官网:
🌟 GitHub: https://github.com/apecloud/kubeblocks
🚀 Get started: https://kubeblocks.io/docs/preview/user_docs/try-out-on-playground/try-kubeblocks-on-your-laptop
关注小猿姐,一起学习更多云原生技术干货。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70035809/viewspace-3020111/ ,如需转载,请注明出处,否则将追究法律责任。