聊聊kube-scheduler如何完成调度和调整调度权重
本文分享自华为云社区《kube-scheduler如何完成调度和调整调度权重》,作者: 可以交个朋友。
一、概述
Kube-scheduler作为k8s集群的默认调度器,它监听(watch机制)kube-apiserver,查询还未调度的pod,根据调度策略将pod调度至集群内最适合的Node
二、调度流程
首先我们通过API或者kubectl工具创建pod,kube-apiserver收到请求信息存储到etcd中,调度器通过watch机制监听apiserver查看到还未被调度的pod列表,循环遍历的为每个pod尝试分配node,这个分配过程如下:
-
kube-scheduler内Informer组件list-watch apiserver,使用spec.nodeName=""筛选出还未调度的Pod
-
预选(predicate):调度器通过Predicate算法过滤掉不满足条件的节点
-
优选(priorlty):对于通过预选的节点,通过打分机制,筛选出得分最高的node
-
当调度器为Pod选择了一个合适的节点后,将Pod和节点进行绑定(将节点名称赋值给pod的spec.nodeName字段)
注意:Pod.spec.nodeName用于强制约束将Pod调度到指定的Node上,通过指定nodeName可直接绕过调度器,并不会做任何的资源过滤和检查
三、kuble-scheduler调度原理
Kube-scheduler的调度框架,在 Kubernetes 里面叫作 Scheduler Framework。Pod在调度过程中,都需要依次经过以下的各个阶段,每个阶段自带调度算法,调度算法由插件提供,也可以在指定阶段开发自己的插件。每个插件可以在指定阶段实现具体的调度算法,比如NodeAffinity插件在Filter阶段过滤掉与Pod不亲和的节点。
-
PreFilter: 预处理 Pod 的相关信息,或者检查集群或Pod 必须满足的某些条件。如果 PreFilter 插件返回错误,则调度周期将终止。
-
Filter: 过滤出不能运行该 Pod 的节点。对于每个节点,调度器将按照其配置顺序调用这些过滤插件。如果任何过滤插件将节点标记为不可行,则节点直接排除,不会为该节点调用剩下的过滤插件。
-
PostFilter: 在 Filter 阶段后调用,但仅在该 Pod 没有可行的节点时调用。 典型的后筛选实现是抢占,试图通过抢占其他 Pod 的资源使该 Pod 可以调度。
-
PreScore: 运行评分任务以生成可评分插件的共享状态,如果 PreScore 插件返回错误,则调度周期将终止
-
Score: 通过调用每个评分插件对可调度节点评分
-
NormalizeScore: 规范每个插件的打分在[0,100]之间
-
Reserve: 在绑定周期之前选择保留的节点
-
Permit: 批准或拒绝pod调度周期的结果
-
PreBind: 用于执行 Pod 绑定前所需的任何工作。例如,一个预绑定插件可能需要提供网络卷并且在允许 Pod 运行在该节点之前 将其挂载到目标节点上。
-
Bind: 用于将 Pod 绑定到节点上。直到所有的PreBind 插件都完成,Bind 插件才会被调用。
-
PostBind: 这是个信息性的扩展点。绑定后插件在 Pod 成功绑定后被调用。这是绑定周期的结尾,可用于清理相关的资源
调度器预选阶段对应filter,主要用于过滤不满足Pod调度条件的节点;优选阶段对应score,主要用于为每个节点打分,节点分数=插件打分*插件权重;然后排序选出分数最高的节点
调度阶段 | 实现插件名称 | 插件功能介绍 |
filter | PodTopologySpread | 判断节点是否满足Pod的拓扑分布,不满足则过滤该节点. |
InterPodAffinity | 判断节点是否满足Pod的亲和性配置,不满足则过滤该节点 | |
NodePorts | 判断节点是否满足Pod的端口申请,不满足则过滤该节点 | |
NodeAffinity | 判断节点是否满足Pod的节点亲和性配置,不满足则过滤该节点 | |
VolumeBinding | 判断节点是否满足pv的节点亲和性,并且将满足动态创建pvc条件(比如拓扑)的节点保存起来,以便后续阶段使用 | |
TaintToleration | 根据Pod容忍和节点污点的NoSchedule和NoExecute过滤节点 | |
Score | NodeAffinity | 根据插件权重算出得分,再根据策略权重比例算出节点分数,分数区间0~100,权重默认2 |
NodeResourcesBalancedAllocatio | 根据不同resource(cpu、mem、volume)对节点容量的占比再加上对应resource的权重得到分数,分数区间0~100,权重默认1 | |
ImageLocality | 根据Pod中镜像大小以及镜像在所有节点上的分布来打分,分数区间0~100,权重默认1 | |
InterPodAffinity | 根据插件权重算出得分,再根据策略权重比例算出节点分数,分数区间0~100,权重默认2 | |
TaintToleration | 根据PreferNoSchedule策略算出分数,分数区间0~100,权重默认3 | |
NodeResourcesFit | 三种策略:LeastAllocated(分配越少得分越高)、MostAllocated(分配越多得分越高)、RequestedToCapacityRatio(请求值与容量比率) | |
PodTopologySpread | 根据拓扑匹配度和权重得出分数,分数区间0~100,权重默认2 |
3.1 kubernetes 1.23版本调度器filter阶段和score阶段源码分析
3.2 修改调度器插件默认权重示例
3.2.1 环境准备
环境:集群中有两个节点:k8s-0001和k8s-0002;已有工作负载nginx,调度至节点k8s-0002,工作负载test,yaml文件如下:
apiVersion: apps/v1 kind: Deployment metadata: name: test spec: selector: matchLabels: app: test template: metadata: labels: app: test spec: containers: - name: container-1 image: nginx:latest dnsPolicy: ClusterFirst affinity: nodeAffinity: #利用节点亲和使其调度至k8s-0001 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: kubernetes.io/hostname operator: In values: - k8s-0001 podAffinity: #利用负载亲和使其调度至k8s-0002 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - nginx namespaces: - default topologyKey: kubernetes.io/hostname
3.2.2 调整InterPodAffinity权重,使工作负载test调度至节点k8s-0002
apiVersion: v1 kind: ConfigMap metadata: name: scheduler-config namespace: kube-system data: scheduler-config.yaml: | apiVersion: kubescheduler.config.k8s.io/v1beta3 #1.23以上版本集群可用v1beta3 kind: KubeSchedulerConfiguration profiles: - schedulerName: default-scheduler plugins: score: disabled: - name: InterPodAffinity - name: NodeAffinity enabled: - name: InterPodAffinity #提高负载亲和权重 weight: 100 - name: NodeAffinity weight: 1
查看kube-scheduler调度日志,k8s-002 score得分为打分100 * 权重 100共得10000分,调度到k8s-002节点上
3.2.3 调整NodeAffinity权重,使工作负载test调度至节点k8s-0001
apiVersion: v1 kind: ConfigMap metadata: name: scheduler-config namespace: kube-system data: scheduler-config.yaml: | apiVersion: kubescheduler.config.k8s.io/v1beta3 kind: KubeSchedulerConfiguration profiles: - schedulerName: default-scheduler plugins: score: disabled: - name: InterPodAffinity - name: NodeAffinity enabled: - name: InterPodAffinity weight: 1 - name: NodeAffinity #提高节点亲和权重 weight: 100

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
4种Python中基于字段的不使用元类的ORM实现方法
本文分享自华为云社区《Python中基于字段的不使用元类的ORM实现》,作者: 柠檬味拥抱 。 不使用元类的简单ORM实现 在 Python 中,ORM(Object-Relational Mapping)是一种将对象和数据库之间的映射关系进行转换的技术,使得通过面向对象的方式来操作数据库更加方便。通常,我们使用元类(metaclass)来实现ORM,但是本文将介绍一种不使用元类的简单ORM实现方式。 Field类 首先,我们定义一个Field类,用于表示数据库表中的字段。这个类包含字段的名称和类型等信息,并且支持一些比较操作,以便后续构建查询条件。 class Field: def __init__(self, **kwargs): self.name = kwargs.get('name') self.column_type = kwargs.get('column_type') def __eq__(self, other): return Compare(self, '=', other) # 其他比较操作略... Compare类 为了构建查询条件,我们引...
- 下一篇
面试官问我:线程锁导致的kafka客户端超时,如何解决?
本文分享自华为云社区《线程锁导致的kafka客户端超时问题》,作者: 张俭 。 问题背景 有一个环境的kafka client发送数据有部分超时,拓扑图也非常简单 定位历程 我们先对客户端的环境及JVM情况进行了排查,从JVM所在的虚拟机到kafka server的网络正常,垃圾回收(GC)时间也在预期范围内,没有出现异常。 紧接着,我们把目光转向了kafka 服务器,进行了一些基础的检查,同时也查看了kafka处理请求的超时日志,其中我们关心的metadata和produce请求都没有超时。 问题就此陷入了僵局,虽然也搜到了一些kafka server会对连上来的client反解导致超时的问题(https://github.com/apache/kafka/pull/10059),但通过一些简单的分析,我们确定这并非是问题所在。 同时,我们在环境上也发现一些异常情况,当时觉得不是核心问题/解释不通,没有深入去看 问题JVM线程数较高,已经超过10000,这个线程数量虽然确实较高,但并不会对1个4U的容器产生什么实质性的影响。 负责指标上报的线程CPU较高,大约占用了1/4 ~ 1/2...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- Mario游戏-低调大师作品
- Linux系统CentOS6、CentOS7手动修改IP地址
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7安装Docker,走上虚拟化容器引擎之路
- Docker快速安装Oracle11G,搭建oracle11g学习环境