pod 间亲和与反亲和: pod 间亲和
与反亲和
使你可以基于已经在节点上运行的 pod 的标签来约束 pod
调度到节点上,而不是基于节点上的标签
Pod 亲和与反亲和的合法操作符有
名称 | 属性 |
---|---|
In | lable在某个列表中 |
NotIn | lable不在某个列表中 |
Exists | 某个lable存在 |
DoesNotExist | 某个lable不存在 |
注意事项:
原则上,topologyKey 可以是任何合法的标签键
。然而,出于性能和安全原因
,topologyKey受到一些限制
:
- 对于亲和与 requiredDuringSchedulingIgnoredDuringExecution(硬亲和) 要求的 pod 反亲和,
topologyKey 不允许为空
- 对于 Pod 反亲和性而言,requiredDuringSchedulingIgnoredDuringExecution 和 preferredDuringSchedulingIgnoredDuringExecution(软亲和) 中,topologyKey
都不可以为空。
- 对于 preferredDuringSchedulingIgnoredDuringExecution 要求的 pod 反亲和,空的 topologyKey 被解释为“所有拓扑结构”(这里的“所有拓扑结构”限制为 kubernetes.io/hostname,failure-domain.beta.kubernetes.io/zone 和 failure-domain.beta.kubernetes.io/region 的组合)。
- 除上述情况外,
topologyKey 可以是任何合法的标签键。
所有与 requiredDuringSchedulingIgnoredDuringExecution 亲和性与反亲和性 关联的 matchExpressions 必须满足,才能将 pod 调度到节点上
一、创建初始的Pod
vim init.yaml
apiVersion: v1
kind: Pod
metadata:
name: init-pod
labels:
app.kubernetes.io/instance: init-pod #Pod标签
spec:
containers:
- name: init-pod
image: nginx:latest
查看pod节点的标签信息
kubectl get pod --show-labels
二、Pod间硬亲和
1、创建Pod的硬亲和
vim pod-required.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-required
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 定义pod硬的亲和性
- labelSelector: #匹配pod标签中的规则
matchExpressions:
- key: app.kubernetes.io/instance #Pod的key值
operator: In #lable标签存在
values:
- init-pod #Pod的键值
topologyKey: kubernetes.io/hostname #是节点标签的键。如果两个节点使用此键标记并且具有相同的标签值。
containers:
- name: pod-required
image: nginx:latest
2、生成Pod硬亲和(调度在与init-pod的pod同一个节点)
kubectl delete -f pod-required.yaml && kubectl apply -f pod-required.yaml && kubectl get pod -o wide
3、再次创建一个不符合标签的pod,查看调度情况
cp pod-required.yaml pod-required-01.yaml
vim pod-required-01.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-required-01
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 定义pod硬的亲和性
- labelSelector: #匹配pod标签中的规则
matchExpressions:
- key: app.kubernetes.io/instance #Pod的key值
operator: In #lable标签存在
values:
- init-pod-01 #Pod的键值(不存在)
topologyKey: kubernetes.io/hostname #是节点标签的键。如果两个节点使用此键标记并且具有相同的标签值。
containers:
- name: pod-required-01
image: nginx:latest
4、生成Pod标签不符合的Pod(调度失败Pending状态)
kubectl apply -f pod-required-01.yaml && kubectl delete -f pod-required-01.yaml && kubectl apply -f pod-required-01.yaml && kubectl get pod
Pod硬亲和,当Pod标签符合进行调度到标签符合的Pod节点上,不符合的话就一直等待,资源调度系统 Scheduler 就会定时去监控 APIServer,当符合条件时候,APIServer 得到创建 Pod 的信息,Scheduler 采用 watch 机制,一旦 Etcd 存储 Pod 信息成功便会立即通知APIServer,APIServer会立即把Pod创建的消息通知Scheduler,Scheduler发现 Pod 的属性中 Dest Node 为空时(Dest Node=””)便会立即触发调度流程进行调度。
三、Pod间软亲和
1、创建Pod的软亲和
vim preferred-podaffinity.yaml
apiVersion: v1
kind: Pod
metadata:
name: preferred-podaffinity
spec:
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution: # 定义软亲和性
- weight: 1 #值越大优先级越高
podAffinityTerm:
labelSelector: #匹配pod标签中的规则
matchExpressions:
- key: app.kubernetes.io/instance #Pod的key值
operator: In #lable标签存在
values:
- init-pod #Pod的键值
topologyKey: kubernetes.io/hostname #节点内置的标签
containers:
- name: preferred-podaffinity
image: nginx:latest
2、生成Pod硬亲和(调度在与init-pod的pod同一个节点)
kubectl apply -f preferred-podaffinity.yaml && kubectl delete -f preferred-podaffinity.yaml && kubectl apply -f preferred-podaffinity.yaml && kubectl get
3、再次创建一个不符合标签的pod,查看调度情况
vim preferred-podaffinity-01.yaml
apiVersion: v1
kind: Pod
metadata:
name: preferred-podaffinity-01
spec:
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution: # 定义软亲和性
- weight: 1 #值越大优先级越高
podAffinityTerm:
labelSelector: #匹配pod标签中的规则
matchExpressions:
- key: app.kubernetes.io/instance #Pod的key值
operator: In #lable标签存在
values:
- init-pod-01 #Pod的键值(不存在)
topologyKey: kubernetes.io/hostname
containers:
- name: preferred-podaffinity-01
image: nginx:latest
5、生成Pod标签不符合的Pod(调度到优先级较高的节点)
kubectl apply -f preferred-podaffinity-01.yaml && kubectl delete -f preferred-podaffinity-01.yaml && kubectl apply -f preferred-podaffinity-01.yaml && kubectl get pod -o wide
Pod软亲和,当Pod标签符合进行调度到标签符合的Pod节点上,不符合的话选择优先级比较高的进行调度。
也可以硬软结合
apiVersion: v1
kind: Pod
metadata:
name: pod-required-preferred
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 定义pod硬的亲和性
- labelSelector: #匹配pod标签中的规则
matchExpressions:
- key: app.kubernetes.io/instance #Pod的key值
operator: In #lable标签存在
values:
- init-pod #Pod的键值
topologyKey: kubernetes.io/hostname #是节点标签的键。如果两个节点使用此键标记并且具有相同的标签值。
preferredDuringSchedulingIgnoredDuringExecution: # >定义软亲和性
- weight: 1 #值越大优先级越高
podAffinityTerm:
labelSelector: #匹配pod标签中的规则
matchExpressions:
- key: app.kubernetes.io/instance #Pod的key值
operator: In #lable标签存在
values:
- init-pod #Pod的键值
topologyKey: kubernetes.io/hostname
containers:
- name: pod-required-preferred
image: nginx:latest
四、Pod反硬亲和
1、创建Pod的反硬亲和
mkdir -p /root/kubernetes/affinity/pod/podAntiAffinity/required && cd /root/kubernetes/affinity/pod/podAntiAffinity/required
vim podantiaffinity-required.yaml
apiVersion: v1
kind: Pod
metadata:
name: podantiaffinity-required
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 定义pod硬的反亲和性
- labelSelector: #匹配pod标签中的规则
matchExpressions:
- key: app.kubernetes.io/instance #Pod的key
operator: In #lable标签存在
values:
- init-pod #Pod的键值
#namespaces: default
topologyKey: kubernetes.io/hostname #是节点标签的键
containers:
- name: podantiaffinity-required
image: nginx:latest
2、生成Pod反硬亲和(调度在与init-pod的pod不同一个节点
)
kubectl apply -f podantiaffinity-required.yaml && kubectl delete -f podantiaffinity-required.yaml && kubectl apply -f podantiaffinity-required.yaml && kubectl get po -o wide
3、可以测试下将标签匹配规则为不存在(个人不在一步步操作直接展现效果)
apiVersion: v1
kind: Pod
metadata:
name: podantiaffinity-required
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 定义pod硬的亲和性
- labelSelector:
#匹配pod标签中的规则
matchExpressions:
- key: app.kubernetes.io/instance #Pod的key
operator: In #lable标签存在
values:
- init-pod-01 #Pod的键值
topologyKey: kubernetes.io/hostname #是节点标签的键
containers:
- name: podantiaffinity-required
image: nginx:latest
4、创建Pod的反软亲和
mkdir -p /root/kubernetes/affinity/pod/podAntiAffinity/preferred && cd /root/kubernetes/affinity/pod/podAntiAffinity/preferred
vim podantiaffinity-preferred.yaml
apiVersion: v1
kind: Pod
metadata:
name: podantiaffinity-preferred
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution: # 定义反软亲和性
- weight: 1 #值越大优先级越高
podAffinityTerm:
labelSelector: #匹配pod标签中的规则
matchExpressions:
- key: app.kubernetes.io/instance #Pod的key值
operator: In #lable标签存在
values:
- init-pod #Pod的键值
topologyKey: kubernetes.io/hostname
containers:
- name: podantiaffinity-preferred
image: nginx:latest
5、生成Pod反软亲和(调度在与init-pod的pod不同节点
)
kubectl apply -f podantiaffinity-preferred.yaml && kubectl delete -f podantiaffinity-preferred.yaml && kubectl apply -f podantiaffinity-preferred.yaml && kubectl get po -o wide
6、可以测试下将标签匹配规则为不存在(不在一步步操作直接展现效果)
apiVersion: v1
kind: Pod
metadata:
name: podantiaffinity-preferred
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution: #定义反软亲和性
- weight: 1 #值越大优先级越高
podAffinityTerm:
labelSelector: #匹配pod标签中的规则
matchExpressions:
- key: app.kubernetes.io/instance #Pod的key值
operator: In #lable标签不存在
values:
- init-pods #Pod的键值
topologyKey: kubernetes.io/hostname
containers:
- name: podantiaffinity-preferred
image: nginx:latest
可自行测试 Pod反亲和 : topologyKey: failure-domain.beta.kubernetes.io/zone (同一可用区)可以测试效果如图
某些信息不便透露, 结果就是failure-domain.beta.kubernetes.io/zone 区域一致造成Pod没法调度其他不同区域。