第7章 Kubernetes调度
- 创建一个pod的工作流程
- Pod中影响调度的主要属性
- 资源限制对pod调度的影响
- nodeSelector&nodeAffnity
- Taints & Tolerations
- nodeName
- DaemonSet控制器
- 调度失败原因分析
7.1 创建一个pod的工作流程
kubernets基于list-watch机制的控制器架构,实现组件间交互的解耦。
其他组件监控自己负责的资源,当这些资源发生变化是,kube-APIServer会通知这些组件,这个过程类似于发布订阅。
1) Kubectl run 创建一个pod,将请求发送给apiserver,apiserver将数据存储到etcd中。
2) Secheduler将创建的pod根据自己的调度算法选择一个合适的节点,订一个标记NodeName=k8s-node1,返回给apiserver,存储到etcd。
3) Kubectl发现有新的pod分配到我这个了,调用docker api创建容器,并将容器状态返回给apiserver,存储到etcd
4) Kubectl get pods
Controller-manager 负责常规后台任务,例如:deployment
Kube-proxy:负责容器网络,具体service实现
7.2 Pod中影响调度的主要属性
7.3 资源限制对pod调度的影响
容器资源限制: • Resources.limits.cpu • Resources.limits.memory 容器使用的最小资源需求,作为容器调度时资源分配的依据: • Resources.requests.cpu • Resources.requests.memory CPU单位:可以写m也可以写浮点数,例如0.5=500m,1=1000m 1、资源限制,容器里应用程序使用的最大资源上限 2、资源请求值对调度的影响 1、limits 容器里应用程序使用的最大资源上限(0.5Core/500Mi) 2、requests 请求值,预留性质,不是实际占用,用于资源分配的参考值,判断node可否容纳(k8s是一个大的资源池) 3、requests 一般良性参考是小于limits的20%-30% 4、节点上limits总和不能超宿主机实际物理配置的20%,否则限制意义不大了 5、requests必须小于limits 6、当请求的值没有节点能够满足时,pod处于pendding
K8s会根据Request的值去查找有足够资源的Node来调度此Pod 实例: apiVersion: v1 kind: Pod metadata: name: resources-pod spec: containers: - name: web image: nginx resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" 验证: kubectl describe pod resources-pod kubectl describe k8s-node1 #该节点运行的pod及资源使用汇总。
7.4 nodeSelector & nodeAffinity、pod节点调度
nodeSelector:用于将pod调度到匹配label的Node上,如果没有匹配的标签会调度失败。
作用:
• 约束pod到特定的节点运行
• 完全匹配节点标签
应用场景:
• 专用节点:根据业务线将Node分组管理
• 匹配特殊硬件:部分Node配有SSD硬盘、GPU
7.4.1NodeSelector&nodeAffinity调度场景
示列:确保pod分配到具有SSD硬盘的节点上
第一步:给节点添加标签
格式:kubectl label nodes <node-name> <label-key>=<label-value>
例如:kubectl label nodes k8s-node1 disktype=ssd
验证:kubectl get nodes --show-labels
第二步:添加nodeSelector字段到Pod配置中
apiVersion: v1 kind: Pod metadata: name: my-pod spec: nodeSelector: disktype: "ssd" containers: - image: nginx:1.16 name: my-pod restartPolicy: Always 最后,验证: kubectl get pods -o wide
7.4.2nodeAffinity的软硬策略
nodeAffinity:节点亲和类似于nodeSelector,可以根据节点上的标签来约束pod可以调度到那些节点。
相比:nodeselector:
- 匹配有更多的逻辑组合,不只是字符串的完全相等,支持的操作符有:In、NotIn,Exists、DoesNotExist、Git、Lt
- In:部署在满足多个条件的节点上
- NotIn:不部署在满足这些条件的节点上
- Exists:部署在具有某个存在key为指定的值得node节点上
- DoesNotExist:和Exists相反
- Gt 大于指定的条件
- Lt小于指定的条件
- 调度分为软策略和硬策略,而不是硬性要求
硬(requireed):必须满足
软(preferred):尝试满足,但不保证
apiVersion: v1 kind: Pod metadata: name: with-node-affinity spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: gpu operator: In values: - nvidia-tesla preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: group operator: In values: - ai containers: - name: web image: nginx
7.5 Taint(污点)与Tolerations(污点容忍)
Taints:避免pod调度到特定Node上
Tokerations:允许Pod调度到特有Taints的Node上
应用场景:
• 专用节点:根据业务线将Node分组管理,希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配
• 配置特殊硬件:部分Node配置有SSD硬盘,GPU,希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配
• 基于Taint的驱逐
7.5.1pod使用污点
第一步:给节点添加污点 格式:kubectl taint node [node] key=value:[effect] 例如:kubectl taint node k8s-node1 gpu=yes:NoSchedule 验证:kubectl describe node k8s-node1 |grep Taint 删除污点:kubectl taint node k8s-node1 gpu=yes:NoSchedule- 其中【effect】可取值: • NoSchedule:一定不能被调度 • PreferNoSchedule:尽量不要调度,非必须配置容忍 • NoExecute:不仅不会调度,还会驱逐Node上已有的pod 第二步:如果希望Pod可以被分配到带有污点的节点上,要在pod配置中添加污点容忍(tolrations)字段 去除污点: Kubectl taint node [node] key:[effect]-
apiVersion: v1 kind: Pod metadata: name: pod-taints spec: containers: - name: pod-taints image: busybox:latest tolerations: - key: "gpu" operator: "Equal" value: "yes" effect: "NoSchedule"
7.6NodeName调度
nodeName:指定节点名称,用于将pod调度到指定的Node上,不经过调度器。
apiVersion: v1 kind: Pod metadata: name: nodename-pod labels: app: nginx spec: nodeName: k8s-master1 containers: - name: nginx image: nginx:1.15
7.7DaemonSet
DaemonSet功能:
• 在每一个Node上运行一个pod
• 新加入的Node也同样会自动运行一个pod
应用场景:网络插件、监控agent、日志agent
7.7.1DaemonSet示列:
示例:部署一个日志采集程序
7.8pod调度失败原因分析
查看调度结果:
kubectl get pod <NAME> -o wide
查看调度失败原因:kubectl describe pod <NAME>
• 节点CPU/内存不足
• 有污点,没容忍
• 没有匹配到节点标签
Affinity:亲和力总结
requiredDuringSchedulingIgnoredDuringExecution:硬亲和力,即支持必须部署在指定的节点上,也支持必须不部署在指定的节点上。 a=b preferredDuringSchedulingIgnoredDuringExecution:软亲和力,尽量部署在满足条件的节点上,或者是尽量不要部署在被匹配的节点。 PodAffinity: pod的亲和力 例如:A应用A应用C应用,将A应用根据某种策略尽量或者部署在一块。Label A:app=a B:app=b requiredDuringSchedulingIgnoredDuringExecution: 将A应用和B应用部署在一块 preferredDuringSchedulingIgnoredDuringExecution: 尽量将A应用和B应用部署在一块 PodAffinity:pod反亲和力 例如:A应用A应用C应用,将A应用根据某种策略尽量或者不部署在一块。Label requiredDuringSchedulingIgnoredDuringExecution: 不要将A应用与之匹配的应用部署在一块 preferredDuringSchedulingIgnoredDuringExecution: 尽量。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!