• Kubernetes kube-scheduler调度器


    APIServer职责主要是认证,鉴权,准入,它判断一个请求是谁发起的,发起人有没有相应的权限,这个请求是不是合法的,以及从apiserver这端觉得要对原始请求变更一些属性,那么它就可以在这里面去做。

    apserver经过这些环节之后,这些检查都通过了,请求也合法,那么它会将请求存在etcd里面。

    apiserver本身是k8s集群当中唯一和etcd数据库通信的这样一个组件,其他所有组件都需要和apiserver去通信,去获取数据的变更信息。

    kubelet分为自己的框架代码,以及包含下面的接口抽象,它将运行时抽象为cri,将网络抽象为cni,将存储抽象为csi。

    kube-scheduler


    kube-scheduler负责分配调度Pod到集群内的节点上,它监听kube-apiserver,查询还未分配Node 的 Pod,然后根据调度策略为这些Pod分配节点(更新 Pod 的 NodeName 字段)。调度器需要充分考虑诸多的因素∶

    • 公平调度(当接受到很多请求的时候,确保我们能够公平的去处理请求,大家都是平等的,本着先到先服务的原则去做调度,这是公平性。还有一些不公平的因素,比如调度的时候有调度优先级,我的一个应用特别重要,希望插队放到前面去,所以在这k8s提供了完备的支持,对于同一个调度优先级,我是公平的原则,不同的优先级会插队放在前面,优先级越高的越优先调度)
    • 资源高效利用(找到最合适的节点调度过去)
    • QoS
    • affinity和anti-affinity
    • 数据本地化(data locality)
    • 内部负载干扰(inter-workload interference)
    • deadlines。

    调度器会去监听集群里面所有计算节点的信息,它要知道当前集群里面有多少个计算节点,这些节点的健康状态如何,它们的资源使用情况如何,有多少资源使用了,有多少可分配。

    每个计算节点都会将自己的信息上报给apiserver,我们的调度器就会去watch apiserver,获取这些节点的信息,那么调度器就有一个集群的全局视图。

    一方面它有集群所有节点的计算资源的全局视图,另外一方面它能够接受到用户的pod,对它来说就是调度请求,来寻找一个最佳节点,找到最佳节点就完成了pod和节点的绑定关系。本质上就是将pod的nodename字段填充了。

    用户建立pod的时候是不去填nodename的,因为不知道pod会被调度到哪,调度器会去看一个pod的nodename为空,那就说明你要去调度的,所以它就会去做调度,找到合适的节点,将nodename填上去。

     

    调度器


    kube-scheduler调度分为两个阶段,predicate和priority∶

    predicate∶过滤不符合条件的节点;filter

    priority∶优先级排序,选择优先级最高的节点。score

    filter:有100台机器,你有一个pod请求,我得先去看看有哪些节点不满足你的需求,先将不满足需求的节点过滤掉。

    过滤之后可能还剩下10台能够满足你的需求,那么就需要排序了,排序就是按照各种因素去打分了,

     

     

    Predicates策略


    因为调度的时候,需要考虑诸多因素,每个因素对于调度器来说都是一个插件。做predicate的过程相对于遍历这些predict插件,然后一个个去执行。

    PodFitsResources:检查Node的资源是否充足,包括允许的Pod数量、CPU、内存、GPU个数以及其他的OpaquelntResources。(先看看哪些节点是不满足pod资源的,没有合适资源机器全部刷掉)

    PodFitsHostPorts:检查是否有Host Ports冲突。

    PodFitsPorts: 同PodFitsHostPorts。(有些pod希望占用主机端口,那我去调度的时候要去看这个端口还是不是空余的,如果这个端口被占用了,说明这个节点就不能安置这个pod了)

    HostName∶ 检查pod.Spec.NodeName是否与候选节点一致。

    MatchNodeSelector∶ 检查候选节点的pod.Spec.NodeSelector是否匹配。(只会调度到这些节点)

    NoVolumeZoneConflict∶ 检查volume zone 是否冲突。

    MatchlnterPodAffinity∶检查是否匹配Pod的亲和性要求。

    NoDiskConflict∶ 检查是否存在Volume冲突,仅限于GCEPD、AWS EBS、Ceph RBD 以及 iSCSI。

    PodToleratesNodeTaints∶ 检查Pod是否容忍Node Taints。

    CheckNodeMemoryPressure∶ 检查Pod是否可以调度到MemoryPressure的节点上。

    CheckNodeDiskPressure∶ 检查Pod是否可以调度到DiskPressure的节点上。

    NoVolumeNodeConflict∶ 检查节点是否满足Pod所引用的Volume的条件。

    还有很多其他策略,你也可以编写自己的策略。

     

     

     

    Predicates plugin 工作原理


    当去做pod调度的时候,就会一个个去遍历predicate的plugin,我就一个一个plugin去跑,经过每一个plugin,我都会过滤一批机器,经过每一个plugin都会过滤掉一批机器,最后就剩下符合调度需求的机器。

     

     

    Priorities策略


    对于priority来说也有很多的插件,针对每个插件,他也是去遍历每个插件去算分,最后会给每个节点打分汇总,最终将得分最高的节点排在前面。

    SelectorSpreadPriority∶优先减少节点上属于同一个Service或Replication Controller的Pod数量。

    InterPodAffinityPriority∶优先将Pod调度到相同的拓扑上(如同一个节点、Rack、Zone等)。

    LeastRequestedPriority∶优先调度到请求资源少的节点上。

    BalancedResourceAllocation∶优先平衡各节点的资源使用。

    NodePreferAvoidPodsPriority∶ alpha.kubernetes.io/preferAvoidPods字段判断,权重为10000,避免其他优先级策略的影响。

     

     

    资源需求


    CPU

        requests

           Kubernetes 调度 Pod 时,会判断当前节点正在运行的 Pod 的 CPU Request 的总和,再加上当前调度Pod的CPU request,计算其是否超过节点的CPU的可分配资源。

       limits

          配置cgroup以限制资源上限。

    内存

        requests

          判断节点的剩余内存是否满足Pod的内存请求量,以确定是否可以将Pod调度到该节点。

     limits

          配置cgroup以限制资源上限。

     

     

    磁盘资源需求


    容器临时存储(ephemeral storage)包含日志和可写层数据,可以通过定义 Pod Spec 中的limits.ephemeral-storage和requests.ephemeral-storage来申请。

    Pod 调度完成后,计算节点对临时存储的限制不是基于 cgroup 的,而是由 kubelet 定时获取容器的日志和容器可写层的磁盘使用情况,如果超过限制,则会对Pod进行驱逐。

     

     

    Init Container的资源需求


    在一个pod里面除了主容器,还有init container,做些初始化的工作,istio就有initcontainer,它起来之后会去配置本地的iptables规则,配置完之后就退出了。

    比如说应用要通过jwt token去访问其他的应用,应用和应用之间需要做认证鉴权的,我们就会使用初始化容器,因为这个token是一次性获取的,我们就会使用初始化的容器去获取这个token,这个token获取完毕就存在本地硬盘,然后硬盘通过volume mount到一个主容器,和主容器mount到同一个路径,那么就可以被读取了。

    initcontainer很多时候是主容器预先加载资源的时候,加载配置的时候就可以让其去做。

    • 当 kube-scheduler调度带有多个init 容器的 Pod 时,只计算 cpu.request 最多的 init 容器,而不是计算所有的init容器总和。(也可以设置request limit)

    ● 由于多个init 容器按顺序执行,并且执行完成立即退出,所以申请最多的资源init 容器中的所

    需资源,即可满足所有init容器需求。

    ● kube-scheduler在计算该节点被占用的资源时,init 容器的资源依然会被纳入计算。因为init

    容器在特定情况下可能会被再次执行,比如由于更换镜像而引起Sandbox重建时。

  • 相关阅读:
    OFDM 十六讲 2- OFDM and the DFT
    ArcGIS Pro 转换Smart3D生成的倾斜3D模型数据osgb——创建集成网格场景图层包
    电机矢量控制算法和例程
    不会Python迟早失业?Python何以成为找工作必备技能(资料下载)
    高性能数据JS网格 Bryntum Grid 5.5.2 Crack
    基于JavaSwing开发MP3音乐播放器系统 课程设计 大作业源码 毕业设计
    红黑树介绍
    SSH客户端工具MobaXterm
    力扣 215. 数组中的第K个最大元素
    [突发奇想] 考研 & LOL & CF & 红警
  • 原文地址:https://blog.csdn.net/qq_34556414/article/details/125879601