k8s 亲和性之Affinity
文章目录
- 1. Node Affinity(节点亲和性)
- 节点亲和性类型
- 配置示例
- 常见场景:
- 2. Pod Affinity 和 Pod Anti-Affinity
- Pod Affinity 配置示例
- Pod Anti-Affinity 配置示例
- 常见场景:
- 3. 亲和性规则概述
- 4. 亲和性和反亲和性的细节
- 5. 亲和性配置的示例
- Pod 与 Node Affinity
- Pod 与 Pod Affinity
- 总结
在 Kubernetes 中,亲和性(Affinity)是一个强大的调度机制,用于控制 Pod 调度到哪些节点或与哪些其他 Pods 一起运行。亲和性帮助你在 Kubernetes 集群中实现更灵活、更高效的资源调度,支持多种不同的场景,如负载均衡、资源隔离、容错等。
亲和性有两种类型:
- Node Affinity(节点亲和性)
- Pod Affinity 和 Pod Anti-Affinity(Pod 亲和性与反亲和性)
1. Node Affinity(节点亲和性)
Node Affinity
用于约束 Pod 可以调度到哪些节点。它是 nodeSelector
的扩展,提供了更灵活的匹配机制。通过设置节点亲和性,Pod 可以根据节点的标签来选择适合的节点进行调度。
节点亲和性类型
Node Affinity
分为两种类型:
requiredDuringSchedulingIgnoredDuringExecution
:在调度时必须满足的条件,意味着如果节点不满足这些条件,Pod 就无法调度到该节点。preferredDuringSchedulingIgnoredDuringExecution
:调度时尽量满足的条件,但如果无法满足条件,Pod 仍然会被调度到其他节点。
配置示例
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "kubernetes.io/hostname"
operator: In
values:
- node-1
- node-2
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: "disk"
operator: In
values:
- ssd
requiredDuringSchedulingIgnoredDuringExecution
:指定节点必须满足的条件。在这个例子中,Pod 只能调度到node-1
或node-2
节点上。preferredDuringSchedulingIgnoredDuringExecution
:表示推荐的调度优先条件。在这个例子中,节点如果具有disk=ssd
标签,会更倾向于调度,但不是强制要求。
常见场景:
- 资源约束:需要特定硬件(例如 GPU 或 SSD 硬盘)的 Pod 必须调度到支持该硬件的节点。
- 环境隔离:将某些 Pods 部署到特定的可用区或区域,例如将数据库 Pod 放到具有高内存节点的区域。
2. Pod Affinity 和 Pod Anti-Affinity
Pod Affinity
和 Pod Anti-Affinity
控制 Pod 如何与其他 Pods 一起调度。它们允许你根据其他 Pods 的位置来影响当前 Pod 的调度。
-
Pod Affinity(Pod 亲和性):表示你希望某个 Pod 与其他特定 Pod 在同一节点上调度。例如,如果你希望某些 Pods 共享同一个节点,以便它们之间有低延迟的通信,可以使用 Pod 亲和性。
-
Pod Anti-Affinity(Pod 反亲和性):与 Pod 亲和性相反,表示你希望某些 Pod 不与其他特定 Pod 在同一节点上调度。例如,如果你希望某些 Pod 避免在同一节点上运行,以确保高可用性或隔离性,可以使用 Pod 反亲和性。
Pod Affinity 配置示例
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: myapp
topologyKey: "kubernetes.io/hostname"
这个例子表示,如果节点上有 app=myapp
标签的 Pod,则会优先调度当前 Pod 到同一节点上。topologyKey
是用来定义约束的范围,kubernetes.io/hostname
表示节点级别的约束。
Pod Anti-Affinity 配置示例
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: myapp
topologyKey: "kubernetes.io/hostname"
这个例子表示,如果节点上已经有 app=myapp
标签的 Pod,新的 Pod 就不会被调度到该节点上。
常见场景:
-
Pod Affinity:
- 将需要高频通信的 Pods 部署到同一节点,以减少网络延迟。例如,在微服务架构中,前端和后端服务可以被调度到相同节点上以提高通信效率。
-
Pod Anti-Affinity:
- 确保多个副本的 Pods 不会被调度到同一节点,以避免单点故障。例如,确保多个数据库副本的 Pods 分布在不同的节点上,以提高容错性。
3. 亲和性规则概述
亲和性规则的配置可以在 Pod 的 affinity
字段中指定,通常包括以下几个部分:
requiredDuringSchedulingIgnoredDuringExecution
:表示在 Pod 调度时必须满足的条件。可以用nodeAffinity
、podAffinity
或podAntiAffinity
来定义。preferredDuringSchedulingIgnoredDuringExecution
:表示尽量满足的条件,如果不满足,也不会阻止调度,但会影响调度优先级。topologyKey
:用于定义约束的范围,例如使用kubernetes.io/hostname
来指定节点级别的约束,或者使用可用区等来实现跨区域调度。
4. 亲和性和反亲和性的细节
-
topologyKey
:决定了亲和性约束的范围。常见的topologyKey
值有:kubernetes.io/hostname
:表示节点级别的亲和性。failure-domain.beta.kubernetes.io/zone
:表示区域级别的亲和性,用于跨区域调度。topology.kubernetes.io/region
:表示区域级别的亲和性,用于跨区域调度。
-
operator
:用于匹配条件的操作符,常见的有:In
:匹配指定的值。NotIn
:排除指定的值。Exists
:仅匹配标签存在的节点或 Pod。DoesNotExist
:仅匹配标签不存在的节点或 Pod。
5. 亲和性配置的示例
Pod 与 Node Affinity
将一个 Pod 调度到具有特定标签的节点上:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "disktype"
operator: In
values:
- ssd
这个例子要求 Pod 被调度到 disktype=ssd
的节点上。
Pod 与 Pod Affinity
将某个 Pod 调度到有特定标签的 Pod 所在的节点:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: myapp
topologyKey: "kubernetes.io/hostname"
这个配置要求将 Pod 调度到与标签为 app=myapp
的 Pod 相同节点上。
总结
Kubernetes 中的亲和性(Affinity)机制提供了灵活的调度策略,帮助我们实现更高效的资源利用、负载均衡、故障隔离等。通过结合 Node Affinity
和 Pod Affinity/Anti-Affinity
,你可以精细地控制 Pod 的调度行为,满足不同应用场景的需求。