• 聊聊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
    复制代码

     

  • 相关阅读:
    Springboot整合Shiro+JWT实现认证授权
    POST_CRC
    笔试刷题汇总
    springboot心理咨询管理系统
    卷积神经网络python实例,python卷积神经网络图像
    数据结构——排序算法——冒泡排序
    令人愉快的 Nuxt3 教程 (一): 应用的创建与配置
    javascript中什么叫“json方式”?
    数学建模——图与网络模型及方法(一)
    168.Hadoop(四):MapReduce基本概念,wordCount案例跑通,bean对象序列化
  • 原文地址:https://www.cnblogs.com/huaweiyun/p/17911323.html