Kubernetes Pods被驱逐是什么意思?它们被终止了,通常是由于没有足够的资源,但是为什么会发生这种情况呢?
驱逐是一个过程,分配给一个节点的Pod被要求终止。Kubernetes中最常见的情况之一是抢占,为了在资源有限的节点上安排一个新的Pod,通常需要终止另外一个Pod。
另外,Kubernetes会不断检查资源使用情况,当节点压力过大的时候,会触发节点压力驱逐。
每天,数以千计的Pod被驱逐出他们的家园。搁浅和迷茫,他们不得不放弃以前的生活方式。他们中的一些人甚至会无家可归。当前的社会,对CPU和内存的要求会越来越高。
本篇文章将从以下几个方面来展开介绍:
Kubernetes中发生Pod驱逐的原因有几个,最重要的原因是:
抢占的过程如下:如果一个新的Pod需要被调度,但没有任何合适的节点有足够的资源,那么kube-scheduler将检查是否通过驱逐(终止)一些优先级较低的Pod,用来保障新的Pod可以调度。
让我们先了解一下Kubernetes调度是如何工作的。
Kubernetes调度是将Pod分配给节点的过程。
默认情况下,有一个负责调度的Kubernetes实体,称为kube-scheduler,它将在控制平面上运行。Pod将在Pending状态下开始,直到找到一个匹配的节点。
将一个Pod分配给一个节点的过程遵循这个顺序。
在预选过程中,kube-scheduler将选择当前Pod可能被放置的所有节点。这里将考虑到污点和容忍度等特征。一旦完成,它将有一个适合该Pod的节点列表。
在打分过程中,kube-scheduler将从上一步得到的列表中,给每个节点分配一个分数。这样一来,候选节点就会从最合适到最不合适排序。如果两个节点有相同的分数,kube-scheduler会将它们随机排序。
但是,如果没有合适的节点让Pod运行,会发生什么?在这种情况下,Kubernetes将启动抢占程序,试图驱逐低优先级的Pod,以便分配新的Pod。
怎样才能防止某个特定的Pod在抢占过程中被驱逐?有时候,一个特定的Pod对你来说是至关重要的,不应该被终止。
这就是为什么Kubernetes具有Priority Class。
Priority Class是一个Kubernetes对象,允许我们将数字优先级值映射到特定的Pod。那些数值较高的被归类为更重要,不太可能被驱逐。
你可以通过以下方式查询当前的Priority Class。
kubectl get priorityclasses
kubectl get pcNAME VALUE GLOBAL-DEFAULT AGE
system-cluster-critical 2000000000 false 2d
system-node-critical 2000001000 false 2d
这里有三个Pod:blueberry, raspberry 和 strawberry。
NAME READY STATUS RESTARTS AGE
blueberry 1/1 Running 0 4h41m
raspberry 1/1 Running 0 58m
strawberry 1/1 Running 0 5h22m
还有两个Priority Class:trueberry和falseberry。其中trueberry拥有比较高的优先级。
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"
这意味着在发生抢占的情况下,raspberry和strawberry更有可能被驱逐,以便为更高优先级的Pod腾出空间。
然后通过在Pod定义中加入优先级类别,将其分配给Pod。
priorityClassName: trueberry
现在让我们试着再增加三种水果:所有的新水果将包含更高的优先级类,称为trueberry。
由于这三个新的水果对内存或CPU的要求是节点无法满足的,kubelet会驱逐所有比新水果优先级低的Pod。Blueberry保持运行,因为它有更高的优先级。
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 2s
最终结果如下:
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 3s
除了抢占之外,Kubernetes还不断检查节点资源,如磁盘压力、CPU或内存不足(OOM)。
如果节点的资源(如CPU或内存)消耗达到一定的阈值,Kubelet将开始驱逐Pod,以释放资源。服务质量(QoS)将被纳入考虑范围,以确定驱逐顺序。
在Kubernetes中,Pod被赋予三种QoS类别之一,这将定义它们在缺乏资源的情况下被驱逐的可能性。这三种QoS分别是:
这些QoS类别是如何分配给Pod的?这是基于对CPU和内存的限制和请求。
如果一个Pod被分配了一个Guaranteed的QoS等级,它们的特征如下:
一个有保证的Pod在正常情况下不会被驱逐以分配给节点中的另一个Pod。
如果一个Pod的QoS等级为Burstable,那么它将被分配到一个QoS等级。
一个Burstable Pod可以被驱逐,但比下一个类别的可能性小。
一个Pod将被分配一个BestEffort的QoS类别,它们将:
BestEffort Pod在节点中发生节点压力过程的情况下具有最高的驱逐机会。
❝重要的是:在限制和请求中可能有其他可用的资源,如短暂的存储,但它们不用于QoS类的计算。
如前所述,QoS类将被纳入节点压力驱逐的考虑范围。以下是内部发生的过程。
kubelet按照以下顺序排列要被驱逐的Pod。
Kubernetes将尝试在第二组之前驱逐第一组的Pod。
从上述内容中得到的一些启示。
本文主要介绍抢占和节点压力驱逐,但Pod也可以通过其他方式被驱逐。例子包括。
你可以通过使用Kubernetes Eviction API【1】请求对你的一个节点中的Pod进行按需驱逐。
通过Kubernetes污点和容忍度,可以指导你的Pod应该如何分配给Node。但是,如果你将NoExecute污点应用于现有的Node,所有不容忍它的Pod将被立即驱逐。
有些时候,节点变得无法使用,或者你不想再在上面工作。命令kubectl cordon可以防止新的Pod被安排在它上面,但也有可能一次性完全清空所有当前Pod。如果你运行kubectl drain nodename,该节点中的所有Pod将被驱逐,尊重其优雅的终止期。
在你的云解决方案中,你可以使用Prometheus来轻松监控Pod驱逐的做法。
kube_pod_status_reason{reason="Evicted"} > 0
这将显示你的集群中所有被驱逐的Pod。你也可以将其与kube_pod_status_phase{phase="Failed"}配对,以提醒那些在Pod发生故障后被驱逐的人。
如果你想深入了解,请查看以下关于Prometheus中监控资源的文章。
如何合理调整Kubernetes的资源限制【1】
正如你所看到的,驱逐只是Kubernetes的另一个功能,它允许你控制有限的资源:在这种情况下,Pod将使用的节点。
在抢占期间,Kubernetes将试图通过驱逐优先级较低的Pod来释放资源,以安排一个新的Pod。通过优先级类,你可以控制哪些Pod更有可能在抢占后继续运行,因为它们被驱逐的可能性较小。
在执行过程中,Kubernetes将检查节点压力,并在需要时驱逐Pod。通过QoS类,你可以控制哪些Pod在节点压力的情况下更有可能被驱逐。
内存和CPU是节点中的重要资源,你需要配置你的Pod、容器和节点来使用它们的正确数量。如果你对这些资源进行相应的管理,不仅可以节省成本,而且还可以确保重要的进程无论如何都能继续运行。
【2】
https://sysdig.com/blog/kubernetes-resource-limits/
【3】
https://sysdig.com/blog/kubernetes-capacity-planning/
原文:https://sysdig.com/blog/kubernetes-pod-evicted/
作者:JAVIER MARTÍNEZ
《Docker中Image、Container与Volume的迁移》
免责声明:本文内容来源于网络,所载内容仅供参考。转载仅为学习和交流之目的,如无意中侵犯您的合法权益,请及时联系Docker中文社区!