pod 间亲和性与反亲和性
Pod的亲和性是基于已经在节点上运行的pod的标签来约束pod可以到的节点
topologyKey
topologyKey是节点标签的键以便系统表示拓扑;pod反亲和性需要对节点进行匹配,不匹配topologyKey的节点不会进行分配。
labelSelector和topology可以指定namespace范围。
Pod 反亲和性需要对节点进行一致的标记,即集群中的每个节点必须具有适当的标签能够匹配 topologyKey。如果某些或所有节点缺少指定的 topologyKey 标签,可能会导致意外行为。
内置的节点标签
- kubernetes.io/hostname
- failure-domain.beta.kubernetes.io/zone
- failure-domain.beta.kubernetes.io/region
- topology.kubernetes.io/zone
- topology.kubernetes.io/region
- beta.kubernetes.io/instance-type
- node.kubernetes.io/instance-type
- kubernetes.io/os
- kubernetes.io/arch
topologyKey 受到一些限制:
对于亲和性与 requiredDuringSchedulingIgnoredDuringExecution 要求的 Pod 反亲和性,topologyKey 不允许为空。
对于 requiredDuringSchedulingIgnoredDuringExecution 要求的 Pod 反亲和性, 准入控制器 LimitPodHardAntiAffinityTopology 被引入来限制 topologyKey 不为 kubernetes.io/hostname。 如果你想使它可用于自定义拓扑结构,你必须修改准入控制器或者禁用它。
对于 preferredDuringSchedulingIgnoredDuringExecution 要求的 Pod 反亲和性, 空的 topologyKey 被解释为“所有拓扑结构”(这里的“所有拓扑结构”限制为 kubernetes.io/hostname,topology.kubernetes.io/zone 和 topology.kubernetes.io/region 的组合)。
除上述情况外,topologyKey 可以是任何合法的标签键。
Operator
Pod 亲和性与反亲和性的合法操作符有 In,NotIn,Exists,DoesNotExist。
使用场景
1. 将服务A和服务B放在同一个服务区域,两个服务具有依赖性
应用Security: S2 依赖于security: S1的应用, 但是应用Security: S1跨区域部署。
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: topology.kubernetes.io/zone
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S2
topologyKey: topology.kubernetes.io/zone
containers:
- name: with-pod-affinity
image: k8s.gcr.io/pause:2.0
2. 将服务跨区域部署
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: front-end
name: front-end
namespace: ing-internal
spec:
selector:
matchLabels:
app: front-end
template:
metadata:
labels:
app: front-end
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- front-end
topologyKey: kubernetes.io/hostname