【云原生 | 从零开始学Kubernetes十、k8sPod节点亲和性和反亲和性

Pod节点亲和性和常见的状态
- Pod 节点亲和性
- pod 节点反亲和性
- 写在最后
Pod 节点亲和性
pod 自身的亲和性调度有两种表示形式 podaffinity:pod 和 pod 更倾向腻在一起,把相近的 pod 结合到相近的位置,比如同一区域,同一机架,这样的话 pod 和 pod 之间更好通信,比方说有两个机房,这两个机房部署的集群有 1000 台主机,那么我们希望把 nginx 和 tomcat 都部署同一个地方的 node 节点上,可以提高通信效率。
podunaffinity:pod 和 pod 更倾向不腻在一起,如果部署两套程序,那么这两套程序更倾向于反亲和性,这样相互之间不会有影响。
第一个 pod 随机选则一个节点,做为评判后续的 pod 能否到达这个 pod 所在的节点上的运行方式,这就称为 pod 亲和性;我们怎么判定哪些节点是相同位置的,哪些节点是不同位置的。我们在定义 pod 亲和性时需要有一个前提,哪些 pod 在同一个位置,哪些 pod 不在同一个位置,这个位置是怎么定义的,标准是什么?以节点名称为标准,这个节点名称相同的表示是同一个位置,节点名称不相同的表示不是一个位置,或者其他方式。
[root@k8smaster ~]# kubectl explain pods.spec.affinity.podAffinity KIND: Pod VERSION: v1 RESOURCE: podAffinity
busybox如果不写sleep会自动关闭,sleep是等待多长时间。然后下面就是pod亲和性,硬亲和性,然后通过label(标签选择器选择),之前我们也通过帮助文档看过了选择器里面的字段(也可以深入看match里面有啥)
下面的key意思是选择app2=myapp2的标签做亲和性,如果不写第二个pod会找不到和哪个做亲和性。
最后一行可以直接用nodes里的已有标签来位置拓扑的键。kubectl get nodes --show-labels查看标签。
kubernetes.io/hostname标签对应的是具体的k8snode节点名,如果frist调度到node2或者node1,第二个pod也跟着调度到哪个节点(根据主机名做位置)
#上面表示创建的 pod 必须与拥有 app2=myapp2 标签的 pod 在一个节点上 [root@k8smaster ~]# kubectl apply -f pod-required-affinity-demo.yaml pod/pod-first created pod/pod-second created [root@k8smaster ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE pod-first 1/1 Running 0 26s 10.244.1.21 k8snode2pod-second 1/1 Running 0 26s 10.244.1.22 k8snode2 #上面说明第一个 pod 调度到哪,第二个 pod 也调度到哪,这就是 pod 节点亲和性 [root@k8smaster ~]# kubectl delete -f pod-required-affinity-demo.yaml pod "pod-first" deleted pod "pod-second" deleted
pod 节点反亲和性
定义两个 pod,第一个 pod 做为基准,第二个 pod 跟它调度节点相反 同样基于node名字作为基准 [root@k8smaster ~]# vim pod-required-anti-affinity-demo.yaml apiVersion: v1 kind: Pod metadata: name: pod-first labels: app1: myapp1 tier: frontend spec: containers: - name: myapp image: nginx --- apiVersion: v1 kind: Pod metadata: name: pod-second labels: app: backend tier: db spec: containers: - name: busybox image: busybox imagePullPolicy: IfNotPresent command: ["sh","-c","sleep 3600"] affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - {key: app1, operator: In, values: ["myapp1"]} topologyKey: kubernetes.io/hostname [root@k8smaster ~]# kubectl apply -f pod-required-anti-affinity-demo.yaml pod/pod-first created pod/pod-second created [root@k8smaster ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE pod-first 1/1 Running 0 21s 10.244.1.23 k8snode2pod-second 1/1 Running 0 21s 10.244.2.20 k8snode #两个 pod 不在一个 node 节点上,这就是 pod 节点反亲和性 [root@k8smaster ~]# kubectl delete -f pod-required-anti-affinity-demo.yaml pod "pod-first" deleted pod "pod-second" deleted #例3:换一个 topologykey [root@k8smaster ~]# kubectl label nodes k8snode zone=foo --overwrite node/k8snode not labeled [root@k8smaster ~]# kubectl label nodes k8snode2 zone=foo --overwrite node/k8snode2 labeled #然后去pp node 和当前目录下都删除掉k8s的pod。 [root@k8smaster pp]# kubectl delete -f . resourcequota "mem-cpu-quota" deleted pod "pod-test" deleted [root@k8smaster node]# kubectl delete -f . pod "demo-pod-1" deleted pod "demo-pod" deleted pod "pod-node-affinity-demo-2" deleted pod "pod-node-affinity-demo" deleted [root@k8smaster node]# kubectl get pods NAME READY STATUS RESTARTS AGE [root@k8smaster node]# vim pod-first-required-anti-affinity-demo-1.yaml apiVersion: v1 kind: Pod metadata: name: pod-first labels: app3: myapp3 tier: frontend spec: containers: - name: myapp image: nginx [root@k8smaster node]# vim pod-second-required-anti-affinity-demo-1.yaml apiVersion: v1 kind: Pod metadata: name: pod-second labels: app: backend tier: db spec: containers: - name: busybox image: busybox imagePullPolicy: IfNotPresent command: ["sh","-c","sleep 3600"] affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - {key: app3, operator: In, values: ["myapp3"]} topologyKey: zone #如果写在一起,可能启动顺序会有错误,比如第二个pod先启动。不管pod调度到哪个节点,都都是以zone标签作为位置。 [root@k8smaster node]# kubectl apply -f pod-first-required-anti-affinity-demo-1.yaml pod/pod-first created [root@k8smaster node]# kubectl apply -f pod-second-required-anti-affinity-demo-1.yaml pod/pod-second created [root@k8smaster node]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE pod-first 1/1 Running 0 21s 10.244.1.23 k8snode2 pod-second 0/1 pending 0 21s
第二个节点现是 pending,因为两个节点是同一个位置(因为配置了一样的zone标签,如果pod1调度到有zone标签的node上,那么第二个pod就永远不会调度到有zone标签的node上,因为我们要求的是反亲和性)现在没有不是同一个位置的了,所以就会处于 pending 状态,如果在反亲和性这个位置把 required 改成 preferred,那么也会运行。
podaffinity:pod 节点亲和性,pod 倾向于哪个 pod nodeaffinity:node 节点亲和性,pod 倾向于哪个 node
写在最后
创作不易,如果觉得内容对你有帮助,麻烦给个三连关注支持一下我!如果有错误,请在评论区指出,我会及时更改! 目前正在更新的系列:从零开始学k8s 感谢各位的观看,文章掺杂个人理解,如有错误请联系我指出~