kubernetes中pod的调度亲和性affinity详解
作者:尘小新
本文简要介绍了Kubernetes中的三种亲和性机制:节点亲和性(控制Pod调度到指定节点)、Pod亲和性(与特定Pod共处同一节点)和Pod反亲和性(避免与特定Pod共处同一节点),并通过示例说明了其配置方式及实际调度效果
一、概述
在k8s当中,“亲和性”分为三种,节点亲和性、pod亲和性、pod反亲和性;
亲和性分类 | 名称 | 解释说明 |
---|---|---|
nodeAffinity | 节点亲和性 | 通过【节点】标签匹配,用于控制pod调度到哪些node节点上,以及不能调度到哪些node节点上;(主角node节点) |
podAffinity | pod亲和性 | 通过【节点+pod】标签匹配,可以和哪些pod部署在同一个节点上(拓扑域);(主角是pod) |
podAntiAffinity | pod反亲和性 | 通过【节点+pod】标签匹配,与pod亲和性相反,就是和那些pod不在一个节点上(拓扑域); |
二、nodeAffinity节点亲和性
1. 给节点打上标签
[root@master ~]# kubectl label nodes master k8s=master
查看三个节点的标签,分别拥有k8s=master,k8s=node1,k8s=node2标签
2.编辑资源清单设置节点亲和性
测试前把我们资源都删除掉
[root@master ~]# kubectl delete pod,svc,deploy --all pod "taint-demo-58f97cc65c-4nhvs" deleted pod "taint-demo-58f97cc65c-lh55g" deleted pod "taint-demo-58f97cc65c-smjd5" deleted pod "taint-demo-58f97cc65c-tr9th" deleted pod "taint-demo-58f97cc65c-tsvdp" deleted service "kubernetes" deleted deployment.apps "taint-demo" deleted
编辑资源清单
ot@master deployment-demo]# cat dm-affinity.yaml apiVersion: apps/v1 kind: Deployment metadata: name: dm-affinity spec: replicas: 20 selector: matchLabels: k8s: dolphin template: metadata: name: pod01 labels: k8s: dolphin spec: affinity: #声明亲和性 nodeAffinity: #声明亲和性类型 requiredDuringSchedulingIgnoredDuringExecution: #硬限制,必须满足的条件有哪些(不满足下边的条件亲和性就设置失败) nodeSelectorTerms: #设置节点选择器列表 - matchExpressions: - key: k8s values: - node1 - node2 operator: In preferredDuringSchedulingIgnoredDuringExecution: #软限制,不一定满足,但会优先满足,相当于调高了调度到优先级 - weight: 10 #配置权重 preference: #偏向性 matchExpressions: - key: k8s values: - node1 #关联关系,表示key和values的关系 #In:表示包含关系(value必须写) #NotIn:表示不包含(value必须写) #Exists: 表示存在关系(不能写value) #DoesNotExist:不存在(不能写value) #Gt:大于(value必须是一个单一的元素,且值将被解释称一个整数) #Lt:小于(value必须是一个单一的元素,且值将被解释称一个整数) operator: In containers: - name: c1 image: nginx ports: - containerPort: 80
3.查看资源验证亲和性
我们可以看到,创建的20个Pod只有一个被调度到node2上,上边节点调度更亲和节点1
三、podAffinity pod亲和性
基于“节点标签”进行设置,第一个pod副本创建在了哪个节点上,那么其余副本也会创建在这个节点上;
拓扑域:节点机器的标签的key和value都相等的机器,就是同一个拓扑域;
1. 编辑资源清单设置pod亲和性
[root@master deployment-demo]# cat dm-affinity.yaml apiVersion: apps/v1 kind: Deployment metadata: name: dm-affinity spec: replicas: 20 selector: matchLabels: k8s: dolphin template: metadata: name: pod01 labels: k8s: dolphin spec: affinity: #声明亲和性 podAffinity: #声明亲和性类型 requiredDuringSchedulingIgnoredDuringExecution: #硬限制,必须满足的条件有哪些(不满足下边的条件亲和性就设置失败) #设置拓扑域,指定【节点的标签名】 #【节点key】就是说,设置了拓扑域,pod就会往这个标签的节点进行创建 # 只要满足key是k8s节点的表情,那么就是同一个拓扑域 - topologyKey: k8s # 【pod标签】确定pod的表情,用于二次确认,选中了拓扑域(节点标签的key),再次选中pod标签才能确认调度到哪个节点 labelSelector: matchExpressions: #意思是是说,只要key的值是k8s的pod创建在了哪个节点,“我”就跟随他。也创建在这个节点上; - key: k8s #建议设置:in的方式进行匹配,更精准,就要设置value了 operator: Exists # Exists的方式进行匹配,这里value就不能设置了 containers: - name: c1 image: nginx ports: - containerPort: 80
2、创建资源
[root@master deployment-demo]# kubectl apply -f dm-affinity.yaml
3、查看结果
都运行在了node1节点上
四、podAntAffinity-pod的反亲和性
- pod的亲和性:符合拓扑域的范围,指定标签的pod创建在哪里,其他pod就创建在哪里;
- pod的反亲和性:与之相反,符合拓扑域的范围,指定标签的pod创建在哪里,其他pod就不能创建在哪里;
1、编辑资源清单
亲和性和反亲和性的配置就下边一个标红差别,其它配置几乎一样
[root@master deployment-demo]# cat dm-affinity.yaml apiVersion: apps/v1 kind: Deployment metadata: name: dm-affinity spec: replicas: 5 selector: matchLabels: k8s: dolphin template: metadata: name: pod01 labels: k8s: dolphin spec: affinity: #声明亲和性 podAntiAffinity: #声明亲和性类型 requiredDuringSchedulingIgnoredDuringExecution: #硬限制,必须满足的条件有哪些(不满足下边的条件亲和性就设置失败) #设置拓扑域,指定【节点的标签名】 #【节点key】就是说,设置了拓扑域,pod就会往这个标签的节点进行创建 # 只要满足key是k8s节点的表情,那么就是同一个拓扑域 - topologyKey: k8s # 【pod标签】确定pod的表情,用于二次确认,选中了拓扑域(节点标签的key),再次选中pod标签才能确认调度到哪个节点 labelSelector: matchExpressions: #意思是是说,只要key的值是k8s的pod创建在了哪个节点,“我”就跟随他。也创建在这个节点上; - key: k8s #建议设置:in的方式进行匹配,更精准,就要设置value了 operator: Exists # Exists的方式进行匹配,这里value就不能设置了 containers: - name: c1 image: nginx ports: - containerPort: 80
2、创建资源
[root@master deployment-demo]# kubectl apply -f dm-affinity.yaml
3、查看结果
因为我们集群中只有2个节点可分配资源,所以我们可以看到上图有2个pod资源被分配在不同节点上。
其它三个因为节点都被占用了,根据反亲和性特点,余下的有“k8s”这个标签pod不会再创建在这两个节点上了,所以一直处于Peding状态。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。