2

细说Kubernetes Pod的驱逐

 1 year ago
source link: https://www.51cto.com/article/746138.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

细说Kubernetes Pod的驱逐

作者:乔克 2023-02-09 16:47:34
在抢占期间,Kubernetes将试图通过驱逐优先级较低的Pod来释放资源,以安排一个新的Pod。通过优先级类,你可以控制哪些Pod更有可能在抢占后继续运行,因为它们被驱逐的可能性较小。

Kubernetes Pods被驱逐是什么意思?它们被终止了,通常是由于没有足够的资源,但是为什么会发生这种情况呢?

驱逐是一个过程,分配给一个节点的Pod被要求终止。Kubernetes中最常见的情况之一是抢占,为了在资源有限的节点上安排一个新的Pod,通常需要终止另外一个Pod。

另外,Kubernetes会不断检查资源使用情况,当节点压力过大的时候,会触发节点压力驱逐。

每天,数以千计的Pod被驱逐出他们的家园。搁浅和迷茫,他们不得不放弃以前的生活方式。他们中的一些人甚至会无家可归。当前的社会,对CPU和内存的要求会越来越高。

本篇文章将从以下几个方面来展开介绍:

Pod被驱逐的原因:抢占和节点压力

抢占式驱逐

Pod优先级类

节点压力驱逐

服务质量类

其他类型的驱逐

Prometheus中的Kubernetes Pod驱逐监控

Pods被驱逐的原因:抢占和节点压力

Kubernetes中发生Pod驱逐的原因有几个,最重要的原因是:

节点压力驱逐

抢占的过程如下:如果一个新的Pod需要被调度,但没有任何合适的节点有足够的资源,那么kube-scheduler将检查是否通过驱逐(终止)一些优先级较低的Pod,用来保障新的Pod可以调度。

让我们先了解一下Kubernetes调度是如何工作的。

Pod调度

Kubernetes调度是将Pod分配给节点的过程。

默认情况下,有一个负责调度的Kubernetes实体,称为kube-scheduler,它将在控制平面上运行。Pod将在Pending状态下开始,直到找到一个匹配的节点。

将一个Pod分配给一个节点的过程遵循这个顺序。

在预选过程中,kube-scheduler将选择当前Pod可能被放置的所有节点。这里将考虑到污点和容忍度等特征。一旦完成,它将有一个适合该Pod的节点列表。

在打分过程中,kube-scheduler将从上一步得到的列表中,给每个节点分配一个分数。这样一来,候选节点就会从最合适到最不合适排序。如果两个节点有相同的分数,kube-scheduler会将它们随机排序。

图片

image.png

但是,如果没有合适的节点让Pod运行,会发生什么?在这种情况下,Kubernetes将启动抢占程序,试图驱逐低优先级的Pod,以便分配新的Pod。

Pod Priority Class

怎样才能防止某个特定的Pod在抢占过程中被驱逐?有时候,一个特定的Pod对你来说是至关重要的,不应该被终止。

这就是为什么Kubernetes具有Priority Class。

Priority Class是一个Kubernetes对象,允许我们将数字优先级值映射到特定的Pod。那些数值较高的被归类为更重要,不太可能被驱逐。

你可以通过以下方式查询当前的Priority Class。

kubectl get priorityclasses
kubectl get pc

NAME                      VALUE        GLOBAL-DEFAULT   AGE
system-cluster-critical   2000000000   false            2d
system-node-critical      2000001000   false            2d

测试Priority Class

这里有三个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"
  • blueberry将使用trueberry
  • raspberry和strawberry将使用ffalseberry

这意味着在发生抢占的情况下,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)将被纳入考虑范围,以确定驱逐顺序。

服务质量QoS

在Kubernetes中,Pod被赋予三种QoS类别之一,这将定义它们在缺乏资源的情况下被驱逐的可能性。这三种QoS分别是:

  • Guaranteed
  • Burstable
  • BestEffort

这些QoS类别是如何分配给Pod的?这是基于对CPU和内存的限制和请求。

  • limits:一个容器可以使用的资源的最大数量。
  • requests:容器运行所需的最小资源量。
图片

Guaranteed

