深入理解Pod对象:调度
创建一个Pod的工作流程
Kubernetes基于list-watch机制的控制器架构,实现组件间交 互的解耦。 其他组件监控自己负责的资源,当这些资源发生变化时,kubeapiserver会通知这些组件,这个过程类似于发布与订阅。

Pod中影响调度的主要属性

资源限制对Pod调度的影响
容器资源限制:
- 
resources.limits.cpu
 - 
resources.limits.memory
 
容器使用的最小资源需求,作为容器调度时资 源分配的依据:
- 
resources.requests.cpu
 - 
resources.requests.memory
 
CPU单位:可以写m也可以写浮点数,例如0.5=500m,1=1000m

K8s会根据Request的值去查找有足够资源的Node来调度此Pod
vim pod-resources.yaml
apiVersion: v1  | 
kubectl apply -f pod-resources.yaml  | 
nodeSelector & nodeAffinity
nodeSelector:用于将Pod调度到匹配Label的Node上,如果没有匹配的标签会调度失败。
作用:
- 
约束Pod到特定的节点运行
 - 
完全匹配节点标签
 
应用场景:
- 
专用节点:根据业务线将Node分组管理
 - 
配备特殊硬件:部分Node配有SSD硬盘、GPU
 
示例:确保Pod分配到具有SSD硬盘的节点上
第一步:给节点添加标签
格式:kubectl label nodes <node-name> <label-key>=<label-value>  | 

第二步:添加nodeSelector字段到Pod配置中
vim pod-selector.yaml
apiVersion: v1  | 
最后,验证:
kubectl apply -f pod-selector.yaml  | 

示例:使Pod分配到gpu是NVIDIA的节点上,k8s节点中并没有这个标签的节点
vim pod-selector2.yaml
apiVersion: v1  | 
验证:
kubectl apply -f pod-selector2.yaml  | 


nodeAffinity:节点亲和性,与nodeSelector作用一样,但相比 更灵活,满足更多条件,诸如:
- 
匹配有更多的逻辑组合,不只是字符串的完全相等
 - 
调度分为软策略和硬策略,而不是硬性要求
 - 
硬(required):必须满足
 - 
软(preferred):尝试满足,但不保证
 
操作符:In、NotIn、Exists、DoesNotExist、Gt、Lt
示例:在pod满足硬性标签要求的前提下,如果没有满足其他的标签,则在满足硬性标签要求的机器上随机调度分配一台
vim pod-affinity.yaml
apiVersion: v1  | 
kubectl apply -f pod-affinity.yaml  | 

验证:
1.如果两个节点都满足硬性标签要求,其中一个节点也满足软性标签要求,那么会优先分配到这个节点。
2.如果两个节点都满足硬性标签要求,都没有满足软性标签要求,那么会随机调度到其中的一个节点。
#给节点添加标签的命令  | 
Taint(污点)与Tolerations(污点容忍)
Taints:避免Pod调度到特定Node上
Tolerations:允许Pod调度到持有Taints的Node上
应用场景:
- 
专用节点:根据业务线将Node分组管理,希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配
 - 
配备特殊硬件:部分Node配有SSD硬盘、GPU,希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配
 - 
基于Taint的驱逐
 
第一步:给节点添加污点
格式:kubectl taint node [node] key=value:[effect]  | 
其中[effect] 可取值:
- 
NoSchedule :一定不能被调度
 - 
PreferNoSchedule:尽量不要调度,非必须配置容忍
 - 
NoExecute:不仅不会调度,还会驱逐Node上已有的Pod
 
第二步:添加污点容忍(tolrations)字段到Pod配置中

去掉污点:
kubectl taint node [node] key:[effect]-  | 
示例一
1.给node节点添加标签
kubectl label nodes k8s-node1 gpu=iniaid  | 
2.给node1节点配置污点
kubectl taint node k8s-node1 gpu=iniaid:NoSchedule  | 
3.新建pod2.yaml文件并启动pod
vim pod2.yaml
apiVersion: v1  | 
4.验证
kubectl apply -f pod2.yaml  | 
示例二
1.基于示例一,给node2节点配置污点
kubectl taint node k8s-node2 disktype=ssd:NoSchedule  | 
2.新建pod3.yaml文件并启动pod
vim pod3.yaml
apiVersion: v1  | 
3.验证
kubectl apply -f pod3.yaml  | 

上面的意思是默认计划程序0/3个节点可用:1个节点有污点{disktype:ssd},pod不能容忍,1个节点有污点{gpu:iniaid},pod不能容忍,1个节点有污点{node}-role.kubernetes.io/主。
示例三
1.基于示例二,添加污点容忍使pod能够分配到node1节点上
vim pod4.yaml
apiVersion: v1  | 
加上effect: "NoSchedule"的意思:更精确一点,如果不加的话,比如两个节点都有gpu=iniaid这个标签,但它们的effect的调度策略不同,那么pod可能会分配到这两个节点上。
2.验证
kubectl apply -f pod4.yaml  | 

最后去掉污点
kubectl describe nodes |grep Taint #查看当前有污点的节点  | 
验证pod3是否被调度成功

nodeName
nodeName:指定节点名称,用于将Pod调度到指定的Node上,不经过调度器
示例:将pod指定到有污点的节点上
vim pod5.yaml
apiVersion: v1  | 
验证:
kubectl apply -f pod5.yaml  | 
适用于调度器故障的时候,可以手动指定分配pod到某个节点上,很少使用。
