• kubernetes-scheduler调度


    1.控制pod调度的意义

    • 集群中有些机器的配置较高,希望将核心的业务放在上面运行
    • 当有两个服务的网络传递频繁,就需要考虑将它们放在同一台机器上
    • 。。。

    2.kubernetes scheduler是如何工作的

    scheduler工作的目的就是将等待调度的pod按照某种调度算法绑定到node上
    scheduler的工作流程是

    • 出现需要调度的pod
    • scheduler按照一定的调度算法找出一个合适的node与pod绑定
    • 将绑定信息写入到ectd中
    • node节点中的kubelet服务通过API Server监听获取到绑定的pod信息,在该node上下载镜像启动容器
      在这里插入图片描述

    3.scheduler的算法

    该算法有两个步骤分别是预选(Predicates)和优选(Priorities)

    • 预选,K8S会遍历当前集群中的所有 Node,筛选出其中符合要求的 Node 作为候选
    • 优选,K8S将对候选的 Node 进行打分
      经过预选筛选和优选打分之后,K8S选择分数最高的 Node 来运行 Pod,如果最终有多个 Node 的分数最高,那么 Scheduler 将从当中随机选择一个 Node 来运行 Pod。
      在这里插入图片描述

    4.NodeSelector

    使用label与selector可以非常灵活的管理集群,当然pod的调度可以根据节点的labe进行指定部署
    在此之前我们需要直到如何查看节点的label和如何为节点打上label

    查看节点label

    kubectl get nodes --show-labels
    
    • 1

    为节点打上label

    kubectl label node k8s-master disktype=ssd
    
    • 1

    为node打上标签之后,就需要为pod编辑selector,这样pod在被调度的时候就可以调度上拥有该label的节点上了
    只需要在pod的yaml中的spec字段中添加nodeselector字段,就可以实现上面的过程

    ...
    spec:
      hostNetwork: true    # 声明pod的网络模式为host模式,效果通docker run --net=host
      volumes: 
      - name: mysql-data
        hostPath: 
          path: /opt/mysql/data
      nodeSelector:   # 使用节点选择器将Pod调度到指定label的节点
        component: mysql
      containers:
      - name: mysql
          image: 172.21.51.143:5000/demo/mysql:5.7
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    5.nodeAffinity

    节点亲和性 , 比上面的nodeSelector更加灵活,它可以进行一些简单的逻辑组合,不只是简单的相等匹配 。分为两种,硬策略和软策略。
    requiredDuringSchedulingIgnoredDuringExecution : 硬策略,如果没有满足条件的节点的话,就不断重试直到满足条件为止,简单说就是你必须满足我的要求,不然我就不会调度Pod。

    preferredDuringSchedulingIgnoredDuringExecution:软策略,如果你没有满足调度要求的节点的话,Pod就会忽略这条规则,继续完成调度过程,说白了就是满足条件最好了,没有满足就忽略掉的策略。

    #要求 Pod 不能运行在128和132两个节点上,如果有节点满足disktype=ssd或者sas的话就优先调度到这类节点上
    ...
    spec:
          containers:
          - name: demo
            image: 172.21.51.143:5000/myblog:v1
            ports:
            - containerPort: 8002
          affinity:
              nodeAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                    nodeSelectorTerms:
                    - matchExpressions:
                        - key: kubernetes.io/hostname
                          operator: NotIn
                          values:
                            - 192.168.136.128
                            - 192.168.136.132
                            
                preferredDuringSchedulingIgnoredDuringExecution:
                    - weight: 1
                      preference:
                        matchExpressions:
                        - key: disktype
                          operator: In
                          values:
                            - ssd
                            - sas
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    这里的匹配逻辑是 label 的值在某个列表中,现在Kubernetes提供的操作符有下面的几种:

    In:label 的值在某个列表中
    NotIn:label 的值不在某个列表中
    Gt:label 的值大于某个值
    Lt:label 的值小于某个值
    Exists:某个 label 存在
    DoesNotExist:某个 label 不存在
    注意:如果nodeSelectorTerms下面有多个选项的话,满足任何一个条件就可以了;如果matchExpressions有多个选项的话,则必须同时满足这些条件才能正常调度 Pod

    6.pod亲和性和反亲和性

    现在有个需求,webblog启动多个副本,期望是这些副本尽可能分散到集群的可用节点中
    这里kubernetes为我们提供了pod的反亲和性,意思就是当某个节点中有了pod的副本我们可以选择不允许同一个node节点,调度两个pod的副本,或者选择可以允许同一个node节点中调度两个pod的副本,前提是尽量把pod分散部署在集群中

    ...
        spec:
          affinity:
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
              - labelSelector:
                  matchExpressions:
                  - key: app
                    operator: In
                    values:
                    - myblog
                topologyKey: kubernetes.io/hostname
          containers:
    ...
    # 如果某个节点中,存在了app=myblog的label的pod,那么 调度器一定不要给我调度过去
    
    ...
        spec:
          affinity:
            podAntiAffinity:
              preferredDuringSchedulingIgnoredDuringExecution:
              - weight: 100
                podAffinityTerm:
                  labelSelector:
                    matchExpressions:
                    - key: app
                      operator: In
                      values:
                      - myblog
                  topologyKey: kubernetes.io/hostname
          containers:
    ...
    # 如果某个节点中,存在了app=myblog的label的pod,那么调度器尽量不要调度过去
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    7.污点(Taints)与容忍(tolerations)

    对于nodeAffinity无论是硬策略还是软策略方式,都是调度 Pod 到预期节点上,而Taints恰好与之相反,如果一个节点标记为 Taints ,除非 Pod 也被标识为可以容忍污点节点,否则该 Taints 节点不会被调度Pod。

    Taints(污点)是Node的一个属性,设置了Taints(污点)后,因为有了污点,所以Kubernetes是不会将Pod调度到这个Node上的。于是Kubernetes就给Pod设置了个属性Tolerations(容忍),只要Pod能够容忍Node上的污点,那么Kubernetes就会忽略Node上的污点,就能够(不是必须)把Pod调度过去。

    场景一:私有云服务中,某业务使用GPU进行大规模并行计算。为保证性能,希望确保该业务对服务器的专属性,避免将普通业务调度到部署GPU的服务器。

    场景二:用户希望把 Master 节点保留给 Kubernetes 系统组件使用,或者把一组具有特殊资源预留给某些 Pod,则污点就很有用了,Pod 不会再被调度到 taint 标记过的节点。taint 标记节点举例如下:
    设置污点:

    $ kubectl taint node [node_name] key=value:[effect]   
          其中[effect] 可取值: [ NoSchedule | PreferNoSchedule | NoExecute ]
           NoSchedule:一定不能被调度。
           PreferNoSchedule:尽量不要调度。
           NoExecute:不仅不会调度,还会驱逐Node上已有的Pod。
      示例:kubectl taint node k8s-slave1 smoke=true:NoSchedule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    去除污点:

    去除指定key及其effect:
         kubectl taint nodes [node_name] key:[effect]-    #这里的key不用指定value
         kubectl taint node k8s-slave1 smoke-
     去除指定key所有的effect: 
         kubectl taint nodes node_name key-
     
     示例:
         kubectl taint node k8s-master smoke=true:NoSchedule
         kubectl taint node k8s-master smoke:NoExecute-
         kubectl taint node k8s-master smoke-
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Pod容忍污点示例

    spec:
          containers:
          - name: demo
            image: 172.21.51.143:5000/myblog:v1
          tolerations: #设置容忍性
          - key: "smoke" 
            operator: "Equal"  #不指定operator,默认为Equal
            value: "true"
            effect: "NoSchedule"
          - key: "drunk" 
            operator: "Exists"  #如果操作符为Exists,那么value属性可省略,不指定operator,默认为Equal
          #意思是这个Pod要容忍的有污点的Node的key是smoke Equal true,效果是NoSchedule,
          #tolerations属性下各值必须使用引号,容忍的值都是设置Node的taints时给的值。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    Qt第八章:安装Qt Creator教程
    用Python实现广度优先搜索
    Vue----生命周期函数
    怎么给视频添加水印?几个简单的步骤就搞定
    Bytebase 和 GitLab 签署 Technology Partner 技术合作伙伴协议
    如何在Kubernetes 里添加自定义的 API 对象(一)
    数据传送三种方式(post、get、ajax)
    华为机试真题实战应用【赛题代码篇】-打印任务排序(附Java、Python和C++代码)
    浅谈Elasticsearch安全和权限管理
    如何从命令行CMD、IDEA的终端快速在explorer/finder资源管理器访达中打开对应的目录(Windows、Mac)
  • 原文地址:https://blog.csdn.net/apple_56973763/article/details/127797616