如果一个Pod被分配了一个Guaranteed的QoS等级,它们的特征如下:

  • Pod中的所有容器都为CPU和内存设置了限制和请求。
  • 在Pod中的所有容器都有相同的CPU限制和CPU请求的值。
  • Pod中的所有容器都有相同的内存限制和内存请求值。

一个有保证的Pod在正常情况下不会被驱逐以分配给节点中的另一个Pod。

Burstable

如果一个Pod的QoS等级为Burstable,那么它将被分配到一个QoS等级。

  • 它没有担保的QoS等级。
  • 为Pod中的一个容器设置了限制或请求。

一个Burstable Pod可以被驱逐,但比下一个类别的可能性小。

BestEffort

一个Pod将被分配一个BestEffort的QoS类别,它们将:

  • 没有为Pod中的任何容器设置限制和请求。

BestEffort Pod在节点中发生节点压力过程的情况下具有最高的驱逐机会。

重要的是:在限制和请求中可能有其他可用的资源,如短暂的存储,但它们不用于QoS类的计算。

图片

如前所述,QoS类将被纳入节点压力驱逐的考虑范围。以下是内部发生的过程。

kubelet按照以下顺序排列要被驱逐的Pod。

  • 使用量超过请求的BestEffort Pods或Burstable Pods
  • 使用量低于请求的Burstable Pods或Guaranteed Pods

Kubernetes将尝试在第二组之前驱逐第一组的Pod。

从上述内容中得到的一些启示。

  • 如果在你的容器中添加了非常低的请求,他们的Pod可能会被分配到组1,这意味着它更有可能被驱逐。
  • 你无法知道哪个特定的Pod会被驱逐,只是Kubernetes会尝试在第2组之前驱逐第1组的Pod。
  • 有保证的Pod通常不会被驱逐:Kubelet不会为了安排其他Pod而驱逐它们。但是,如果一些系统服务需要更多的资源,kubelet将在必要时终止有保证的Pod,并且总是以最低的优先级。

其他类型的驱逐

本文主要介绍抢占和节点压力驱逐,但Pod也可以通过其他方式被驱逐。例子包括。

API发起的驱逐

你可以通过使用Kubernetes Eviction API【1】请求对你的一个节点中的Pod进行按需驱逐。

基于污点的驱逐

通过Kubernetes污点和容忍度,可以指导你的Pod应该如何分配给Node。但是,如果你将NoExecute污点应用于现有的Node,所有不容忍它的Pod将被立即驱逐。

有些时候,节点变得无法使用,或者你不想再在上面工作。命令kubectl cordon可以防止新的Pod被安排在它上面,但也有可能一次性完全清空所有当前Pod。如果你运行kubectl drain nodename,该节点中的所有Pod将被驱逐,尊重其优雅的终止期。

Kubernetes Pod驱逐监控

在你的云解决方案中,你可以使用Prometheus来轻松监控Pod驱逐的做法。

kube_pod_status_reason{reasnotallow="Evicted"} > 0
图片

这将显示你的集群中所有被驱逐的Pod。你也可以将其与kube_pod_status_phase{phase="Failed"}配对,以提醒那些在Pod发生故障后被驱逐的人。

如果你想深入了解,请查看以下关于Prometheus中监控资源的文章。

  • 如何合理调整Kubernetes的资源限制【1】
  • Kubernetes容量规划:如何合理安排你的集群的请求【2】

正如你所看到的,驱逐只是Kubernetes的另一个功能,它允许你控制有限的资源:在这种情况下,Pod将使用的节点。

在抢占期间,Kubernetes将试图通过驱逐优先级较低的Pod来释放资源,以安排一个新的Pod。通过优先级类,你可以控制哪些Pod更有可能在抢占后继续运行,因为它们被驱逐的可能性较小。

在执行过程中,Kubernetes将检查节点压力,并在需要时驱逐Pod。通过QoS类,你可以控制哪些Pod在节点压力的情况下更有可能被驱逐。

内存和CPU是节点中的重要资源,你需要配置你的Pod、容器和节点来使用它们的正确数量。如果你对这些资源进行相应的管理,不仅可以节省成本,而且还可以确保重要的进程无论如何都能继续运行。

​文档

【1】https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#create-eviction-pod-v1-core

【1】https://sysdig.com/blog/kubernetes-resource-limits/

【2】https://sysdig.com/blog/kubernetes-capacity-planning/


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK