初探认识Scheduler

一、调度简介

   在开始之前,先来看看kubernetes的架构图,其中控制节点包含三大组件,kube-apiserver、kube-controller-manager、kube-scheduler。

   kube-scheduler是kubernetes的核心组件之一,其主要负责Pod的调度、监听kube-apiserver,查询未分配Node的Pod,根据配置的调度策略,将Pod调度到最优的工作节点上,从而高效、合理的利用集群资源。

二、Scheduler解决了什么问题

   ==kube-scheduler==负责将Pod调度到集群内的最佳节点上,其监听kube-apiserver,查询还未分配Node的Pod,然后根据调度策略为这些Pod分配节点,执行绑定节点的操作。

   在上述流程中,需要考虑到以下几点问题

  • Node公平性
    • 如何保证每个Node都会被分配到Pod资源
  • 资源利用性

    • 如何确保节点资源分配的高效性,使每个节点资源被合理利用
  • 调度性能性

    • 在短时间内对大量Pod进行分批调度
  • 用户灵活性

    • 允许用户根据自己或业务需求控制调度逻辑

三、调度方式

3.1 kubernetes默认调度

   kubernetes调度分为几个流程:

  • 首先是过滤掉不满足条件的节点,这个过程被称为Predicate,支持的算法有以下几种;

    • PodFitsResources

      • 节点上剩余的资源是否大于Pod请求的资源。
    • PodFitsHost

      • 如果Pod指定了NodeName,检查节点名称是否和NodeName一致。
    • PodFitsHostPorts

      • 节点上已经使用的port是否和pod申请的port冲突
    • PodSelectorMatches

      • 过滤掉和Pod指定label不匹配节点
    • NoDiskConflict

      • 已经mount的volume和Pod指定的volume不冲突(排除只读的策略)
  • 然后对通过的节点进行优先级排序,这个过程被称为Priority;
  • 最后从中选择优先级最高的节点

   如果中间任何一步有错误,就会直接返回异常。如果在Predicate过程中没有找到合适的节点,Pod会一直处于Pending状,不断重试调度,直到所节点满足条件。经过这个步骤。如果有多个节点满足条件,就继续priorities过程,按照优先级大小对节点排序。

3.2 亲和力调度

   亲和力包括节点亲和力及Pod亲和力,表示我们部署的服务更加倾向于运行在哪些节点上,对服务的部署有一定的可控性。

3.2.1 节点亲和力
pod.spec.nodeAffinity
  • 运算符关系
运算关系 说明
In label的值在某个列表中
NotIn label的值不在某个列表中
Gt label的值大于某个值
Lt label的值小于某个值
Exists 某个label存在
DoesNotExist 某个label不存在
  • 每个节点都有自己的标签
[root@node1 kube-state-metrics]# kubectl get nodes --show-labels
NAME           STATUS   ROLES    AGE   VERSION   LABELS
10.22.33.104   Ready    <none>   28d   v1.21.6   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=10.22.33.104,kubernetes.io/os=linux
10.22.33.105   Ready    <none>   28d   v1.21.6   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=10.22.33.105,kubernetes.io/os=linux
10.22.33.106   Ready    <none>   28d   v1.21.6   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=10.22.33.106,kubernetes.io/os=linux
  • 硬策略 requiredDuringSchedulingIgnoredDuringExecution

    apiVersion: v1
    kind: Pod
    metadata:
    name: affinity
    labels:
      app: node-affinity-pod
    spec:
    containers:
      - name: with-node-affinity
        image: devops.wangtianci/open/grafana:v8.45
    affinity:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
            - matchExpressions:
                - key: kubernetes.io/hostname
                  operator: NotIn
                  values:
                    - k8s-node01 //主机名不是k8s-node01即可
    
  • 软策略 preferredDuringSchedulingIgnoredDuringExecution

    apiVersion: v1
    kind: Pod
    metadata:
    name: affinity
    labels:
      app: node-affinity-pod
    spec:
    containers:
      - name: with-node-affinity
        image:  devops.wangtianci/open/grafana:v8.45
    affinity:
      nodeAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            preference:
              matchExpressions:
                - key: source
                  operator: In
                  values:
                    - k8s-node03  //主机名是k8s-node03即可
    
