k8s调度深入刨析
调度程序决定 pod 在集群中的部署位置,这听起来像是一项简单的工作,但它相当复杂!当使用 kubectl 提交部署时,API 服务器会收到请求,并将资源存储在 etcd 中。
一、谁创建了 Pod?
一个常见的误解是创建 pod 是调度程序的工作。相反,控制器管理器创建它们(以及关联的 ReplicaSet)。
此时,pod 在 etcd 中存储为“Pending”,未分配给任何节点。它们也被添加到调度程序的队列中,准备好被分配。
二、调度绑定
调度程序通过两个阶段 1 个 1 个地处理 Pod:
- 调度阶段(我应该选择什么节点?)
- 绑定阶段(将此 pod 所属于的节点信息写入数据库)
Scheduler阶段分为两部分。调度程序:
- 过滤相关节点(Predicates 预选策略),强制性规则,遍历所有的Node,按照具体的预选策略筛选出符合要求的Node列表,如没有Node符合Predicates策略规则,那该Pod就会被挂起,直到有Node能够满足;
- 对剩余节点进行排名(Priorites优选策略),优选策略,在第一步筛选的基础上,按照优选策略为待选Node打分排序,获取最优者;
参考页面:
Kubernetes Scheduler分析
k8s官网调度策略文档
三、GPU调度示例
让我们看一个例子,比如我们有一个带和不带 GPU 的节点的集群。此外,一些节点已经满负荷运行。
您想要部署需要一些 GPU 的 Pod,将 pod 提交到集群,它被添加到调度程序队列中。调度器丢弃所有没有 GPU 的节点(过滤阶段)。
接下来,调度程序对剩余的节点进行评分。充分利用的节点得分较低,最后会选择空节点。
过滤器的分类示例:
NodeUnschedulable
防止 pod 调度标记为不可调度的节点VolumeBinding
检查节点是否可以绑定请求的卷
建议参考:kube-scheduler predicates 与 priorities 调度算法源码分析
默认过滤阶段有 13 个 断言(Predicates)— 这部分要根据实际k8s版本而定,不同版本内容也在更新。
以下是一些评分示例:
ImageLocality
首选已在本地下载容器映像的节点。NodeResourcesBalancedAllocation
更喜欢未充分利用的节点。
有 13 个函数决定如何对节点进行评分和排名 — 每个 priority 函数为 node 打分,分数为 0-10 ,0 表示优先级最低的节点,10表示优先级最高的节点 。
四、控制调度程序的决策
控制调度程序的决策方式主要有以下这些:
- nodeSelector
- Node affinity
- Pod affinity/anti-affinity
- Taints and tolerations
- Topology constraints
- Scheduler profiles
nodeSelector
是最直接的机制,将标签分配给节点并将该标签添加到 pod,Pod 只能部署在具有该标签的节点上。
Node affinity
节点亲和性通过更灵活的接口扩展了 nodeSelector,您仍然可以告诉调度器 Pod 应该部署在哪里,但是您也可以有软约束和硬约束。
Pod affinity/anti-affinity
使用 Pod 亲和性/反亲和性,您可以要求调度程序将一个 pod 放置在特定 pod 旁边(或排斥某pod)。
Taints and tolerations
有了污点和容忍度,pod 被污染,节点排斥(或容忍)pod ,这类似于节点亲和性,但有一个显着的区别:对于节点亲和性,Pod 被吸引到节点上。污点恰恰相反——它们允许节点排斥 pod。
此外,容忍度可以通过三种效果排斥 pod:逐出、“不调度”和“强列不调度(双重否定)”。个人说明:这是我使用过的最困难的 API 之一。我总是(并且一直)把它弄错,因为(对我来说)很难用双重否定来推理。
Topology constraints
您可以使用拓扑分布约束来控制 Pod 在集群中的分布方式 。当您要确保所有 Pod 不落在同一个节点上时,这很方便。
Scheduler profiles
最后,您可以使用调度程序策略来自定义调度程序如何使用过滤器和谓词将节点分配给 Pod。这个相对较新的功能 (>1.25) 允许您关闭或向调度程序添加新逻辑。
您可以在此处了解有关调度程序的更多信息:
- Kubernetes 调度程序https://kubernetes.io/docs/concepts/scheduling-eviction/kube-scheduler/
- 调度框架https://kubernetes.io/docs/concepts/scheduling-eviction/scheduling-framework/
- 调度器策略https://kubernetes.io/docs/reference/scheduling/config/
本篇内容基于 Daniele Polencic的文章 翻译再加工。
捐赠本站(Donate)
如您感觉文章有用,可扫码捐赠本站!(If the article useful, you can scan the QR code to donate))
- Author: shisekong
- Link: https://blog.361way.com/k8s-scheduler-deep-dive/8485.html
- License: This work is under a 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. Kindly fulfill the requirements of the aforementioned License when adapting or creating a derivative of this work.