Kubernetes---集群调度

⒈简介

  Scheduler 是 kubernetes 中的调度器组件,主要的任务是把定义的pod 分配到集群的节点上。听起来非常简单,但有很多要考虑的问题:
    公平:如何保证每个节点都能被分配
    资源资源高效利用:集群所有资源最大化被使用
    效率:调度的性能要好,能够尽快地对大批量的pod 完成调度工作
    灵活:允许用户根据自己的需求控制调度的逻辑
  Sheduler是作为单独的程序运行的,启动之后会一直和APIServer持续连接,获取PodSpec.NodeName 为空的 pod,对每个pod都会创建一个binding,表明该 pod 应该放到哪个节点上
⒉调度过程
  调度分为几个部分:首先是过滤掉不满足条件的节点,这个过程称为 predicate;然后对通过的节点按照优先级排序,这个是 priority ;最后从中选择优先级最高的节点。如果中间任何一步骤有错误,就直接返回错误
  Predicate有一系列的算法可以使用: 
    PodFitsResources : 节点上剩余的资源是否大于 pod请求的资源
    Podfitshost:如果pod指定了NodeName,检查节点名称是否和NodeName相匹配
    PodFfitsHostPorts :节点上已经使用的port是否和 pod申请的port冲突
    PodSelectorMatches:过滤掉和 pod指定的label 不匹配的节点
    NoDiskConflict::已经mount 的 volume 和 pod指定的 volume不冲突,除非它们都是只读
  如果在predicate 过程中没有合适的节点。pod会一直在 pending 状态,不断重试调度,直到有节点满足条件。经过这个步骤,如果有多个节点满足条件,就继续priorities 过程:按照优先级大小对节点排序
  优先级由一系列键值对组成,键是该优先级项的名称,值是它的权重(该项的重要性)。这些优先级选项包括:
  ·LeastRequestedPriority:通过计算CPU和 Memory的使用率来决定权重,使用率越低权重越高。换句话说,这个优先级指标倾向于资源使用比例更低的节点
  ·BalancedResourceA1location:节点上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

    ·preferredDuringSchedulinglgnoredDuringExecution:软策略 【我想要去这个节点】

    ·requiredDuringschedulinglgnoredDuringExecution:硬策略 【我一定要去这个节点】

  requiredDuringschedulinglgnoredDuringExecution【硬策略示例】

apiVersion: v1 
kind: Pod 
metadata:
  name: affinity 
  labels:
    app: node-affinity-pod 
spec:
  containers:
  - name: with-node-affinity 
    image: hub.coreqi.cn/library/myapp:v1 
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        node5electorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname 
            operator: NotIn 
            values:
            - k8s-node02

  preferredDuringSchedulinglgnoredDuringExecution【软策略示例】

apiVersion: v1 
kind: Pod 
metadata:
  name: affinity 
  labels:
    app: node-affinity-pod 
spec:
  containers:
  - name: with-node-affinity 
    image: hub.coreqi.cn/library/myapp:v1 
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1 
        preference:
          matchExpressions:
          - key: source
            operator: In 
            values:
            - k8s-node03

  合并示例

apiVersion: v1 
kind: Pod 
metadata:
  name: affinity 
  labels:
    app: node-affinity-pod 
spec:
  containers:
  - name: with-node-affinity 
    image: hub.coreqi.cn/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:
            - k8s-node02

  键值运算关系

    In: label的值在某个列表中

    Notin: label的值不在某个列表中

    Gt: label 的值大于某个值

    Lt: label 的值小于某个值

    Exists:某个label存在

    DoesNotExist:某个label不存在

  <!-- 如果`nodeSelectorTerms`下面有多个选项的话,满足任何一个条件就可以了;如果`matchExpressions`有多个选项的话,则必须同时满足这些条件才能正常调度Pod -->

⒌Pod亲和性

  pod.spec.affinity.podAffinity/podAntiAffinity

    preferredDuringSchedulinglgnored DuringExecution:软策略

    requiredDuringSchedulinglgnoredDuringExecution:硬策略

  

