zoukankan      html  css  js  c++  java
  • k8s集群安装学习笔记六——集群调度

    简介:

    集群调度
    节点亲和性
    Pod 亲和性
    Taint 和 Toleration(污点和容忍)

    集群调度

    简介

    Scheduler 是 kubernetes 的调度器,主要的任务是把定义的 pod 分配到集群的节点上。听起来非常简单,但有很多要考虑的问题:
      公平:如何保证每个节点都能被分配资源
      资源高效利用:集群所有资源最大化被使用
      效率:调度的性能要好,能够尽快地对大批量的 pod 完成调度工作
      灵活:允许用户根据自己的需求控制调度的逻辑
     
    Sheduler 是作为单独的程序运行的,启动之后会一直坚挺 API Server,获取 PodSpec.NodeName 为空的 pod,对每个 pod 都会创建一个 binding,表明该 pod 应该放到哪个节点上。
     
    调度过程
    调度分为几个部分:首先是过滤掉不满足条件的节点,这个过程称为 predicate ;
    然后对通过的节点按照优先级排序,这个是 priority ;
    最后从中选择优先级最高的节点。如果中间任何一步骤有错误,就直接返回错误。
     
    Predicate 有一系列的算法可以使用:
      PodFitsResources :节点上剩余的资源是否大于 pod 请求的资源
      PodFitsHost :如果 pod 指定了 NodeName,检查节点名称是否和 NodeName 匹配
      PodFitsHostPorts :节点上已经使用的 port 是否和 pod 申请的 port 冲突
      PodSelectorMatches :过滤掉和 pod 指定的 label 不匹配的节点
      NoDiskConflict :已经 mount 的 volume 和 pod 指定的 volume 不冲突,除非它们都是只读
     
    如果在 predicate 过程中没有合适的节点,pod 会一直在 pending 状态,不断重试调度,直到有节点满足条件。
    经过这个步骤,如果有多个节点满足条件,就继续 priorities 过程: 按照优先级大小对节点排序。
     
    优先级由一系列键值对组成,键是该优先级项的名称,值是它的权重(该项的重要性)。这些优先级选项包括:
      LeastRequestedPriority :通过计算 CPU 和 Memory 的使用率来决定权重,使用率越低权重越高。换句话说,这个优先级指标倾向于资源使用比例更低的节点。
      BalancedResourceAllocation :节点上 CPU 和 Memory 使用率越接近,权重越高。这个应该和上面的一起使用,不应该单独使用。
      ImageLocalityPriority :倾向于已经有要使用镜像的节点,镜像总大小值越大,权重越高通过算法对所有的优先级项目和权重进行计算,得出最终的结果。
     
     
    自定义调度器
    除了 kubernetes 自带的调度器,你也可以编写自己的调度器。通过 spec:schedulername 参数指定调度器的名字,
    可以为 pod 选择某个调度器进行调度。比如下面的 pod 选择 my-scheduler 进行调度,而不是默认的default-scheduler :
    apiVersion: v1 
    kind: Pod 
    metadata: 
      name: annotation-second-scheduler 
      labels: 
        name: multischeduler-example 
    spec: 
      schedulername: my-scheduler 
      containers: 
      - name: pod-with-second-annotation-container 
        image: gcr.io/google_containers/pause:2.0

    节点亲和性

    pod.spec.nodeAffinity
      preferredDuringSchedulingIgnoredDuringExecution:软策略
      requiredDuringSchedulingIgnoredDuringExecution:硬策略
     
    requiredDuringSchedulingIgnoredDuringExecution
    $ vim pod1.yaml

    apiVersion: v1 kind: Pod metadata: name: affinity labels: app: node
    -affinity-pod spec: containers: - name: with-node-affinity image: hub.atguigu.com/library/myapp:v1 affinity: #亲和性 nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: #硬策略亲和性,必须匹配,不匹配就不运行 nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname #键,就是node节点的标签,可通过kubectl get node --show-labels查看 operator: NotIn #含义:只要上面的键值不是k8s-node02即可 values: #值 - k8s-node02

    $ kubectl create -f pod1.yaml

     

    可以看到只在k8s-node01节点创建运行了:

     

    preferredDuringSchedulingIgnoredDuringExecution
     
    $ vim pod2.yaml

    apiVersion: v1 kind: Pod metadata: name: affinity labels: app: node
    -affinity-pod spec: containers: - name: with-node-affinity image: hub.atguigu.com/library/myapp:v1 affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: #软策略,如果匹配的话更好,不匹配也执行 - weight: 1 preference: matchExpressions: - key: kubernetes.io/hostname operator: In values: - k8s-node02

    $ kubectl create -f pod2.yaml
    合体(先满足赢策略,再匹配软策略)
    apiVersion: v1 
    kind: Pod 
    metadata: 
      name: affinity 
      labels: 
        app: node-affinity-pod 
    spec: 
      containers: 
      - name: with-node-affinity 
        image: hub.atguigu.com/library/myapp:v1 
      affinity: 
        nodeAffinity: 
          requiredDuringSchedulingIgnoredDuringExecution: 
            nodeSelectorTerms: 
            - matchExpressions: 
              - key: kubernetes.io/hostname 
                operator: NotIn 
                values: 
                - k8s-node02 
          preferredDuringSchedulingIgnoredDuringExecution:  #软策略
          - weight: 1  #权重,如果有多个软策略,比较权重大小,权重越大越亲和
            preference: 
              matchExpressions: 
              - key: source 
                operator: In 
                values: 
                - qikqiak
    键值运算关系
      In:label 的值在某个列表中
      NotIn:label 的值不在某个列表中
      Gt:label 的值大于某个值
      Lt:label 的值小于某个值
      Exists:某个 label 存在
      DoesNotExist:某个 label 不存在
     
     
    Pod 亲和性
    pod.spec.affinity.podAffinity/podAntiAffinity
      preferredDuringSchedulingIgnoredDuringExecution:软策略
      requiredDuringSchedulingIgnoredDuringExecution:硬策略
     
    先创建一个pod-1
    $ vim pod1.yaml
    
    apiVersion: v1 
    kind: Pod 
    metadata: 
      name: node01 
      labels: 
        app: node01 
    spec: 
      containers: 
      - name: node01 
        image: hub.atguigu.com/library/myapp:v1
    
    $ kubectl create -f pod1.yaml

     查看当前有的标签信息

     
    apiVersion: v1 
    kind: Pod 
    metadata: 
      name: pod-3 
      labels: 
        app: pod-3 
    spec: 
      containers: 
      - name: pod-3 
        image: hub.atguigu.com/library/myapp:v1 
      affinity: 
        podAffinity:  #pod亲和性,该方案可以让pod运行在同一个node上
          requiredDuringSchedulingIgnoredDuringExecution:  #硬策略
          - labelSelector: 
            matchExpressions:   
            - key: app  #匹配有没有pod标签的key=app,value=node01,如果匹配上,创建的pod必须在该节点上
              operator: In 
              values: 
              - node01 
            topologyKey: kubernetes.io/hostname  #判断条件是:hostname的名称
        podAntiAffinity: #不想让pod运行在同一个node上时,选择此方案
          preferredDuringSchedulingIgnoredDuringExecution:  #软策略
          - weight: 1 
            podAffinityTerm: 
              labelSelector: 
                matchExpressions: 
                - key: app  
                  operator: In 
                  values: 
                  - node01 
              topologyKey: kubernetes.io/hostname

    创建后可看到和匹配的node节点在一起了

     同理,验证podAntiAffinity时,创建后可看到和匹配的node节点完全不一样。

     

    Taint 和 Toleration

    节点亲和性,是 pod 的一种属性(偏好或硬性要求),它使 pod 被吸引到一类特定的节点。Taint 则相反,它使节点 能够 排斥 一类特定的 pod。
     
    Taint 和 toleration 相互配合,可以用来避免 pod 被分配到不合适的节点上。每个节点上都可以应用一个或多个taint ,
    这表示对于那些不能容忍这些 taint 的 pod,是不会被该节点接受的。如果将 toleration 应用于 pod上,
    则表示这些 pod 可以(但不要求)被调度到具有匹配 taint 的节点上。
     
    污点(Taint)
    Ⅰ、 污点 ( Taint ) 的组成
    使用 kubectl taint 命令可以给某个 Node 节点设置污点,Node 被设置上污点之后就和 Pod 之间存在了一种相斥的关系,
    可以让 Node 拒绝 Pod 的调度执行,甚至将 Node 已经存在的 Pod 驱逐出去。
    每个污点的组成如下:
    key=value:effect
    每个污点有一个 key 和 value 作为污点的标签,其中 value 可以为空,effect 描述污点的作用。当前 tainteffect 支持如下三个选项:
      NoSchedule :表示 k8s 将不会将 Pod 调度到具有该污点的 Node 上。
      PreferNoSchedule :表示 k8s 将尽量避免将 Pod 调度到具有该污点的 Node 上。
      NoExecute :表示 k8s 将不会将 Pod 调度到具有该污点的 Node 上,同时会将 Node 上已经存在的 Pod 驱逐出去。
     
    Ⅱ、污点的设置、查看和去除
    # 设置污点 
    kubectl taint nodes node1 key1=value1:NoSchedule
    # 节点说明中,查找 Taints 字段
    kubectl describe pod pod-name
    # 去除污点
    kubectl taint nodes node1 key1=value1:NoSchedule- #只需要加一个"-"号即可

    例:原pod设置污点之后,会将 Node 上已经存在的 Pod 驱逐出去,因为是自主式创建的pod,所以会被删除而且不会被重新创建。

    如果是deployment、StatefulSet控制器控制的pod,因为要维持副本数,就会重新创建在其他node节点上。

    容忍(Tolerations)
    设置了污点的 Node 将根据 taint 的 effect:NoSchedule、PreferNoSchedule、NoExecute 和 Pod 之间产生互斥的关系,
    Pod 将在一定程度上不会被调度到 Node 上。 但我们可以在 Pod 上设置容忍 ( Toleration ) ,
    意思是设置了容忍的 Pod 将可以容忍污点的存在,可以被调度到存在污点的 Node 上。
    pod.spec.tolerations
    $ vim pod3.yaml
    apiVersion: v1 kind: Pod metadata: name: pod
    -3 labels: app: pod-3 spec: containers: - name: pod-3 image: hub.atguigu.com/library/myapp:v1 tolerations: #设置容忍 - key: "key1" operator: "Equal" value: "value1" effect: "NoSchedule" tolerationSeconds: 3600 - key: "key1" operator: "Equal" value: "value1" effect: "NoExecute" - key: "key2" operator: "Exists" effect: "NoSchedule"

    $ kubectl apply -f pod3.yaml
      其中 key, vaule, effect 要与 Node 上设置的 taint 保持一致。
      operator 的值为 Exists 将会忽略 value 值。
      tolerationSeconds 用于描述当 Pod 需要被驱逐时可以在 Pod 上继续保留运行的时间。
     
    Ⅰ、当不指定 key 值时,表示容忍所有的污点 key:
    tolerations: 
    - operator: "Exists"
    Ⅱ、当不指定 effect 值时,表示容忍所有的污点作用
    tolerations: 
    - key: "key" 
      operator: "Exists"
    Ⅲ、有多个 Master 存在时,防止资源浪费,可以如下设置
    kubectl taint nodes Node-Name node-role.kubernetes.io/master=:PreferNoSchedule

    实际应用场景:

    有一天,node02需要维护,但是上面跑了很多pod,不能直接关闭,否则可能会影响访问。

    这时就可以给node02打一个NoExecute污点,上面的pod就会被驱逐出去,此时就可以进行正常维护了。

    指定调度节点

    Ⅰ、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-node01  #强制指定运行节点,7个pod都会运行在这个节点。
          containers: 
          - name: myweb 
            image: hub.atguigu.com/library/myapp:v1 
            ports: 
            - containerPort: 80
    Ⅱ、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:  #键名选择
            disk: ssd  #key:value   #匹配标签键值
          containers: 
          - name: myweb 
            image: harbor/tomcat:8.5-jre8 
            ports: 
            - containerPort: 80

    手动打一个标签

    kubectl label node k8s-node01 disk=ssd

     
    好记性不如烂笔头,最难不过坚持
  • 相关阅读:
    三数之和
    罗马数字与整数
    Oracle 开启或关闭归档
    Oracle RMAN scripts to delete archivelog
    Oracle check TBS usage
    Oracle kill locked sessions
    场景9 深入RAC运行原理
    场景7 Data Guard
    场景4 Data Warehouse Management 数据仓库
    场景5 Performance Management
  • 原文地址:https://www.cnblogs.com/dannylinux/p/15330659.html
Copyright © 2011-2022 走看看