11.3.k8s中pod的调度-亲和affinity,反亲和antAffinity
在K8S中,亲和性(Affinity)用来定义Pod与节点关系的概念,亲和性通过指定标签选择器和拓扑域约束来决定 Pod 应该调度到哪些节点上。与污点相反,它主要是尽量往某节点靠。在k8s当中,“亲和性”分为三种,节点亲和性、pod亲和性、pod反亲和性;
·
目录
一、概念
在K8S中,亲和性(Affinity)用来定义Pod与节点关系的概念,亲和性通过指定标签选择器和拓扑域约束来决定 Pod 应该调度到哪些节点上。与污点相反,它主要是尽量往某节点靠。
关键点是标签label
在k8s当中,“亲和性”分为三种,节点亲和性、pod亲和性、pod反亲和性;
亲和性分类 | 名称 | 解释说明 |
nodeAffinity | 节点亲和性 | 通过【节点】标签匹配,用于控制pod调度到哪些node节点上,以及不能调度到哪些node节点上;(主角node节点) |
podAffinity | pod亲和性 | 通过【节点+pod】标签匹配,可以和哪些pod部署在同一个节点上(拓扑域);(主角是pod) |
podAntiAffinity | pod反亲和性 | 通过【节点+pod】标签匹配,与pod亲和性相反,就是和那些pod不在一个节点上(拓扑域); |
二、nodeAffinity-节点亲和性
- 亲和与反亲和。nodeSelector 提供了一种非常简单的方法来将 pod 约束到具有特定标签的节点上。亲和/反亲和功能极大地扩展了你可以表达约束的类型。
- 你可以发现规则是“软”/“偏好”,而不是硬性要求,因此,如果调度器无法满足该要求,仍然调度该 pod
- 你可以使用节点上的 pod 的标签来约束,而不是使用节点本身的标签,来允许哪些 pod 可以或者不可以被放置在一起。
- 节点亲和(仅作用于调度期间)
- requiredDuringSchedulingIgnoredDuringExecution 必须满足
- preferredDuringSchedulingIgnoredDuringExecution 倾向满足
- IgnoreDuringExecution 表示如果在Pod运行期间Node的标签发生变化,导致亲和性策略不能满足,则继续运行当前的Pod。
- nodeaffinity还支持多种规则匹配条件的配置如
- In:label 的值在列表内
- NotIn:label 的值不在列表内
- Gt:label 的值大于设置的值,不支持Pod亲和性
- Lt:label 的值小于设置的值,不支持pod亲和性
- Exists:设置的label 存在
- DoesNotExist:设置的 label 不存在
1.给k8s节点创建标签
[root@k8s1 ~]# kubectl label nodes k8s1 k8s=oslee1
node/k8s1 labeled
[root@k8s1 ~]# kubectl label nodes k8s2 k8s=oslee2
node/k8s2 labeled
# 查看标签
[root@k8s1 ~]# kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
k8s1 Ready control-plane,master 5d12h v1.23.17 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,k8s=oslee1,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s1,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=,node=k8s1,os=lee
k8s2 Ready <none> 5d12h v1.23.17 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,k8s=oslee2,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s2,kubernetes.io/os=linux,node=k8s2,os=lee
2.编辑资源清单设置节点亲和性
[root@k8s1 deploy]# cat deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: dm-affinity
spec:
replicas: 20
selector:
matchLabels:
k8s: oslee
template:
metadata:
name: pod-affinity
labels:
k8s: oslee
spec:
#声明亲和性
affinity:
#声明亲和性类型
nodeAffinity:
#硬亲和力,即支持必须部署在指定的节点上,也支持必须不部署在指定的节点上(不满足下面的条件,亲和性就设置失败)
requiredDuringSchedulingIgnoredDuringExecution:
#设置节点选择器列表:
nodeSelectorTerms:
#声明基于节点的标签进行关联
- matchExpressions:
- key: k8s
values:
- oslee1
- oslee2
#设置key和value的关系;
#--In:key==value(必须写value)
#--NotIn:key !=value(必须写value)
operator: In
#软亲和力:尽量部署在满足条件的节点上,或尽量不要部署在被匹配的节点上
preferredDuringSchedulingIgnoredDuringExecution:
#配置权重
- weight: 1
#偏向性
preference:
#基于节点的标签进行关联
matchExpressions:
#节点的标签名称
- key: k8s
values:
# 硬亲和力设置了oslee1和oslee2,软亲和力使尽量在oslee1上
- oslee1
#关联关系,表示key和values的关系
#In:表示包含关系(value必须写),部署在满足条件的节点上
#NotIn:表示不包含(value必须写),匹配不在条件中的节点,实现节点反亲和性
#Exists: 表示存在关系(只要存在 key 名字就可以,不能写value)
#DoesNotExist:不存在(不能写value),实现节点反亲和性
#Gt:大于(value 为数值,大于节点上的值)
#Lt:小于(value 为数值,小于节点上的值)
operator: In
containers:
- name: c1
image: nginx:1.20.1-alpine
ports:
- containerPort: 80
[root@k8s1 deploy]# kubectl apply -f deploy.yaml
deployment.apps/dm-affinity created
3.查看pod所在节点,验证亲和性
[root@k8s1 deploy]# kubectl get all -owide
三、podAffinity-pod的亲和性
基于“节点标签”进行设置,第一个pod副本创建在了哪个节点上,那么其余副本也会创建在这个节点上;
拓扑域:节点机器的标签的key和value都相等的机器,就是同一个拓扑域;
1.编辑资源清单设置pod亲和性
apiVersion: apps/v1
kind: Deployment
metadata:
name: dm-affinity
spec:
replicas: 20
selector:
matchLabels:
k8s: oslee
template:
metadata:
name: pod-affinity
labels:
k8s: oslee
spec:
#声明亲和性
affinity:
#声明亲和性类型
podAffinity:
#硬限制,必须满足的条件有哪些?(不满足下面的条件,亲和性就设置失败)
requiredDuringSchedulingIgnoredDuringExecution:
#设置拓扑域,指定【节点的标签名】
#【节点key】就是说,设置了拓扑域,pod就会往这个标签的节点进行创建
#只要满足key是k8s的节点的标签,那么就是同一个拓扑域
- topologyKey: k8s
#【pod标签】确定pod的标签,用于二次确认,选中了拓扑域(节点标签的key),再次选中pod标签才能确认调度到哪个节点;
labelSelector:
matchExpressions:
#意思是说,只要key的值是k8s的pod创建在了哪个节点,“我”就跟随他。也创建在这个节点上;
- key: k8s
#如果pod标签,出现了key值相同,value值不同的情况下,就不见设置Exists存在的关系了
#建议设置:In的方式进行匹配,当然此时Value就不能设置了;
operator: Exists
containers:
- name: c1
image: nginx:1.20.1-alpine
ports:
- containerPort: 80
[root@k8s1 deploy]# kubectl apply -f deploy.yaml
deployment.apps/dm-affinity created
2.查看pod所在节点
四、podAntAffinity-pod的反亲和性
pod的亲和性:符合拓扑域的范围,指定标签的pod创建在哪里,其他pod就创建在哪里;
pod的反亲和性:与之相反,符合拓扑域的范围,指定标签的pod创建在哪里,其他pod就不能创建在哪里;
[root@k8s1 deploy]# cat deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: dm-affinity
spec:
replicas: 4
selector:
matchLabels:
k8s: oslee
template:
metadata:
name: pod-affinity
labels:
k8s: oslee
spec:
#声明亲和性
affinity:
#声明亲和性类型
podAntiAffinity:
#硬限制,必须满足的条件有哪些?(不满足下面的条件,亲和性就设置失败)
requiredDuringSchedulingIgnoredDuringExecution:
#设置拓扑域,指定【节点的标签名】
#【节点key】就是说,设置了拓扑域,pod就会往这个标签的节点进行创建
- topologyKey: k8s
#【pod标签】确定pod的标签,用于二次确认,选中了拓扑域(节点标签的key),再次选中pod标签才能确认调度到哪个节点;
labelSelector:
matchExpressions:
- key: k8s
#如果pod标签,出现了key值相同,value值不同的情况下,就不见设置Exists存在的关系了
#建议设置:In的方式进行匹配,当然此时Value就不能设置了;
operator: Exists
containers:
- name: c1
image: nginx:1.20.1-alpine
ports:
- containerPort: 80
[root@k8s1 deploy]# kubectl apply -f deploy.yaml
deployment.apps/dm-affinity created
[root@k8s1 deploy]# kubectl get all -owide
结论:
- 由于第一pod创建在了k8s1,所以第二个pod就无法再k8s1中创建;
- 第二个pod就再k8s2中创建了;
- 由于我们是4个副本,只有两个节点,pod3和pod4没法创建了;
==============================至此,已成艺术===============================
更多推荐
已为社区贡献25条内容
所有评论(0)