3.2.2 Pod亲和力
pod.spec.affinity.podAffinity/podAntiAffinity
  • 软策略
    spec:
      hostNetwork: false
      hostIPC: false
      affinity:
      podAffinity:        
      podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - podAffinityTerm:
              labelSelector:
                  matchLabels:
                  app.kubernetes.io/name: kafka
                  app.kubernetes.io/instance: wtc
                  app.kubernetes.io/component: kafka
              namespaces:
                  - "default"
              topologyKey: kubernetes.io/hostname
              weight: 1
    
    3.2.3 亲和力与反亲和力对比
运算关系 匹配标签 操作符 调度目标
nodeAffinity 主机 In、NotIn、Exists、DoesNotExist、Gt、Lt 主机
podAffinity pod In、NotIn、Exists、DoesNotExist Pod与指定Pod在同一域
podAntiAffinity pod In、NotIn、Exists、DoenNotExist Pod与指定Pod在非同一域

3.3 污点调度

   节点亲和力时间Pod的一种属性,它使Pod被吸引到一类特点的节点。污点(Taint)则相反,它是节点能排斥一类特有的Pod

3.3.1 污点

   kubectl taint可以给某个Node节点设置污点,Node被设置上污点之后就和Pod之间存在了一种相斥的关系,可以让Node节点拒绝Pod的调度执行,升至将Node已经存在的Pod驱逐出去。污点的数据结构如下

key=value:effect

   每一个污点有一个key和value作为污点的标签,其中value可以为空,effect描述污点的作用,总共有3个值

  • NoSchedule

    • k8s将不会把Pod调度到具有该污点的Node上
  • PreferNoSchedule

    • k8s将尽量避免把Pod调度到具有该污点的Node上
  • NoExecute

    • k8s将不会把Pod调度到有该污点的Node上,同时会将Node上已经存在的Pod驱逐

   污点的设置和驱逐

# 设置污点
$ kubectl taint nodes k8s-node1 key1=value1:NoSchedule
$ kubectl taint nodes k8s-node1 type=master:NoExecute

# 节点说明中查找Taints字段
$ kubectl describe pod pod-name

# 去除污点
$ kubectl taint nodes k8s-node1 key1:NoSchedule-
3.3.2 容忍

   设置了污点的 Node 将根据 taint 的 effect:NoSchedule、PreferNoSchedule、NoExecute 和 Pod 之间产生互斥的关系,Pod 将在一定程度上不会被调度到 Node 上。但我们可以在 Pod 上设置容忍,意思是设置了容忍的 Pod 将可以容忍污点的存在,可以被调度到存在污点的 Node 上。

pod.spec.tolerations
3.4 指定节点调度
3.4.1 Pod.spec.nodeName

   将 Pod 直接调度到指定的 Node 节点上,会跳过 Scheduler 的调度策略,该匹配规则是强制匹配。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myweb
spec:
  replicas: 7
  template:
    metadata:
      labels:
        app: myweb
    spec:
      nodeName: k8s-node1
      containers:
        - name: myweb
          image: devops.wangtianci/open/grafana:v8.45
          ports:
            - containerPort: 80
3.4.1 Pod.spec.nodeSelector

   通过 kubernetes 的 label-selector 机制选择节点,由调度器调度策略匹配 label,而后调度 Pod 到目标节点,该匹配规则属于强制约束。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myweb
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: myweb
    spec:
    nodeSelector:
      type: BackendNode
    containers:
      - name: myweb
        image: devops.wangtianci/open/grafana:v8.45
        ports: 3000

Copyright & TianCiwang 2021 all right reserved,powered by Gitbook修改时间: 2022-04-20 11:48:10

results matching ""

    No results matching ""

    results matching ""

      No results matching ""