k8s 亲和 & 反亲和介绍
文章内容来自k8s文档翻译以及个人理解和实际使用过程中的实践内容参考:https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/
目录
文章目录
k8s 亲和 & 反亲和介绍目录pod调度到node(nodeSelector)亲和与反亲和(Affinity and anti-affinity)节点亲和Pod间亲和 & 反亲和其他需要注意的点:pod调度到node(nodeSelector)
apiVersion: v1kind: Podmetadata:name: nginxlabels:env: testspec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresentnodeSelector: # 匹配节点的label,多个label之间为‘与’关系disktype: ssd
节点内置label: Well-Known Labels, Annotations and
亲和与反亲和(Affinity and anti-affinity)
节点亲和
节点亲和在概念上和nodeSelector
类似–根据node的label来约束pod可以调度到哪些节点。
有两种类型的节点亲和
硬亲和requiredDuringSchedulingIgnoredDuringExecution
软亲和preferredDuringSchedulingIgnoredDuringExecution
硬亲和指定将pod调度到节点上必须满足的规则(类似于nodeelector,但语法更形象)
软亲和指定首选项,调度器将尝试执行但没有保证。
名称中IgnoredDuringExecution
的部分表示:如果pod根据亲和规则被调度到某节点运行之后,此时node上的labels发生变化(不再符合pod上的亲和性规则)不会对在该节点上运行的pod造成影响。
在未来,k8s计划提供requireduringschedulingrequireduringexecution
,除了从不再符合pod亲和规则的节点上会自动驱逐pod,其他功能和requireduringschedulingignoredduringexecution
一致。
apiVersion: v1kind: Podmetadata:name: with-node-affinityspec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/e2e-az-nameoperator: Invalues:- e2e-az1- e2e-az2preferredDuringSchedulingIgnoredDuringExecution:- weight: 1preference:matchExpressions:- key: another-node-label-keyoperator: Invalues:- another-node-label-valuecontainers:- name: with-node-affinityimage: k8s.gcr.io/pause:2.0
查询表达式中可以使用的操作符有:In
,NotIn
,Exists
,DoesNotExist
,Gt
,Lt
等。操作符为In
,NotIn
时可以有多个值,Gt
,Lt
只能有且必须有一个值,Exists
,DoesNotExist
值必须为空。
可以使用NotIn
和DoesNotExist
来实现节点反亲和行为,或使用node taints
驱逐特定节点上的Pod。
如果同时指定了nodeSelector
和nodeAffinity
,则必须同时满足这两个条件,才能将pod调度到候选节点上
requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms
数组的多个元素之间为或
的关系
requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[i].matchExpressions
数组的多个元素之间为与
的关系
preferredDuringSchedulingIgnoredDuringExecution
数组的多个元素之间为或
的关系
preferredDuringSchedulingIgnoredDuringExecution
中的weight
字段的范围是1-100。对于每个满足所有调度要求的节点(资源需求,requireduringscheduling
亲和表达式等等),调度程序就计算preferredDuringSchedulingIgnoredDuringExecution
下所有匹配MatchExpressions
的条目的weight的总和,然后将此分数与该节点的其他优先级函数的分数合并,优先选择总得分最高的节点。
Node affinity per scheduling profile
FEATURE STATE: Kubernetes v1.20 [beta]
另外可以通过kube-scheduler的multiple-profiles特性来实现不同的亲和策略。即在KubeSchedulerConfiguration的profiles中配置不同调度器的亲和规则
apiVersion: kubescheduler.config.k8s.io/v1beta1kind: KubeSchedulerConfigurationprofiles:- schedulerName: default-scheduler- schedulerName: foo-schedulerpluginConfig:- name: NodeAffinityargs:addedAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: scheduler-profileoperator: Invalues:- foo
Pod间亲和 & 反亲和
pod间亲和与反亲和调度算法计算量较大,集群规模越大、节点越调度降速越明显,呈指数级增长。需要在使用此特性时考虑对调度速度的影响。
与节点不同,因为Pod是命名空间(因此Pod上的标签是隐式命名空间),所以Pod标签上的标签选择器必须指定选择器应用于哪些命名空间。若namespaces
为空,则默认是和pod的namespace相同。
apiVersion: v1kind: Podmetadata:name: with-pod-affinityspec:affinity:podAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: securityoperator: Invalues:- S1namespaces:- ns-1- ns-2topologyKey: topology.kubernetes.io/zonepodAntiAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 100podAffinityTerm:labelSelector:matchExpressions:- key: securityoperator: Invalues:- S2topologyKey: topology.kubernetes.io/zonecontainers:- name: with-pod-affinityimage: k8s.gcr.io/pause:2.0
查询表达式中可以使用的操作符只有:In
,NotIn
,Exists
,DoesNotExist
pod间亲和与反亲和的调度尺度不一定是以节点区分的,还可能是机架、机房、云服务提供商等拓扑域。
其拓扑域是通过topologyKey
字段定义的,这个字段的值是node的一个label的key,针对这个label,拥有相同value的节点属于同一拓扑域,pod亲和调度的时候会以拓扑域为基础,即根据该拓扑域(可能是一个节点、也可能是多个节点)中已存在的pod,判断新的pod应该(或不应该)调度到该拓扑域中的节点上。
原则上,topologyKey
可以是任何合法的标签的key。然而,出于性能和安全方面的原因,对topologyKey
有一些限制:
pod亲和与反亲和的requiredDuringSchedulingIgnoredDuringExecution
和preferredDuringSchedulingIgnoredDuringExecution
都不允许topologyKey
为空。pod反亲和的requiredDuringSchedulingIgnoredDuringExecution
被引入的admission controllerLimitPodHardAntiAffinityTopology
限制,只能是kubernetes.io/hostname
,如果想使用自定义的topologyKey
您可以修改或禁用掉admission controller。
其他需要注意的点:
节点亲和与pod间亲和为&的关系,即需要同时满足两者或三者。
应当避免多个同时部署的的k8s负载资源pod间亲和配置存在相互依赖关系,如果形成死锁会导致无法成功调度。