node节点选择器
我们在创建pod资源的时候,pod会根据schduler进行调度,那么默认会调度到随机的一个工作节点,如果我们想要pod调度到指定节点或者调度到一些具有相同特点的node节点,可以使用pod中的nodeName或者nodeSelector字段指定要调度到的node节点。
手动干预pod运行在node2节点上
nodeName 指定pod节点运行在哪个具体node上
vim pod1.yml

kubectl apply -f pod1.yml
nodeSelector 指定pod调度到具有哪些标签的node节点上
vim pod1.yml

给 k8s-node2 这个节点 打标签:kubectl label nodes k8s-node2 worker=node2
kubectl apply -f pod1.yml

Pod亲和性
生产上为了保证应用的高可用性,需要将同一应用的不同pod分散在不同的宿主机上,以防宿主机出现宕机等情况导致pod重建,影响到业务的连续性。要想实现这样的效果,需要用到k8s自带的pod亲和性和反亲和性特性。
**requiredDuringSchedulingIgnoredDuringExecution ##一定满足
preferredDuringSchedulingIgnoredDuringExecution ##尽量满足**
**podAffinity(亲和性):** pod和pod更倾向腻在一起,把相近的pod结合到相近的位置,如同一区域,同一机架,这样的话pod和pod之间更好通信,比方说有两个机房,这两个机房部署的集群有1000台主机,那么我们希望把nginx和tomcat都部署同一个地方的node节点上,可以提高通信效率;
**podAntiAffinity(反亲和性):** pod和pod更倾向不腻在一起,如果部署两套程序,那么这两套程序更倾向于反亲和性,这样相互之间不会有影响。
第一个pod随机选则一个节点,做为评判后续的pod能否到达这个pod所在的节点上的运行方式,这就称为pod亲和性;我们怎么判定哪些节点是相同位置的,哪些节点是不同位置的;我们在定义pod亲和性时需要有一个前提,哪些pod在同一个位置,哪些pod不在同一个位置,这个位置是怎么定义的,标准是什么?以节点名称为标准,这个节点名称相同的表示是同一个位置,节点名称不相同的表示不是一个位置。
kubectl explain pod.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution.labelSelector
解释 Pod 亲和性(podAffinity) 里,强制调度规则 下 labelSelector 标签选择器有哪些字段、怎么写、含义是什么。
vim pod-first.yml

kubectl apply -f pod-first.yml
vim pod-second.yml(一定满足)

kubectl apply -f pod-second.yml
创建 一定不满足
vim pod-three.yml

kubectl apply -f pod-three.yml

换一个topologykey
kubectl label nodes k8s-node2 zone=foo

在topoligykey不是zone的节点上运行

污点与容忍
前面介绍了节点亲和性调度,它可以使得我们的Pod调度到指定的Node节点上,而污点(Taints)与之相反,它可以让Node拒绝Pod的运行,甚至驱逐已经在该Node上运行的Pod
污点是Node上设置的一个属性,通常设置污点表示该节点有问题,比如磁盘要满了,资源不足,或者该Node正在升级暂时不能提供使用等情况,这时不希望再有新的Pod进来,这个时候就可以给该节点设置一个污点。
但是有的时候其实Node节点并没有故障,只是不想让一些Pod调度进来,比如这台节点磁盘空间比较大,希望是像Elasticsearch、Minio这样需要较大磁盘空间的Pod才调度进来,那么就可以给节点设置一个污点,给Pod设置容忍(Tolerations)对应污点,如果再配合节点亲和性功能还可以达到独占节点的效果
一般时候 Taints 总是与 Tolerations配合使用
查看污点:kubectl get nodes k8s-master -o go-template={{.spec.taints}}
污点类别
NoSchedule: 如果没有容忍该污点就不能调度进来。
PreferNoSchedule: 相当于NoExecute的一个软限制,如果没有容忍该污点,尽量不要把Pod调度进来,但也不是强制的。
NoExecute: 如果没有设置容忍该污点,新的Pod肯定不会调度进来, 并且已经在运行的Pod没有容忍该污点也会被驱逐。(pod被驱逐后不会自动安置,不要随意设置)
设置污点并不允许Pod调度到该节点
$ kubectl taint node k8s-node1 key=value:NoSchedule
设置污点尽量不要让Pod调度到该节点
$ kubectl taint node k8s-node1 key=value:PreferNoSchedule
设置污点,不允许Pod调度到该节点,并且且将该节点上没有容忍该污点的Pod将进行驱逐
$ kubectl taint node k8s-node1 key=value:NoExecute
(!! key和valuw的位置都是要设置值的,要有意义)
删除该key的所有污点
$ kubectl taint node k8s-node1 key-
删除该key的某一个污点
$ kubectl taint node k8s-node1 key=value:NoSchedule-
删除该key的某一个污点可以不写value
$ kubectl taint node k8s-node1 key:NoSchedule-
(!!key和valuw的位置都要写当前的key和valuw值)
容忍(Toletations)
如果需要Pod忽略Node上的污点,就需要给Pod设置容忍,并且是需要容忍该Pod上的所有污点。
通过 kubectl explain pod.spec.tolerations 可以查看容忍的配置项
tolerations: # 数组类型,可以设置多个容忍
- key: # 污点key
operator: # 操作符,有两个选项 Exists and Equal 默认是Equal
value: # 污点value,如果使用Equal需要设置,如果是Exists就不需要设置
effect: # 可以设置为NoSchedule、PreferNoSchedule、NoExecute,如果为空表示匹配该key下所有污点,
tolerationSeconds: # 如果污点类型为NoExecute,还可以设置一个时间,表示这一个时间段内Pod不会被驱逐,过了这个时间段会立刻驱逐,0或者负数会被立刻驱逐


Equal 与 Exists
Exists 表示key是否存在所以无需设置value,Equal 则必须设置value需要完全匹配,默认为Equal
空的key配合Exists 可以匹配所有的key-value,也就是容忍所有的污点,生产上非常不建议使用