apiVersion: v1 
kind: Pod 
metadata:
  name: pod-3 
  labels:
    app: pod-3 
spec:
  containers:
  - name: pod-3 
    image: hub.coreqi.cn/library/myapp:v1 
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app 
            operator: In 
            values:
            - pod-1 
      topologyKey: kubernetes.io/hostname 
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 1 
          podAffinityTerm:
            labelSelector:
              matchExpressions:
              - key: app 
                operator: In 
                values:
                - pod-2 
            topologyKey: kubernetes.io/hostname

 ⒍Taint(污点) 和 Toleration(容忍) 

  节点亲和性,是pod的一种属性(偏好或硬性要求),它使pod被吸引到一类特定的节点。Taint 则相反,它使节点能够排斥一类特定的pod。
  Taint 和 toleration 相互配合,可以用来避免pod被分配到不合适的节点上。每个节点上都可以应用一个或多个taint,这表示对于那些不能容忍这些 taint 的 pod,是不会被该节点接受的。如果将toleration 应用于pod上,则表示这些pod 可以(但不要求)被调度到具有匹配 taint 的节点上。
 
⒎污点(Taint)
 
  1.污点(Taint)的组成
 
  使用kubectltaint 命令可以给某个Node节点设置污点,Node被设置上污点之后就和Pod之间存在了一种相斥的关系,可以让Node拒绝 Pod的调度执行,甚至将Node已经存在的Pod驱逐出去
  每个污点的组成如下:
key-value:effect
  每个污点有一个key和 value作为污点的标签,其中 value 可以为空,effect 描述污点的作用。当前 tainteffect 支持如下三个选项:

    NoSchedu1e:表示k8s将不会将Pod 调度到具有该污点的Node上
    PreferNoSchedu1e:表示k8s将尽量避免将Pod调度到具有该污点的 Node上
    NoExecute:表示k8s将不会将 Pod调度到具有该污点的Node上,同时会将Node上已经存在的 Pod 驱逐出去
 
  2.污点的设置、查看和去除
#设置污点 
kubectl taint nodes node1 key1=value1:NoSchedule 
#节点说明中,查找 Taints 字段 
kubectl describe pod pod-name 
# 去除污点 
kubectl taint nodes node1 key1:NoSchedule-

 

⒏容忍(Tolerations) 

  设置了污点的Node将根据 taint 的 effect:NoSchedule、PreferNoSchedule、NoExecute 和 Pod之间产生 互斥的关系,Pod将在一定程度上不会被调度到Node上。但我们可以在Pod上设置容忍(Toleration),意思 是设置了容忍的Pod将可以容忍污点的存在,可以被调度到存在污点的Node 上
 
  pod.spec.tolerations
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"
    其中key, vaule, effect 要与Node上设置的 taint保持一致 
    operator 的值为Exists将会忽略value值 
    tolerationSeconds用于描述当Pod需要被驱逐时可以在 Pod上继续保留运行的时间 
 
  1.当不指定key值时,表示容忍所有的污点key:
tolerations:
- operator: "Exists"

  2.当不指定 effect 值时,表示容忍所有的污点作用 

tolerations:
- key: "key"
  operator: "Exists"

  3.有多个Master 存在时,防止资源浪费,可以如下设置

kubectl taint nodes Node-Name node-role.kubernetes.io/master=:PreferNoSchedule

 

⒐指定调度节点

  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-node01 
      containers:
      - name: myweb 
        image: hub.coreqi.cn/library/myapp:v1 
        ports:
        - containerPort: 80

 

  2.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: backEndNode1 
      containers:
      - name: myweb 
        image: harbor/tomcat:8.5-jre8 
        ports:
        - containerPort: 80

 

  

 
 

 

posted @ 2020-05-01 10:45  SpringCore  阅读(325)  评论(0编辑  收藏  举报