k8s 亲和 & 反亲和介绍
k8s 亲和 & 反亲和介绍文章内容来自k8s文档翻译以及个人理解和实际使用过程中的实践内容参考:https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/目录文章目录k8s 亲和 & 反亲和介绍目录pod调度到node(nodeSelector)亲和与反亲和(Affinity and anti-
k8s 亲和 & 反亲和介绍
文章内容来自k8s文档翻译以及个人理解和实际使用过程中的实践内容
参考:https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/
目录
文章目录
pod调度到node(nodeSelector)
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector: # 匹配节点的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: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
- e2e-az2
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value
containers:
- name: with-node-affinity
image: 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/v1beta1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
- schedulerName: foo-scheduler
pluginConfig:
- name: NodeAffinity
args:
addedAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: scheduler-profile
operator: In
values:
- foo
Pod间亲和 & 反亲和
pod间亲和与反亲和调度算法计算量较大,集群规模越大、节点越调度降速越明显,呈指数级增长。需要在使用此特性时考虑对调度速度的影响。
与节点不同,因为Pod是命名空间(因此Pod上的标签是隐式命名空间),所以Pod标签上的标签选择器必须指定选择器应用于哪些命名空间。若namespaces
为空,则默认是和pod的namespace相同。
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
namespaces:
- ns-1
- ns-2
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
查询表达式中可以使用的操作符只有: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间亲和配置存在相互依赖关系,如果形成死锁会导致无法成功调度。
更多推荐
所有评论(0)