深入理解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到某个节点上,很少使用。