生产上为了保证应用的高可用性,需要将同一应用的不同pod分散在不同的宿主机上,以防宿主机出现宕机等情况导致pod重建,影响到业务的连续性。要想实现这样的效果,需要用到k8s自带的pod亲和性和反亲和性特性。
Pod 的亲和性与反亲和性有两种类型:
requiredDuringSchedulingIgnoredDuringExecution
preferredDuringSchedulingIgnoredDuringExecution
其中requiredDuringSchedulingIgnoredDuringExecution表示必须满足要求,preferredDuringSchedulingIgnoredDuringExecution表示尽量满足要求。
下面以一个yaml文件为例
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
service.cpaas.io/name: deployment-nginx
topologyKey: kubernetes.io/hostname
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: a
operator: In
values:
- b
topologyKey: kubernetes.io/hostname
containers:
- name: test-pod
image: nginx:1.18
上面配置中亲和性表示调度的节点上必须有labels包含service.cpaas.io/name: deployment-nginx的pod,如果没有这样的pod则调度失败。
反亲和性表示如果节点上有labels包含a: b的pod,则pod不应该调度到该节点上。
如果希望同一应用的不同pod,可以采用反亲和性配置,如果希望调用频繁的应用在相同节点上,减少通信延迟,可以采用亲和性配置。
具体的亲和性和反亲和性结构可以参考官方Kubernetes API.
原则上,topologyKey 可以是任何合法的标签键。出于性能和安全原因,topologyKey 有一些限制:
- 对于 Pod 亲和性而言,在 requiredDuringSchedulingIgnoredDuringExecution 和
preferredDuringSchedulingIgnoredDuringExecution 中,topologyKey 不允许为空。 - 对于 requiredDuringSchedulingIgnoredDuringExecution 要求的 Pod 反亲和性, 准入控制器
LimitPodHardAntiAffinityTopology 要求 topologyKey 只能是 kubernetes.io/hostname。如果你希望使用其他定制拓扑逻辑, 你可以更改准入控制器或者禁用之。