Kubernetes 中的 Affinity 和 Anti-Affinity 规则用于控制如何将 Pod 放在集群内的节点上。这些规则有助于确保 Pod 的调度方式满足特定要求,例如将相关服务共用同一地点或将工作负载分散到不同节点上。


下面的代码片段说明了如何设置 Affinity(亲和)规则,以确保在同一节点上调度某些 Pod,而 Anti-Affinity(反亲和)规则则防止将 Pod 放在同一节点上。

[代码清单]

apiVersion: apps/v1
kind: Deployment
metadata:
 name: my-app
spec:
 replicas: 3
 selector:
  matchLabels:
   app: my-app
 template:
  metadata:
   labels:
​    app: my-app
  spec:
   affinity:
​    podAffinity:
​     requiredDuringSchedulingIgnoredDuringExecution:
​     \- labelSelector:
​       matchExpressions:
​       \- key: app
​        operator: In
​        values:
​        \- my-app
​      topologyKey: "kubernetes.io/hostname"
​    podAntiAffinity:
​     requiredDuringSchedulingIgnoredDuringExecution:
​     \- labelSelector:
​       matchExpressions:
​       \- key: app
​        operator: In
​        values:
​        \- my-app
​      topologyKey: "kubernetes.io/hostname"
   containers:
   \- name: my-container
​    image: my-image

[执行结果]

部署已成功创建,Pod 将根据定义的 Affinity 和 Anti-Affinity 规则进行调度。

在此示例中,podAffinity 规则规定,带有 app: my-app 标签的 Pod 应调度在同一节点上(topologyKey: kubernetes.io/hostname)。这对于需要低延迟通信的应用程序非常有用。相反,podAntiAffinity 规则确保具有相同标签的 Pod 不被放在同一个节点上,这样可以通过将副本分散到不同节点来增强容错能力。

[小知识]

拓扑密钥: 拓扑密钥定义了如何根据节点标签应用规则。常见密钥包括节点级规则的 kubernetes.io/hostname,以及区域级规则的 failure-domain.beta.kubernetes.io/zone。

对调度的影响: 亲缘和反亲缘规则会使调度变得更加复杂,如果集群没有足够的资源或合适的节点,可能会导致 Pod 无法调度。

最佳实践: 谨慎使用亲和与反亲和规则,避免过度限制调度程序,否则可能导致资源浪费或调度失败。