跳到主要内容

亲和性调度

2024年09月19日
柏拉文
越努力,越幸运

一、认识


Kubernetes 中,亲和性调度(Affinity Scheduling 是一种强大且灵活的机制,用于控制 Pod 如何被调度到特定的节点或与其他 Pod 之间的关系。通过使用亲和性,您可以优化资源利用、提高应用的可靠性和性能。

亲和性调度 允许您定义 Pod 与节点或其他 Pod 之间的调度规则。这些规则可以基于标签、拓扑域(如区域、可用区、主机名)等,以确保 Pod 被调度到最合适的位置。Kubernetes 提供了以下几种亲和性类型:

  1. 节点亲和性(Node Affinity:控制 Pod 调度到哪些节点。

  2. Pod 亲和性(Pod Affinity:控制 Pod 被调度到与特定标签的其他 Pod 相同的节点或拓扑域。

  3. Pod 反亲和性(Pod Anti-Affinity:控制 Pod 被调度到与特定标签的其他 Pod 不同的节点或拓扑域。

亲和性调度 应用场景如下:

  1. 高可用性部署: 使用 Pod 反亲和性,确保多个副本的 Pod 分布在不同的节点或可用区,避免单点故障。

  2. 使用节点亲和性: 使用节点亲和性,将需要访问特定存储的 Pod 调度到具备该存储节点上,以减少网络延迟和带宽消耗。

  3. 资源隔离: 使用 Pod 反亲和性,防止不同租户的 Pod 部署在同一节点上,增强安全性和隔离性。

  4. 应用亲和性: 使用 Pod 亲和性,将前端服务与后端服务部署在同一节点或同一可用区,减少通信延迟。

亲和性调度 前提如下:

  1. 查看节点标签: 可以通过 kubectl get node --show-labels 查看所有 Worker 节点标签

  2. 设置节点标签: disktype 标签可以通过 kubectl label nodes [Worker 节点名称] disktype=[xxx] 进行设置

二、属性


2.1 topologyKey

topologyKey 决定了亲和性规则的作用范围。常见的拓扑键包括:

  • kubernetes.io/hostname:按节点(主机)划分。

  • failure-domain.beta.kubernetes.io/zonetopology.kubernetes.io/zone:按可用区(Zone)划分。

  • failure-domain.beta.kubernetes.io/regiontopology.kubernetes.io/region:按区域(Region)划分。

选择合适的 topologyKey 可以帮助您实现跨节点、跨可用区甚至跨区域的调度策略。例如,使用 zone 作为 topologyKey 可以确保 Pod 分布在不同的可用区,增强高可用性。

2.2 requiredDuringSchedulingIgnoredDuringExecution

requiredDuringSchedulingIgnoredDuringExecution 必需的节点亲和性 (Required Node Affinity) 这是一个硬性约束,Pod 只能被调度到满足条件的节点上。如果没有符合条件的节点,Pod 将无法调度成功。

2.3 preferredDuringSchedulingIgnoredDuringExecution

preferredDuringSchedulingIgnoredDuringExecution 偏好的节点亲和性(Preferred Node Affinity 这是一个软性约束,表示调度器会优先选择满足条件的节点,但如果没有符合条件的节点,Pod 仍然可以被调度到其他节点上。

三、Node Affinity


节点亲和性(Node Affinity 允许您指定 Pod 应该被调度到哪些节点,或者哪些节点更适合运行该 Pod。节点亲和性分为 必需(required) 和 偏好(preferred) 两种类型:

3.1 必需的节点亲和性(Required Node Affinity)

必需的节点亲和性 (Required Node Affinity) 这是一个硬性约束,Pod 只能被调度到满足条件的节点上。如果没有符合条件的节点,Pod 将无法调度成功。

语法

apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx
image: registry.cn-hangzhou.aliyuncs.com/bolawen/nginx:1.27.1-perl-linux-arm64
imagePullPolicy: IfNotPresent
  • requiredDuringSchedulingIgnoredDuringExecution:指定这是一个必须满足的条件。

  • nodeSelectorTerms:定义节点选择的条件。

  • matchExpressions:指定节点标签 disktype 必须是 ssddisktype 标签可以通过 kubectl label nodes [Worker 节点名称] disktype=[xxx] 进行设置。同时,可以通过 kubectl get node --show-labels 查看所有 Worker 节点标签。

3.2 偏好的节点亲和性(Preferred Node Affinity)

偏好的节点亲和性(Preferred Node Affinity 这是一个软性约束,表示调度器会优先选择满足条件的节点,但如果没有符合条件的节点,Pod 仍然可以被调度到其他节点上。

语法

apiVersion: v1
kind: Pod
metadata:
name: preferred-node-affinity-pod
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: region
operator: In
values:
- us-west
containers:
- name: app-container
image: nginx
  • preferredDuringSchedulingIgnoredDuringExecution:指定这是一个偏好条件。

  • weight:权重,范围为 1 到 100,表示优先级。

  • matchExpressions:节点标签 region 优先选择 us-westdisktype 标签可以通过 kubectl label nodes [Worker 节点名称] disktype=[xxx] 进行设置。同时,可以通过 kubectl get node --show-labels 查看所有 Worker 节点标签。

四、Pod Affinity


Pod 亲和性(Pod Affinity 允许 Pod 被调度到与具有特定标签的其他 Pod 相同的节点或拓扑域,而 Pod 反亲和性则相反,防止 Pod 被调度到与具有特定标签的其他 Pod 相同的节点或拓扑域。

4.1 必需的节点亲和性(Required Node Affinity)

语法

apiVersion: v1
kind: Pod
metadata:
name: pod-affinity-pod
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: frontend
topologyKey: "kubernetes.io/hostname"
containers:
- name: app-container
image: nginx
  • podAffinity :定义 Pod 亲和性规则。

  • requiredDuringSchedulingIgnoredDuringExecution:必须满足的条件。

  • labelSelector:选择具有标签 app=frontendPod

  • topologyKey:亲和性作用的拓扑域,这里是主机名,表示 Pod 必须与具有 app=frontend 标签的 Pod 在同一节点上。

4.2 偏好的节点亲和性(Preferred Node Affinity)

五、Pod Anti-Affinity


Pod 反亲和性(Pod Anti-Affinity

5.1 必需的节点亲和性(Required Node Affinity)

语法

apiVersion: v1
kind: Pod
metadata:
name: pod-anti-affinity-pod
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: backend
topologyKey: "kubernetes.io/hostname"
containers:
- name: app-container
image: nginx
  • podAntiAffinity:定义 Pod 反亲和性规则。

  • requiredDuringSchedulingIgnoredDuringExecution:必须满足的条件。

  • labelSelector:选择具有标签 app=backendPod

  • topologyKey:反亲和性作用的拓扑域,这里是主机名,表示 Pod 不能与具有 app=backend 标签的 Pod 在同一节点上。

5.2 偏好的节点亲和性(Preferred Node Affinity)