
亲和性 反亲和性 污点 容忍
1.nodeSelector
nodeSelector:用于将Pod调度到匹配Label的Node上,如果没有匹配的标签会调度失败
作用:
- 约束Pod到特定的节点运行
- 完全匹配节点标签
应用场景:
- 专用节点:根据业务线将Node分组管理
- 配备特殊硬件:部分Node配有SSD硬盘、GPU
需求
确保Pod分配到具有SSD硬盘的节点
查看标签
# kubectl get node --show-labels给节点打上标签
# kubectl label node cka-node1 disktype=ssd添加nodeSelector字段到Pod配置中
# kubectl run pod1 --image=nginx --dry-run=client -o yaml > /tmp/pod1.yaml #cat pod1.yaml apiVersion: v1 kind: Pod metadata: labels: run: pod1 name: pod1 spec: nodeSelector: disktype: "ssd" containers: - image: nginx name: pod1 resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {}验证
# kubectl get pods -o wide排错
# kubectl describe pod pod2 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 16s default-scheduler 0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 node(s) didn't match Pod's node affinity/selector. Warning FailedScheduling 14s default-scheduler 0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 node(s) didn't match Pod's node affinity/selector.删除Node标签
# kubectl label node cka-node1 disktype-
2.亲和性调度
nodeAffinity:节点亲和性
podAffinity:pod 亲和性
podAntiAffinity:pod 反亲和性
preferredDuringSchedulingIgnoredDuringExecution:软策略
requiredDuringSchedulingIgnoredDuringExecution:硬策略
在默认的K8S调度中,一般经过预选和优选即可完成调度,但是生产的实际使用中,考虑到部分业务的特殊性,一般会手动进行一些"指定", K8S 把这些"指定"分为nodeAffinity(节点亲和性)、podAffinity(pod 亲和性) 以及 podAntiAffinity(pod 反亲和性), 这在调度过程中,称之为亲和性调度
亲和性调度可以分成软策略(preferredDuringSchedulingIgnoredDuringExecution )和硬策略(requiredDuringSchedulingIgnoredDuringExecution)两种方式,软策略意思是如果现在没有满足调度要求要求的话,那就跳过这条策略,继续调度,总结起来就是"有则用之,无则跳过", 而硬策略相对就强硬很多,如果不满足调度策略,则不停重试,直到满足策略。
3.nodeAffinity
nodeAffinity: 节点亲和类似于nodeSelector,可以根据节点上的标签来约束Pod可以调度到哪些节点
pod 有podAffinity和podAntiAffinity,但是node 却只有nodeAffinity,这是因为operator , operator 是匹配表达式的操作符,nodeAffinity支持In, NotIn, Exists, DoesNotExist, Gt和Lt,所以想支持"nodeAntiAffinity"只要operator使用NotIn或者DoesNotExist就可以实现了。
相比nodeSelector:
- 匹配有更多的逻辑组合,不只是字符串的完全相等,支持的操作符有:
In、NotIn、Exists、DoesNotExist、Gt、Lt- 调度分为软策略和硬策略,而不是硬性要求
- 硬(required):必须满足
- 软(preferred):尝试满足,但不保证
可以添加多个策略
apiVersion: v1 kind: Pod metadata: name: with-node-affinity spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/e2e-az-name operator: In values: - e2e-az1 - e2e-az2 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: another-node-label-key operator: In values: - another-node-label-value containers: - name: with-node-affinity image: k8s.gcr.io/pause:2.0.
4.pod亲和性和反亲和性
podAffinity和podAntiAffinity:
1.podAffinity
- topologyKey
podAffinity的operator支持In, NotIn, Exists, DoseNotExit。
相对nodeAffinity,podAffinity多了一个topologyKey,topologyKey可以理解为拓扑域,在yaml里的意思是调度需要对应的node有对应的标签,而不关心这个label对应的值。
假设反topologykey是idc的维度,公司有北京上海2个idc,pod的副本数量为2,那么pod在完成了topologykey-idc=beijing之后,根据podAntiAffinity的策略,则不会在同样个zone的topologykey在创建了,而会创建在shanghai,从而做到了IDC的均衡部署。
2.podAntiAffinity
Pod 反亲和性(podAntiAffinity)则是反着来的,比如一个节点上运行了某个 Pod,那么我们的模板 Pod 则不希望被调度到这个节点上面去了。
5.污点和容忍
亲和性和反亲和性的作用是为了让pod可以根据需要调度到自己像分配的一个或者一组node上,污点的作用其实就是反过来,就是给node打上一个特殊的标签,让该node不再被分配pod,除非该pod容忍了该污点。假设有服务器硬件发生了预告警,或者服务器维保到期需要预下线,那么从服务器等待维护/预下线到真正服务器不在提供服务的周期里,该node不会被调度。
taints:避免Pod调度到特定Node上
effect 支持以下3种:
- NoSchedule //不会将 Pod 调度到有污点的 Node
- PreferNoSchedule //避免将 Pod 调度到有污点的 Node
- NoExecute //不会将 Pod 调度到有污点的 Node, 将已经存在的 Pod 驱逐出去
添加污点
格式:
kubectl taint node [node] key=value:[effect]示例:
#kubectl taint node cka-node2 memtype=samsung:NoSchedule node/cka-node2 tainted验证:
#kubectl describe node cka-node2 | grep Taint Taints: memtype=samsung:NoSchedule去掉污点
#kubectl taint node cka-node2 memtype:NoSchedule- node/cka-node2 untaintedtolerations:允许Pod调度到持有Taints的Node上
假设NodeA存在"node-role.kubernetes.io/maintenance"的标签,该pod可以容忍NoSchedule的污点。容忍存在以下默认场景:
- 如果不指定 operator 属性,则operator默认值为 Equal
- 空的 key 如果再配合 Exists 就能匹配所有的 key 与 value,也就是能容忍所有节点的所有 Taints
- 空的 effect 匹配所有的 effect
- 如果需要容忍多个污点,就写多个-key:–effect的过滤策略即可。
#cat tolrations.yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: tolrations name: tolrations spec: tolerations: - key: memtype operator: "Equal" value: "samsung" effect: "NoSchedule" containers: - image: nginx name: tolrations dnsPolicy: ClusterFirst restartPolicy: Always status: {}应用场景:
- 专用节点,根据业务线将Node分组管理,希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配
- 配备特殊硬件,部分Node配有SSD硬盘、GPU、希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配
- 基于Taint的驱逐
6.调度失败原因分析
查看调度结果:
kubectl get pod <NAME> -o wide查看调度失败原因
kubect describe pod <NAME>
- 节点CPU/内存不足
- 有污点,没容忍
- 没有匹配到节点标签