Kubernetes:默认调度器的优先级与Pod 抢占机制

简介: Kubernetes:默认调度器的优先级与Pod 抢占机制

在本篇文章中,讲解一下 Kubernetes 调度器里的另一个重要机制,即:优先级(Priority )和抢占(Preemption)机制


首先需要明确的是,优先级和抢占机制,解决的是 Pod 调度失败时该怎么办的问题

正常情况下,当一个 Pod 调度失败后,它就会被暂时“搁置”起来,直到 Pod 被更新,或者集群状态发生变化,调度器才会对这个 Pod 进行重新调度。

但在有时候,我们希望的是这样一个场景。当一个高优先级的 Pod 调度失败后,该 Pod 并不会被“搁置”,而是会“挤走”某个 Node 上的一些低优先级的 Pod 。这样就可以保证这个高优先级 Pod 的调度成功。这个特性,其实也是一直以来就存在于 Borg 以及 Mesos 等项目里的一个基本功能。


而在 Kubernetes 里,优先级和抢占机制是在 1.10 版本后才逐步可用的。要使用这个机制,你首先需要在 Kubernetes 里提交一个 PriorityClass 的定义,如下所示:

apiVersion: scheduling.k8s.io/v1beta1
kind: PriorityClass
metadata:
  name: high-priority
value: 1000000
globalDefault: false
description: "This priority class should be used for high priority service pods only."


上面这个 YAML 文件,定义的是一个名叫 high-priority 的 PriorityClass,其中 value 的值是 1000000 (一百万)。


Kubernetes 规定,优先级是一个 32 bit 的整数,最大值不超过 1000000000(10 亿,1 billion),并且值越大代表优先级越高。而超出 10 亿的值,其实是被 Kubernetes 保留下来分配给系统 Pod 使用的。显然,这样做的目的,就是保证系统 Pod 不会被用户抢占掉。


而一旦上述 YAML 文件里的 globalDefault 被设置为 true 的话,那就意味着这个 PriorityClass 的值会成为系统的默认值。而如果这个值是 false,就表示我们只希望声明使用该 PriorityClass 的 Pod 拥有值为 1000000 的优先级,而对于没有声明 PriorityClass 的 Pod 来说,它们的优先级就是 0。


在创建了 PriorityClass 对象之后,Pod 就可以声明使用它了,如下所示:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  priorityClassName: high-priority

注意:PriorityClass是非namespace隔离的,是global的。因此metadata下面是不能设置namespace field的。

  • apiVersion: scheduling.k8s.io/v1alpha1 # enable的时候需要配置的runtime-config参数;
  • metadata.name: 设置PriorityClass的名字;
  • value: 32-bit 整型值,值越大代表优先级越高,但是必须小于等于 1 billion,大于 1 billion的值是给集群内的critical system Pods保留的,表示该Priority的Pod是不能被抢占的。
  • globalDefault: true or false,注意只能有一个PriorityClass的这个字段为true,如果没有一个PriorityClass的该字段为true,则那些没有明确引用PriorityClass的Pod的Priority value就为最低值0.
  • description: String,写给人看的备注,Kubernetes不做处理;

注意:

  • PriorityClass只会影响那些还没创建的Pod,一旦Pod创建完成,那么admission Controller就已经将Pod Spec中应用的PriorityClassName对应的PriorityClass的value设置到Pod的Priority field了。意味着你再修改PriorityClass的任何field,包括globalDefault,也不会影响已经创建完成的Pod。
  • 如果你删除某个PriorityClass,那么不会影响已经引用它的Pod Priority,但你不能用它来创建新的Pod了。这其实是显而易见的。


可以看到,这个 Pod 通过 priorityClassName 字段,声明了要使用名叫 high-priority 的 PriorityClass。当这个 Pod 被提交给 Kubernetes 之后,Kubernetes 的 PriorityAdmissionController 就会自动将这个 Pod 的 spec.priority 字段设置为 1000000。


而我在前面的文章中曾为你介绍过,调度器里维护着一个调度队列。所以,当 Pod 拥有了优先级之后,高优先级的 Pod 就可能会比低优先级的 Pod 提前出队,从而尽早完成调度过程。这个过程,就是“优先级”这个概念在 Kubernetes 里的主要体现。

