声明:本文为《Kubernetes权威指南:从Docker到Kubernetes实践全接触(第5版)》的读书笔记
在前前面的博客《k8s教程(14)-pod之node亲和性调度》,我们知道了pod的亲和性(Pod Affinity
)一般适用于以下场景:
存在某些相互依赖、频繁调用的Pod,它们需要被尽可能地部署在同一个Node节点、机架、机房、网段或者区域(Zone)内,这就是Pod之间的亲和性
反之,出于避免竞争或者容错的需求,我们也可能使某些Pod尽可能地远离某些特定的Pod,这就是Pod之间的反亲和性或者互斥性(Pod Anti Affinity
),也就是本文要讲的pod互斥调度。
亲和性与互斥性可以理解为就是相关联的两种或多种Pod是否可以在同一个拓扑域中共存或者互斥。
那么什么是拓扑域?
拓扑域的概念:
Node
节点组成,这些Node
节点通常有相同的地理空间坐标,比如在同一个机架、机房或地区;region
表示机架、 机房等的拓扑区域,用Zone
表示地区这样跨度更大的拓扑区域;k8s
内置了如下一些常用的默认拓扑域,主要是为了确定各个节点所属的拓扑域:
默认拓扑域 | 描述 |
---|---|
kubernetes.io/hostname | 在Node节点初始化时,controller–manager会为Node打上该标签 |
topology.kubernetes.io/region | 公有云厂商提供的Kubernetes服务或者使用cloud-controller-manager创建的集群,会给Node打上该标签 |
topology.kubernetes.io/zone | 同上 |
Pod
亲和与互斥的调度是通过在Pod
的定义上增加topologyKey 属性来声明对应的目标拓扑区域内几种相关联的Pod
要 “在一起或不在一起”。
与节点亲和相同,Pod亲和与互斥的条件设置也是requiredDuringSchedulingIgnoredDuringExecution
和
preferredDuringSchedulingIgnoredDuringExecution
:
下面通过实例来说明Pod间的亲和性和互斥性策略设置。
首先,创建一个名为pod-flag
的Pod
,带有标签security=S1
和app=nginx
,后面的例子将使用pod-flag
作为Pod
亲和与互斥的目标Pod
:
apiversion:v1
kind:Pod
metadata:
name:pod-flag
labels:
security:"S1"
app:"nginx"
spec:
containers:
-name:nginx
image:nginx
下面创建第2个Pod来说明Pod的亲和性调度,这里定义的亲和标签是 “security=S1”,对应上面的Pod “pod-flag”,topologyKey的值被设置为 “kubernetes.io/hostname“:
apiVersion:vl
kind:Pod
metadata:
name:pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key:security
operator:In
values:
-S1
topologyKey:kubernetes.io/hostname
containers:
- name:with-pod-affinity
image:gcr.io/google_containers/pause:2.0
创建Pod
之后,使用kubectl get pods -o wide
命令可以看到,这两个Pod
在同
一个Node
上运行。
在创建这个
Pod
之前,删掉这个节点的kubernetes.io/hostname
标签,重复上面的创建步骤,将会发现Pod
一直处于Pending
状态,这是因为找不到满足条件的Node
了。
创建第3个Pod
,我们希望它不与目标Pod
运行在同一个Node
上:
apiversion:v1
kind:Pod
metadata:
name:anti-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key:security
operator:In
values:
-S1
topologyKey:topology.kubernetes.io/zone
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key:app
operator:In
values:
-nginx
topologyKey:kubernetes.io/hostname
containers:
- name:anti-affinity
image:gcr.io/google_containers/pause:2.0
这里要求这个新Pod
与security=S1
的Pod为同一个zone
,但是不与app=nginx
的Pod
为同一个Node
。
创建Pod
之后,同样用kubectl get pods -o wide
来查看,会看到新的Pod
被调度到了同一Zone
内的不同Node
上。
与节点亲和性类似,Pod
亲和性的操作符也包括In、NotIn、Exists、 DoesNotExist、Gt、Lt
。
原则上,topologyKey
可以使用任意合法的标签Key
赋值,但是出于性能和安全方面的考虑,对topologyKey
有如下限制:
PodAffinity规则设置的注意事项如下:
本文主要讲解了pod的亲和性调度与互斥性调度的概念及例子,并简单地介绍了拓扑域的概念,希望能帮助到大家,谢谢大家的阅读,本文完!