Pod 亲和调度
首先我们来看 Pod 亲和调度,假如我想把一个 Pod 和另一个 Pod 放在一起,这时我们可以看上图中的实例写法,填写上 podAffinity,然后填上 required 要求。
在这个例子中,必须要调度到带了 key: k1 的 Pod 所在的节点,并且打散粒度是按照节点粒度去打散索引的。这种情况下,假如能找到带 key: k1 的 Pod 所在节点,就会调度成功。假如这个集群不存在这样的 Pod 节点,或者是资源不够的时候,那就会调度失败。这是一个严格的亲和调度,我们叫做尝试亲和调度。
有些时候我们并不需要这么严格的调度策略。这时候可以把 required 改成 preferred,变成一个优先亲和调度。
也就是优先可以调度带 key: k2 的 Pod 所在节点。并且这个 preferred 里面可以是一个 list 选择,可以填上多个条件,比如权重等于 100 的是 key: k2,权重等于 10 的是 key: k1。那调度器在调度的时候会优先把这个 Pod 分配到权重分更高的调度条件节点上去。
另外 Kubernetes 除了 In 这个 Operator 语法之外,还提供了更多丰富的语法组合来给大家使用。比如说 In/NotIn/Exists/DoesNotExist 这些组合方式。上图的例子用的是 In,比如说第一个强制反亲和例子里面,相当于我们必须要禁止调度到带了 key: k1 标签的 Pod 所在节点。
同样的功能也可以使用 Exists,Exists 范围可能会比 In 范围更大,当 Operator 填了 Exists,就不需要再填写 values。它做到的效果就是禁止调度到带了 key: k1 标签的 Pod 所在节点,不管 values 是什么值,只要带了 k1 这个 key 标签的 Pod 所在节点,都不能调度过去。
以上就是 Pod 与 Pod 之间的关系调度。
Pod 反亲和调度
上面介绍了亲和调度,而反亲和调度其实是与亲和调度比较像的。比如说功能上是取反的,在语法上基本上是一样的,只是 podAffinity 换成了 podAntiAffinity,做到的效果也是 required 强制反亲和,以及一个 preferred 优先反亲和。
我这里同时举了两个例子:一个是禁止调度到带了 key: k1 标签的 Pod 所在节点;另一个是优先反亲和调度到带了 key: k2 标签的 Pod 所在节点。
另外 Kubernetes 除了 In 这个 Operator 语法之外,还提供了更多丰富的语法组合来给大家使用。比如说 In/NotIn/Exists/DoesNotExist 这些组合方式。上图的例子用的是 In,比如说第一个强制反亲和例子里面,相当于我们必须要禁止调度到带了 key: k1 标签的 Pod 所在节点。
同样的功能也可以使用 Exists,Exists 范围可能会比 In 范围更大,当 Operator 填了 Exists,就不需要再填写 values。它做到的效果就是禁止调度到带了 key: k1 标签的 Pod 所在节点,不管 values 是什么值,只要带了 k1 这个 key 标签的 Pod 所在节点,都不能调度过去。
pod yaml 里面声明了刚才我们创建出来的 PVC 对象,然后把它挂载到 nas-container 容器中的 /data 下面。我们这个 pod 是通过前面课程中讲解 deployment 创建两个副本,通过反亲和性,将两个副本调度在不同的 node 上面。
以上就是 Pod 与 Pod 之间的关系调度。
调度亲和性 Pod亲和性 实战
pod.spec.affinity.podAffinity/podAntiAffinity
- preferedDuringSchedulingIgnoredDuringExecution:软策略
- 软策略是偏向于,更想(不)落在某个节点上,但如果实在没有,落在其他节点也可以
- requiredDuringSchedulingIgnoredDuringExecution:硬策略
- 硬策略是必须(不)落在指定的节点上,如果不符合条件,则一直处于Pending状态
先创建一个测试Pod
[root@k8s-master ~]# kubectl apply -f pod.yaml
pod/pod-1 created
[root@k8s-master ~]# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-1
labels:
app: nginx
type: web
spec:
containers:
- name: pod-1
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: web
containerPort: 80
[root@k8s-master ~]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-1 1/1 Running 0 72s app=nginx,type=web
requiredDuringSchedulingIgnoredDuringExecution Pod硬策略
[root@k8s-master ~]# cat pod-affinity-required.yaml
apiVersion: v1
kind: Pod
metadata:
name: affinity-required
labels:
app: pod-3
spec:
containers:
- name: with-pod-required
image: nginx:1.2.1
imagePullPolicy: IfNotPresent
affinity:
podAffinity: #在同一域下
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app #标签key
operator: In
values:
- nginx #标签value
topologyKey: kubernetes.io/hostname #域的标准为node节点的名称
[root@k8s-master ~]# kubectl apply -f pod-affinity-required.yaml
pod/affinity-required created
以上文件策略为:此Pod必须要和包含label为app:nginx的pod在同一node下
[root@k8s-master ~]# kubectl get pod -o wide --show-labels
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
affinity-required 1/1 Running 0 3m7s 10.244.0.19 k8s-master <none> <none> app=pod-3
pod-1 1/1 Running 0 7m37s 10.244.0.18 k8s-master <none> <none> app=nginx,type=web
和此标签的Pod在同一node节点下
将podAffinity改为podAnitAffinity,使它们不在用于node节点下
[root@k8s-master ~]# cat pod-affinity-required.yaml
apiVersion: v1
kind: Pod
metadata:
name: required-pod2
labels:
app: pod-3
spec:
containers:
- name: with-pod-required
image: nginx
imagePullPolicy: IfNotPresent
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app #标签key
operator: In
values:
- nginx #标签value
topologyKey: kubernetes.io/hostname #域的标准为node节点的名称
[root@k8s-master ~]# kubectl get pod -o wide --show-labels
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
pod-1 1/1 Running 0 15m 10.244.0.18 k8s-master <none> <none> app=nginx,type=web
required-pod2 1/1 Running 0 2m2s 10.244.1.7 k8s-node1 <none> <none> app=pod-3
此策略表示,必须要和label为app:nginx的pod在不同的node节点上
preferedDuringSchedulingIgnoredDuringExecution Pod软策略
vim pod-affinity-prefered.yaml
apiVersion: v1
kind: Pod
metadata:
name: affinity-prefered
labels:
app: pod-3
spec:
containers:
- name: with-pod-prefered
image: nginx:v1
imagePullPolicy: IfNotPresent
affinity:
podAntiAffinity: #不在同一个域下
preferedDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- pod-2
topologyKey: kubernetes.io/hostname
软策略和硬策略的方法基本类似,只是添加了权重,表示更喜欢而已,也可以接受其他,在此就不再演示