而当一个高优先级的 Pod 调度失败的时候,调度器的抢占能力就会被触发。这时,调度器就会试图从当前集群里寻找一个节点,使得当这个节点上的一个或者多个低优先级 Pod 被删除后,待调度的高优先级 Pod 就可以被调度到这个节点上。这个过程,就是“抢占”这个概念在 Kubernetes 里的主要体现。


为了方便叙述,我接下来会把待调度的高优先级 Pod 称为“抢占者”(Preemptor)。

当上述抢占过程发生时,抢占者并不会立刻被调度到被抢占的 Node 上。事实上,调度器只会将抢占者的 spec.nominatedNodeName 字段,设置为被抢占的 Node 的名字。然后,抢占者会重新进入下一个调度周期,然后在新的调度周期里来决定是不是要运行在被抢占的节点上。这当然也就意味着,即使在下一个调度周期,调度器也不会保证抢占者一定会运行在被抢占的节点上。


这样设计的一个重要原因是,调度器只会通过标准的 DELETE API 来删除被抢占的 Pod,所以,这些 Pod 必然是有一定的“优雅退出”时间(默认是 30s)的。而在这段时间里,其他的节点也是有可能变成可调度的,或者直接有新的节点被添加到这个集群中来。所以,鉴于优雅退出期间,集群的可调度性可能会发生的变化,把抢占者交给下一个调度周期再处理,是一个非常合理的选择。


而在抢占者等待被调度的过程中,如果有其他更高优先级的 Pod 也要抢占同一个节点,那么调度器就会清空原抢占者的 spec.nominatedNodeName 字段,从而允许更高优先级的抢占者执行抢占,并且,这也就是得原抢占者本身,也有机会去重新抢占其他节点。这些,都是设置 nominatedNodeName 字段的主要目的。

参考链接:

https://my.oschina.net/jxcdwangtao/blog/1559580

http://docs.kubernetes.org.cn/769.html


相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
27天前
|
前端开发 编解码 数据格式
浅谈响应式编程在企业级前端应用 UI 开发中的实践
浅谈响应式编程在企业级前端应用 UI 开发中的实践
22 0
浅谈响应式编程在企业级前端应用 UI 开发中的实践
|
28天前
|
Kubernetes 应用服务中间件 nginx
提升K8S故障排除效率:详解Pod内抓包的高效策略!
提升K8S故障排除效率:详解Pod内抓包的高效策略!
34 0
|
29天前
|
存储 Kubernetes 容器
K8s中Pod常见问题排查
K8s中Pod常见问题排查
20 6
|
2天前
|
Kubernetes 网络协议 调度
kubernetes最小调度单元pod详解(二)
kubernetes最小调度单元pod详解(二)
|
2天前
|
Kubernetes 应用服务中间件 调度
kubernetes最小调度单元pod详解(一)
kubernetes最小调度单元pod详解(一)
|
18天前
|
Kubernetes 固态存储 调度
Kubernetes节点亲和性分配Pod
Kubernetes节点亲和性分配Pod
30 0
Kubernetes节点亲和性分配Pod
|
18天前
|
存储 Kubernetes 调度
Kubernetes Pod生命周期
Kubernetes Pod生命周期
29 0
Kubernetes Pod生命周期
|
18天前
|
存储 Kubernetes 应用服务中间件
Kubernetes Pod
Kubernetes Pod
56 0
Kubernetes Pod
|
28天前
|
存储 Kubernetes 调度
kubernetes核心技术之Pod知识总结
【4月更文挑战第2天】kubernetes核心技术之Pod知识总结
49 0
|
29天前
|
存储 Kubernetes 调度
K8s Pod亲和性、污点、容忍度、生命周期与健康探测详解(下)
本文全面探讨了Kubernetes集群中Pod的四种关键机制——Pod亲和性、污点(Taints)、容忍度(Tolerations)、生命周期以及健康探测,为读者提供了深入理解并有效应用这些特性的指南。

推荐镜像

更多