各位亲爱的Kubernetes爱好者们,大家好!我是你们的老朋友,人称“K8s百晓生”的程序猿老王。今天咱们要聊点高级货,聊聊K8s调度器里的“宫斗剧”——优先级与抢占调度。
想象一下,你是一位皇帝,手下有一群妃子(Pod),每个妃子都想得到你的宠幸(资源)。有的妃子出身高贵(优先级高),有的妃子默默无闻(优先级低)。如果皇帝的寝宫(节点)满了,谁能入住,谁要让位?这就是我们今天的主题:优先级与抢占调度。
一、为什么需要优先级与抢占?
在K8s的世界里,资源是有限的。节点上的CPU、内存、网络带宽等,就像皇宫里的床位,僧多粥少啊!没有优先级,所有Pod一视同仁,那就会出现以下问题:
- 重要应用得不到保障: 想象一下,核心数据库和临时测试任务争夺资源,结果测试任务占满了CPU,数据库崩溃了,这还得了?
- 资源利用率低下: 如果所有Pod都平等竞争,可能会出现某些节点负载过高,而另一些节点却闲置的情况。
- 难以应对紧急情况: 比如,突发流量导致某个服务需要紧急扩容,如果没有优先级,新Pod可能无法及时启动,导致服务雪崩。
所以,我们需要一种机制,能够区分Pod的重要性,让重要的Pod优先获得资源,保障核心应用的稳定运行。这就是优先级与抢占机制的意义所在。
二、什么是优先级(Priority)?
优先级,顾名思义,就是给Pod贴上一个“重要性”的标签。这个标签决定了Pod在调度时的地位。优先级越高,Pod就越容易被调度到节点上。
在K8s中,优先级是通过PriorityClass
对象来定义的。PriorityClass
包含两个关键字段:
value
: 一个整数值,代表优先级的大小。数值越大,优先级越高。globalDefault
: 一个布尔值,表示是否将该优先级作为集群的默认优先级。
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: critical-priority
value: 1000000
globalDefault: false
description: "This priority class should be used for critical pods only."
这个例子定义了一个名为critical-priority
的PriorityClass
,其优先级值为1000000,并且不是全局默认优先级。
定义好PriorityClass
后,就可以在Pod的spec
中指定priorityClassName
来使用它了。
apiVersion: v1
kind: Pod
metadata:
name: critical-pod
labels:
app: critical-app
spec:
containers:
- name: critical-container
image: nginx
priorityClassName: critical-priority
这个例子中,critical-pod
使用了critical-priority
这个PriorityClass
,因此具有很高的优先级。
优先级就像古代官场上的品级制度,一品大员自然比九品芝麻官更有话语权。 👑
三、什么是抢占(Preemption)?
有了优先级,还不够。如果所有节点都已经被低优先级的Pod占满了,高优先级的Pod怎么办?难道只能眼巴巴地等着?
这时候,抢占就派上用场了。抢占是指,当调度器找不到合适的节点来调度高优先级的Pod时,它可以“驱逐”一个或多个低优先级的Pod,从而释放资源,让高优先级的Pod得以运行。
抢占就像古代战争中的“清场”,为了迎接重要人物,先把无关人等赶走。 ⚔️
抢占的流程大概是这样的:
- 调度器发现一个高优先级的Pod无法被调度。
- 调度器开始评估哪些节点上的Pod可以被抢占。
- 调度器选择一个或多个低优先级的Pod进行驱逐。
- 被驱逐的Pod进入
Pending
状态,等待重新调度。 - 高优先级的Pod被调度到释放了资源的节点上。
四、抢占的注意事项和配置
抢占不是万能的,它也有一些限制和需要注意的地方:
preemptionPolicy
: PodSpec 中可以设置preemptionPolicy
来控制抢占行为。可选值为PreemptLowerPriority
(默认) 和Never
。设置为Never
时,该 Pod 永远不会抢占其他 Pod,只能等待资源。terminationGracePeriodSeconds
: 被抢占的Pod会收到一个SIGTERM
信号,然后优雅地关闭。terminationGracePeriodSeconds
定义了Pod关闭的宽限期。如果Pod在宽限期内没有关闭,K8s会强制杀死它。priorityClassName
的选择: 要谨慎选择priorityClassName
。如果过度使用高优先级,可能会导致低优先级的Pod永远无法被调度。- PodDisruptionBudget (PDB): PDB可以保护某些Pod不被意外驱逐。PDB可以定义允许同时被驱逐的Pod数量。
- 节点亲和性和反亲和性: 节点亲和性和反亲和性会影响抢占的决策。调度器会尽量避免驱逐那些与高优先级Pod有亲和性关系的Pod。
- 容忍度(Tolerations)和污点(Taints): 如果节点上设置了污点,只有具有相应容忍度的Pod才能被调度到该节点上。抢占也会受到污点和容忍度的影响。
五、抢占的配置示例
假设我们有一个节点,上面运行着一个低优先级的Pod和一个中等优先级的Pod。现在,我们想调度一个高优先级的Pod,并且允许它抢占低优先级的Pod。
首先,定义三个PriorityClass
:
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: low-priority
value: 100
globalDefault: false
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: medium-priority
value: 500
globalDefault: false
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000
globalDefault: false
然后,创建一个低优先级的Pod:
apiVersion: v1
kind: Pod
metadata:
name: low-priority-pod
spec:
containers:
- name: low-priority-container
image: nginx
priorityClassName: low-priority
创建一个中等优先级的Pod:
apiVersion: v1
kind: Pod
metadata:
name: medium-priority-pod
spec:
containers:
- name: medium-priority-container
image: nginx
priorityClassName: medium-priority
最后,创建一个高优先级的Pod:
apiVersion: v1
kind: Pod
metadata:
name: high-priority-pod
spec:
containers:
- name: high-priority-container
image: nginx
priorityClassName: high-priority
当你创建high-priority-pod
时,调度器会发现没有足够的资源来调度它。然后,调度器会评估哪些Pod可以被抢占。由于low-priority-pod
的优先级最低,它会被驱逐,high-priority-pod
会被调度到该节点上。
六、如何监控和调试抢占?
抢占是一个复杂的调度过程,需要进行监控和调试,以便及时发现和解决问题。
- 查看Pod的事件: 可以使用
kubectl describe pod <pod-name>
命令查看Pod的事件,了解Pod是否被抢占,以及抢占的原因。 - 查看调度器的日志: 调度器的日志包含了详细的调度信息,可以帮助你了解抢占的决策过程。
- 使用Metrics Server和Prometheus: 可以使用Metrics Server和Prometheus等工具来监控集群的资源利用率和Pod的调度情况。
- 模拟抢占场景: 可以使用
kubectl drain
命令模拟节点故障,然后观察高优先级Pod是否能够成功抢占资源。
七、优先级与抢占的“葵花宝典”
为了帮助大家更好地理解和应用优先级与抢占机制,我总结了一份“葵花宝典”,供大家参考:
项目 | 描述 | 注意事项 |
---|---|---|
PriorityClass |
定义Pod的优先级。 | 优先级值越大,优先级越高。 |
priorityClassName |
在Pod的spec 中指定PriorityClass 。 |
确保PriorityClass 已经存在。 |
抢占(Preemption) | 当高优先级的Pod无法被调度时,可以驱逐低优先级的Pod来释放资源。 | 抢占可能会导致服务中断,需要谨慎使用。 |
preemptionPolicy |
控制抢占行为。PreemptLowerPriority (默认) 允许抢占, Never 禁止抢占。 |
根据实际需求选择合适的策略。 |
PDB | 保护某些Pod不被意外驱逐。 | PDB会限制抢占行为,需要合理配置。 |
监控与调试 | 通过查看Pod事件、调度器日志、Metrics Server和Prometheus等工具来监控和调试抢占。 | 及时发现和解决问题。 |
八、总结
优先级与抢占是K8s调度器中非常重要的机制,它们可以帮助我们更好地管理和利用集群资源,保障核心应用的稳定运行。
希望今天的讲解能够帮助大家更好地理解和应用优先级与抢占机制。记住,在K8s的世界里,掌握了优先级与抢占,就掌握了调度的“生杀大权”!
最后,祝大家在K8s的世界里玩得开心!😊