Kubernetes之Pod调度策略
一、NodeSelector:定向调度
1. 基本原理
在 Kubernetes 上部署应用时,有时候可能需要限制 Pod 的调度范围,将 Pod 调度到指定的一些 Node 上。此时,可以为需要调度的这些 Node 打上标签,同时设置 Pod 的 nodeSelector 属性,使二者相匹配来达到定向调度的目的。
2. 简单实践
(1)为目标 Node 打标签

(2)为 Pod 设置 nodeSelector 属性

(3)创建 deployment

可以看到,该 deployment 创建的 3 个 pod 都调度到了打了对应标签的 Node 上。
(4)注意事项
如果指定了 Pod 的 nodeSelector 属性,但没有给任何 Node 打上对应的标签,则 Pod 将无法成功调度,一直处于 Pending 状态。
二、NodeAffinity:Node 亲和性调度
1. 基本原理
NodeAffinity 是用于替换 NodeSelector 的全新调度策略,目前有两种亲和性表达:
(1)RequiredDuringSchedulingIgnoredDuringExecution:必须满足指定的规则才可以调度 Pod 到 Node 上(功能与 nodeSelector 相似),相当于硬限制。
(2)PreferredDuringSchedulingIgnoredDuringExecution:强调优先满足指定规则,调度器会尝试调度 Pod 到 Node 上,但并不强求,相当于软限制。多个优先级规则还可以设置权重值,以定义执行的先后顺序。
IgnoredDuringExecution 的意思是:如果一个 Pod 所在的节点在 Pod 运行期间标签发生了变更,不再符合该 Pod 的节点亲和性需求,则系统将忽略 Node 上标签的变化,该 Pod 还能继续在该节点上运行。
2. 简单实践
(1)在 deployment 规约中定义 nodeAffinity

这里 nodeAffinity 定义的规则为:只运行在 amd64 的节点上,同时尽量运行在 disk-type=ssd 的节点上。
NodeAffinity 语法支持的操作符:In、NotIn、Exists、DoesNotExists、Gt、Lt。
(2)给节点打标签

(3)创建 deployment

可以看到,满足硬限制但不满足软限制的 Node 也被调度了 Pod 运行。
(4)注意事项
<1>如果同时定义了 NodeSelector 和 nodeAffinity,那么必须两个条件都得到满足,Pod 才能最终运行在指定的 Node 上。
<2>如果 nodeAffinity 指定了多个 NodeSelectorTerms,那么其中一个能匹配成功即可。
<3>如果在 NodeSelectorTerms 中有多个 matchExpressions,则一个节点必须满足所有 matchExpressions 才能运行该 Pod。
三、PodAffinity:Pod 亲和与反亲和调度
1. 基本原理
在实际的生产环境中有一类特殊的 Pod 调度需求:存在某些相互依赖、频繁调用的 Pod,它们需要被尽可能地部署在同一个 Node 节点、机架、机房、网段或者区域内,这就是 Pod 之间的亲和性;反之,出于避免竞争或者容错的需求,我们也可能使某些 Pod 尽可能地远离某些特定的 Pod,这就是 Pod 之间的反亲和性或者互斥性。
简单地说,就是相关联的两种或多种 Pod 是否可以在同一个拓扑域中共存或者互斥,前者被称为 Pod Affinity,后者被称为 Pod Anti Affinity。拓扑域可以是区域、机房、机架,甚至可用是一个节点。
定义调度策略时,先为 Pod 设置 topologyKey 属性,声明拓扑域,然后再定义亲和与反亲和的规则。
2. 简单实践
(1)创建参照目标 Pod

(2)Pod 的亲和性调度

Pod 亲和性调度策略:希望与带有 security=S1 标签的 Pod 调度到同一个 Node 上。

可以看到 deployment 创建出来的三个 Pod 都被调度到 flag-pod 运行的 Node 上了。
(3)Pod 的反亲和性调度

Pod 互斥性调度策略:希望 Pod 被调度到与带有 app=flag-pod 标签的 Pod 不同的 Node 上。

可以看到 deployment 创建出来的三个 Pod 都被调度到与 flag-pod 不同的 Node 上了。
四、Taints and Tolerations:污点和容忍
1. 基本原理
NodeAffinity 使得 Pod 能够被调度到某些 Node 上运行,taints 则相反,它让 Node 拒绝 Pod 的运行,除非 Pod 定义了对应的 tolerations。
Node 声明 taints 的格式示例:

Pod 声明 tolerations 的格式示例:

要使得 Pod 能够在定义了 taints 的 Node 上运行,则 Pod 定义 tolerations 的 key 和 effect 需要与 taints 的设置保持一致,operator 为 Exists,或者 operator 为 Equal 且 value 与 taints 的 value 相等。
其中,effect 有三种取值:
(1)NoSchedule:一个 Pod 如果没有声明容忍这个 taint,则不会被调度到这个 Node 上。
(2)PreferNoSchedule:一个 Pod 如果没有声明容忍这个 taint,则系统会尽量避免将这个 Pod 调度到这个 Node 上,但不是强制的,相当于 NoSchedule 的软限制版本。
(3)NoExecute:为一个 Node 加上 taint 后,该 Node 上运行的所有无对应 toleration 的 Pod 都会被立刻驱逐,同时系统也允许设置 tolerationSeconds 字段,单位为秒,表示这个 Pod 在 taint 添加到 Node 上以后还能在这个 Node 上运行多久。
2. 简单实践
(1)创建不带 tolerations 的 Pod

(2)为 Node 设置 taints

(3)查看 pod

可以看到,Node 设置完 taints 以后,deployment 中两个位于该 Node 上的 Pod 都被驱逐了,在另一个 Node 上拉起了新的 Pod 副本。
(4)删除 Node 的 taints

3. 应用场景
(1)将集群中某些 Node 专门给特定应用使用。
(2)将具有特殊硬件设备的 Node 提供给对这类硬件有需求的 Pod,而将不需要这类硬件的 Pod 排除在外。
(3)定义 Pod 驱逐行为,以应对 Node 故障。
参考:
《Kubernetes 权威指南第 5 版》
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器