概述图
在 Kubernetes 中,节点亲和性(Node Affinity) 是一种调度约束机制,用来控制 Pod 应调度到哪些节点上运行。通过节点亲和性,可以基于节点的标签来定义调度规则,确保 Pod 只会调度到满足条件的节点。节点亲和性对 Kubernetes 的调度器有直接的影响,因为它决定了调度器在选择节点时的规则和优先级。
节点亲和性类型
Kubernetes 提供了两种主要的节点亲和性类型:
-
强制型亲和性 (
requiredDuringSchedulingIgnoredDuringExecution):- Pod 必须 调度到满足亲和性条件的节点上,否则调度会失败。即,如果没有符合条件的节点,Pod 将无法被调度。
-
软约束型亲和性 (
preferredDuringSchedulingIgnoredDuringExecution):- 调度器会 尽量 将 Pod 调度到符合条件的节点,但如果没有满足条件的节点,Pod 依然会被调度到其他节点上。
在节点亲和性中,调度器会根据节点的标签进行评估,确保 Pod 被分配到满足这些标签条件的节点上。
节点亲和性对 Pod 调度的影响
1. 强制型节点亲和性 (requiredDuringSchedulingIgnoredDuringExecution)
- 如果 Pod 的节点亲和性规则属于 强制型,调度器会严格按照这些规则进行调度。如果没有符合亲和性条件的节点,Pod 将无法被调度。
- 举例来说,假设某个 Pod 只允许调度到带有
disktype=ssd标签的节点上,调度器会遍历所有节点,并只选择符合这个标签的节点。如果没有符合条件的节点,Pod 会一直处于Pending状态,直到有符合条件的节点出现。
示例:强制型节点亲和性
yaml
复制代码
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx
在这个示例中,Pod 必须调度到拥有 disktype=ssd 标签的节点。如果没有符合这个条件的节点,Pod 将无法被调度成功。
2. 软约束型节点亲和性 (preferredDuringSchedulingIgnoredDuringExecution)
- 如果 Pod 的节点亲和性规则属于 软约束型,调度器会优先选择符合条件的节点进行调度,但如果没有符合条件的节点,调度器会选择其他节点来调度 Pod。
- 这种方式可以提高调度的灵活性,确保 Pod 能够在尽可能满足亲和性条件的前提下成功调度,而不会因为没有匹配的节点而阻塞。
示例:软约束型节点亲和性
yaml
复制代码
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx
在这个示例中,调度器会优先选择带有 disktype=ssd 标签的节点来调度 Pod,但如果没有此类节点,Pod 仍然会被调度到其他节点上运行。
节点亲和性 vs 节点选择器
节点亲和性和 节点选择器(Node Selector) 都是基于节点标签的调度机制,但节点亲和性比节点选择器更加灵活和强大。
-
节点选择器 只支持简单的等式匹配,无法表达更复杂的调度策略。
- 例如,节点选择器无法表达 "节点的标签
disktype必须是ssd或hdd" 这样的条件。
- 例如,节点选择器无法表达 "节点的标签
-
节点亲和性 提供了更多运算符(
In、NotIn、Exists、DoesNotExist等),并支持多条件组合,可以更灵活地控制调度规则。
示例:节点选择器 vs 节点亲和性
-
节点选择器 只能简单匹配标签:
yaml 复制代码 spec: nodeSelector: disktype: ssd -
节点亲和性 可以表达更复杂的条件,如:
yaml 复制代码 spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: disktype operator: In values: - ssd - hdd
节点亲和性和 Pod 调度的应用场景
-
不同硬件配置的节点:
- 如果集群中有不同硬件配置的节点(如 SSD 节点和 HDD 节点),可以使用节点亲和性将对存储有较高需求的 Pod 调度到 SSD 节点上,而将对存储需求较低的 Pod 调度到 HDD 节点上。
-
隔离工作负载:
- 可以通过节点亲和性将不同类型的工作负载(如生产环境和测试环境的工作负载)隔离到不同的节点池中。例如,可以为生产环境的节点打上特定标签,然后使用强制型亲和性将生产环境的 Pod 调度到这些节点上。
-
区域或机房分布:
- 在多区域或多机房的 Kubernetes 集群中,可以使用节点亲和性将 Pod 限制在特定的区域或机房,以确保数据和计算在同一地理位置,减少延迟。
节点亲和性的关键运算符
在定义节点亲和性规则时,matchExpressions 使用以下运算符来构建调度条件:
-
In:节点标签的值在指定列表中。
- 例:
disktype在['ssd', 'hdd']中。
- 例:
-
NotIn:节点标签的值不在指定列表中。
- 例:
disktype不在['ssd']中。
- 例:
-
Exists:节点必须具有指定的标签(标签值不重要)。
- 例:节点必须有
disktype标签。
- 例:节点必须有
-
DoesNotExist:节点不能有指定的标签。
- 例:节点不能有
disktype标签。
- 例:节点不能有
-
Gt / Lt:节点标签的值大于或小于某个数值。
- 例:
num_cpu大于 4。
- 例:
调度过程中的优先级
Kubernetes 调度器根据定义的节点亲和性规则来筛选节点,并遵循以下流程:
- 过滤阶段:调度器首先过滤出符合所有 强制型节点亲和性(
requiredDuringSchedulingIgnoredDuringExecution)规则的节点,排除不符合条件的节点。 - 打分阶段:对于符合强制型亲和性的节点,调度器根据 软约束型节点亲和性(
preferredDuringSchedulingIgnoredDuringExecution)的权重对这些节点进行打分。得分较高的节点将优先被选择。
总结
节点亲和性通过灵活的调度约束规则控制 Pod 的调度,确保 Pod 被调度到满足特定需求的节点上。它为集群管理员提供了更强大的调度策略,可以基于节点的硬件特性、工作负载隔离需求、地理分布等因素优化调度决策。
理解和应用节点亲和性可以帮助你更高效地管理 Kubernetes 集群,提高资源利用率,减少调度冲突,并确保应用程序在合适的节点上运行。