[关闭]
@zhangyy 2020-12-04T22:19:18.000000Z 字数 8254 阅读 169

kubernetes 的调度

kubernetes系列


  • 一: kubernetes的调度
  • 二: kubernetes的节点的亲和性
  • 三: kubernetes的污点与容忍
  • 四: kubernetes的固定节点

一:kubernetes的调度

1.1 scheduler 的介绍

  1. Scheduler kubernetes 的调度器,主要的任务是把定义的 pod 分配到集群的节点上。听起来非常简单,但有很多要考虑的问题:
  2. 1.公平:如何保证每个节点都能被分配资源
  3. 2. 资源高效利用:集群所有资源最大化被使用
  4. 3. 效率:调度的性能要好,能够尽快地对大批量的 pod 完成调度工作
  5. 4. 灵活:允许用户根据自己的需求控制调度的逻辑
  6. Sheduler 是作为单独的程序运行的,启动之后会一直坚挺 API Server,获取 PodSpec.NodeName 为空的 pod,对每个 pod 都会创建一个 binding,表明该 pod 应该放到哪个节点上

1.2 调度过程

  1. 调度分为几个部分:首先是过滤掉不满足条件的节点,这个过程称为 predicate ;然后对通过的节点按照优先级排序,这个是 priority;最后从中选择优先级最高的节点。如果中间任何一步骤有错误,就直接返回错误

  1. Predicate 有一系列的算法可以使用:
  2. PodFitsResources :节点上剩余的资源是否大于 pod 请求的资源
  3. PodFitsHost :如果 pod 指定了 NodeName,检查节点名称是否和 NodeName 匹配
  4. PodFitsHostPorts :节点上已经使用的 port 是否和 pod 申请的 port 冲突
  5. PodSelectorMatches :过滤掉和 pod 指定的 label 不匹配的节点
  6. NoDiskConflict :已经 mount volume pod 指定的 volume 不冲突,除非它们都是只读

  1. 如果在 predicate 过程中没有合适的节点,pod 会一直在 pending 状态,不断重试调度,直到有节点满足条件。
  2. 经过这个步骤,如果有多个节点满足条件,就继续 priorities 过程: 按照优先级大小对节点排序
  3. 优先级由一系列键值对组成,键是该优先级项的名称,值是它的权重(该项的重要性)。这些优先级选项包括:
  4. LeastRequestedPriority :通过计算 CPU Memory的使用率来决定权重,使用率越低权重越高。换句话说,这个优先级指标倾向于资源使用比例更低的节点
  5. BalancedResourceAllocation :节点上 CPU Memory使用率越接近,权重越高。这个应该和上面的一起使用,不应该单独使用
  6. ImageLocalityPriority:倾向于已经有要使用镜像的节点,镜像总大小值越大,权重越高通过算法对所有的优先级项目和权重进行计算,得出最终的结果

二: kubernetes 调度的亲和性

  1. 键值运算关系
  2. Inlabel 的值在某个列表中
  3. NotInlabel 的值不在某个列表中
  4. Gtlabel 的值大于某个值
  5. Ltlabel 的值小于某个值
  6. Exists:某个 label 存在
  7. DoesNotExist:某个 label 不存在

2.1 节点亲和性

  1. 节点亲和性
  2. pod.spec.nodeAffinity
  3. preferredDuringSchedulingIgnoredDuringExecution:软策略
  4. requiredDuringSchedulingIgnoredDuringExecution:硬策略
  5. requiredDuringSchedulingIgnoredDuringExecution
  6. vim affit1.yaml
  7. ---
  8. apiVersion: v1
  9. kind: Pod
  10. metadata:
  11. name: affinity
  12. labels:
  13. app: node-affinity-pod
  14. spec:
  15. containers:
  16. - name: with-node-affinity
  17. image: wangyanglinux/myapp:v1
  18. affinity:
  19. nodeAffinity:
  20. requiredDuringSchedulingIgnoredDuringExecution:
  21. nodeSelectorTerms:
  22. - matchExpressions:
  23. - key: kubernetes.io/hostname
  24. operator: NotIn
  25. values:
  26. - node02.flyfish
  27. ---
  28. kubectl get pod --show-labes
  29. 排除operator:NotIn 就是不在 node02.flyfish 运行
  30. kubectl apply -f affit1.yaml
  31. kubectl get pod
  32. kubernetes.io/hostname
  33. kubectl get node --show-labels

image_1e45sj4nnq601a0v6khfkem1c.png-44.6kB

image_1e4l185kkrlseqmpuo1ch9n09.png-107.4kB


  1. vim aifft2.yaml
  2. ----
  3. apiVersion: v1
  4. kind: Pod
  5. metadata:
  6. name: affinity1
  7. labels:
  8. app: node-affinity-pod1
  9. spec:
  10. containers:
  11. - name: with-node-affinity1
  12. image: wangyanglinux/myapp:v1
  13. affinity:
  14. nodeAffinity:
  15. requiredDuringSchedulingIgnoredDuringExecution:
  16. nodeSelectorTerms:
  17. - matchExpressions:
  18. - key: kubernetes.io/hostname
  19. operator: In
  20. values:
  21. - node03.flyfish
  22. ----
  23. node03.flyfish 节点上 运行
  24. kubectl apply -f aifft2.yaml

image_1e45t40ul131ekdchjpt3logmp.png-73.1kB

  1. vim aifft3.yaml
  2. -----
  3. apiVersion: v1
  4. kind: Pod
  5. metadata:
  6. name: affinity2
  7. labels:
  8. app: node-affinity-pod2
  9. spec:
  10. containers:
  11. - name: with-node-affinity2
  12. image: wangyanglinux/myapp:v1
  13. affinity:
  14. nodeAffinity:
  15. requiredDuringSchedulingIgnoredDuringExecution:
  16. nodeSelectorTerms:
  17. - matchExpressions:
  18. - key: kubernetes.io/hostname
  19. operator: NotIn
  20. values:
  21. - node03.flyfish
  22. -----
  23. 不在node03.flyfish 运行
  24. kubectl apply -f aifft3.yaml

image_1e45t54t21sbu1bdu942qt910l816.png-75.1kB


  1. preferredDuringSchedulingIgnoredDuringExecution:软策略
  2. vim prefer.yaml
  3. ---
  4. apiVersion: v1
  5. kind: Pod
  6. metadata:
  7. name: affinity
  8. labels:
  9. app: node-affinity-pod
  10. spec:
  11. containers:
  12. - name: with-node-affinity
  13. image: wangyanglinux/myapp:v1
  14. affinity:
  15. nodeAffinity:
  16. preferredDuringSchedulingIgnoredDuringExecution:
  17. - weight: 1
  18. preference:
  19. matchExpressions:
  20. - key: source
  21. operator: In
  22. values:
  23. - node04.flyfish
  24. ---
  25. 软策略 如果节点 存在 在这个节点上面运行,如果节点不存在者会随便选择一个节点去运行
  26. ---
  27. kubectl apply -f perfer.yaml
  28. kubectl get pod -o wide

image_1e45u8q0uveg1rrn1m1cb68run1j.png-52.9kB

  1. vim perfer1.yaml
  2. ---
  3. apiVersion: v1
  4. kind: Pod
  5. metadata:
  6. name: affinity1
  7. labels:
  8. app: node-affinity-pod1
  9. spec:
  10. containers:
  11. - name: with-node-affinity1
  12. image: wangyanglinux/myapp:v1
  13. affinity:
  14. nodeAffinity:
  15. preferredDuringSchedulingIgnoredDuringExecution:
  16. - weight: 1
  17. preference:
  18. matchExpressions:
  19. - key: source
  20. operator: In
  21. values:
  22. - node03.flyfish
  23. ---
  24. 因为node3.flyfish 这个节点存在 所以 就会在node03.flyfish 这个节点上面运行
  25. kubectl apply -f perfer1.yaml
  26. kubectl get pod -o wide

image_1e45ub455lsa1eds15aa1mqi65s20.png-81.3kB


  1. 合体使用
  2. ---
  3. vim perfer3.yaml
  4. -----
  5. apiVersion: v1
  6. kind: Pod
  7. metadata:
  8. name: affinity2
  9. labels:
  10. app: node-affinity-pod2
  11. spec:
  12. containers:
  13. - name: with-node-affinity2
  14. image: wangyanglinux/myapp:v1
  15. affinity:
  16. nodeAffinity:
  17. requiredDuringSchedulingIgnoredDuringExecution:
  18. nodeSelectorTerms:
  19. - matchExpressions:
  20. - key: kubernetes.io/hostname
  21. operator: NotIn
  22. values:
  23. - node02.flyfish
  24. preferredDuringSchedulingIgnoredDuringExecution:
  25. - weight: 1
  26. preference:
  27. matchExpressions:
  28. - key: source
  29. operator: In
  30. values:
  31. - node03.flyfish
  32. ----
  33. 从上到下 进行亲和性 匹配 先满足硬 匹配在满足软匹配
  34. kubectl apply -f perfer3.yaml
  35. kubectl get pod -o wide

image_1e45urfg61nilcgi1b7710o71b812d.png-85.7kB

2.2 pod 亲和性

  1. pod.spec.affinity.podAffinity/podAntiAffinity
  2. preferredDuringSchedulingIgnoredDuringExecution:软策略
  3. requiredDuringSchedulingIgnoredDuringExecution:硬策略
  4. 新建一个node01 pod
  5. -----
  6. vim node01.yaml
  7. ----
  8. apiVersion: v1
  9. kind: Pod
  10. metadata:
  11. name: node01
  12. labels:
  13. app: node01
  14. spec:
  15. containers:
  16. - name: with-node-affinity1
  17. image: wangyanglinux/myapp:v1
  18. ----
  19. kubectl apply -f node01.yaml
  20. kubectl get pod -o wide
  21. node02.flyfish 上面运行

image_1e4l24gii6ogaht1mt7nee1nnhm.png-124.8kB


  1. vim pod1.yaml
  2. -----
  3. apiVersion: v1
  4. kind: Pod
  5. metadata:
  6. name: pod-3
  7. labels:
  8. app: pod-3
  9. spec:
  10. containers:
  11. - name: pod-3
  12. image: wangyanglinux/myapp:v1
  13. affinity:
  14. podAffinity:
  15. requiredDuringSchedulingIgnoredDuringExecution:
  16. - labelSelector:
  17. matchExpressions:
  18. - key: app
  19. operator: In
  20. values:
  21. - node01
  22. topologyKey: kubernetes.io/hostname
  23. ----
  24. pod-3 这个pod 必须和node01 pod 在一个节点上面
  25. kubectl apply -f pod1.yaml
  26. kubectl get pod -o wide

image_1e4l2iihibhood31m9ehoe15u313.png-66kB

  1. vim pod2.yaml
  2. -----
  3. apiVersion: v1
  4. kind: Pod
  5. metadata:
  6. name: pod-4
  7. labels:
  8. app: pod-4
  9. spec:
  10. containers:
  11. - name: pod-4
  12. image: wangyanglinux/myapp:v1
  13. affinity:
  14. podAntiAffinity:
  15. requiredDuringSchedulingIgnoredDuringExecution:
  16. - labelSelector:
  17. matchExpressions:
  18. - key: app
  19. operator: In
  20. values:
  21. - node01
  22. topologyKey: kubernetes.io/hostname
  23. ------
  24. 必须和 node01 pod 不在同一个节点
  25. kubectl apply -f pod2.yaml
  26. kubectl get pod -o wide

image_1e4l2vpkhtvvjcdcp16ok6o81g.png-107.9kB

2.3 亲和性/反亲和性调度策略比较如下:

image_1e4l36r2q1g0618k51bj813b51lee1t.png-95.9kB

三:kubernetes 的污点与容忍

3.1 Taint 和 Toleration

  1. 节点亲和性,是 pod 的一种属性(偏好或硬性要求),它使 pod 被吸引到一类特定的节点。Taint 则相反,它使
  2. 节点 能够 排斥 一类特定的 pod
  3. Taint toleration 相互配合,可以用来避免 pod 被分配到不合适的节点上。每个节点上都可以应用一个或多个
  4. taint ,这表示对于那些不能容忍这些 taint pod,是不会被该节点接受的。如果将 toleration 应用于 pod
  5. 上,则表示这些 pod 可以(但不要求)被调度到具有匹配 taint 的节点上

3.2 污点(Taint)

  1. Ⅰ、 污点 ( Taint ) 的组成
  2. 使用 kubectl taint 命令可以给某个 Node 节点设置污点,Node 被设置上污点之后就和 Pod 之间存在了一种相
  3. 斥的关系,可以让 Node 拒绝 Pod 的调度执行,甚至将 Node 已经存在的 Pod 驱逐出去
  4. 每个污点的组成如下:
  5. 每个污点有一个 key value 作为污点的标签,其中 value 可以为空,effect 描述污点的作用。当前 taint
  6. key=value:effect
  7. effect 支持如下三个选项:
  8. NoSchedule :表示 k8s 将不会将 Pod 调度到具有该污点的 Node
  9. PreferNoSchedule :表示 k8s 将尽量避免将 Pod 调度到具有该污点的 Node
  10. NoExecute :表示 k8s 将不会将 Pod 调度到具有该污点的 Node 上,同时会将 Node 上已经存在的 Pod
  11. 逐出去

  1. kubectl get node
  2. kubectl describe node node01.flyfish |grep Taints

image_1e4l47fbm10ssk1t14mo11ah15pj2a.png-47.6kB

3.3 污点的设置、查看和去除

  1. # 设置污点
  2. kubectl taint nodes node1.flyfish key1=value1:NoSchedule
  3. # 节点说明中,查找 Taints 字段
  4. kubectl describe pod pod-name
  5. # 去除污点
  6. kubectl taint nodes node1 key1:NoSchedule-

  1. 驱逐 node03.flyfish 节点上面的 pod
  2. kubectl taint nodes node03.flyfish check=flyfish:NoExecute
  3. 因为 此处的pod 不是使用deployment 创建的 自主式pod 驱逐就没有了

image_1e4l4ms2ekh1po11292u181van2n.png-275.8kB

3.4 容忍(Tolerations)

  1. 设置了污点的 Node 将根据 taint effectNoSchedulePreferNoScheduleNoExecute Pod 之间产生
  2. 互斥的关系,Pod 将在一定程度上不会被调度到 Node 上。 但我们可以在 Pod 上设置容忍 ( Toleration ) ,意思
  3. 是设置了容忍的 Pod 将可以容忍污点的存在,可以被调度到存在污点的 Node

  1. pod.spec.tolerations
  2. ------
  3. tolerations:
  4. - key: "key1"
  5. operator: "Equal"
  6. value: "value1"
  7. effect: "NoSchedule"
  8. tolerationSeconds: 3600
  9. - key: "key1"
  10. operator: "Equal"
  11. value: "value1"
  12. effect: "NoExecute"
  13. - key: "key2"
  14. operator: "Exists"
  15. effect: "NoSchedule"
  16. ------

  1. vim pod5.yaml
  2. ----
  3. apiVersion: v1
  4. kind: Pod
  5. metadata:
  6. name: pod-5
  7. labels:
  8. app: pod-5
  9. spec:
  10. containers:
  11. - name: pod-5
  12. image: wangyanglinux/myapp:v1
  13. tolerations:
  14. - key: "check"
  15. operator: "Equal"
  16. value: "flyfish"
  17. effect: "NoExecute"
  18. tolerationSeconds: 3600
  19. 容忍 3600s 在节点上面运行
  20. -----
  21. 驱逐node02.flyfish 上面的pod
  22. kubectl taint nodes node02.flyfish check=flyfish:NoExecute

image_1e4l5jcsi1gps1gs7qh6dgv1m4534.png-132.4kB

  1. kubectl apply -f pod5.yaml

image_1e4l5lvnv1i2m1ut118lp1hln1nuj41.png-106.7kB

  1. 其中 key, vaule, effect 要与 Node 上设置的 taint 保持一致
  2. operator 的值为 Exists 将会忽略 value
  3. tolerationSeconds 用于描述当 Pod 需要被驱逐时可以在 Pod 上继续保留运行的时间

  1. 1.当不指定 key 值时,表示容忍所有的污点 key
  2. tolerations:
  3. - operator: "Exists"
  4. 2.当不指定 effect 值时,表示容忍所有的污点作用
  5. tolerations:
  6. - key: "key"
  7. operator: "Exists"
  8. 3. 有多个 Master 存在时,防止资源浪费,可以如下设置
  9. kubectl taint nodes node01.flyfish node-role.kubernetes.io/master=:PreferNoSchedule
  10. 这样主节点上面 也可以 运行pod

image_1e4l5u8td1kkb43h1nme51ien4e.png-48.2kB

  1. 去除node02.flyfish node03.flyfish的污点
  2. kubectl taint nodes node02.flyfish check=flyfish:NoExecute-
  3. kubectl taint nodes node03.flyfish check=flyfish:NoExecute-

image_1e4l62nm81kh817ltorl1pfh5ao4r.png-188.5kB


四: kubernetes的固定节点

  1. 1Pod.spec.nodeName Pod 直接调度到指定的 Node 节点上,会跳过 Scheduler 的调度策略,该匹配规则是强制匹配
  2. ----
  3. vim pod.yaml
  4. ----
  5. apiVersion: extensions/v1beta1
  6. kind: Deployment
  7. metadata:
  8. name: myweb
  9. spec:
  10. replicas: 3
  11. template:
  12. metadata:
  13. labels:
  14. app: myweb
  15. spec:
  16. nodeName: node02.flyfish
  17. containers:
  18. - name: myweb
  19. image: wangyanglinux/myapp:v1
  20. ports:
  21. - containerPort: 80
  22. ----
  23. kubectl apply -f pod.yaml
  24. kubectl get pod -o wide
  25. 强制pod 运行在node02.flyfish上面

image_1e4l76pp3cro2km17ks62v17jk58.png-123.6kB


  1. Pod.spec.nodeSelector:通过 kubernetes label-selector 机制选择节点,由调度器调度策略匹配 label
  2. 而后调度 Pod 到目标节点,该匹配规则属于强制约束
  3. ----
  4. vim pod1.yaml
  5. -----
  6. apiVersion: extensions/v1beta1
  7. kind: Deployment
  8. metadata:
  9. name: myweb222
  10. spec:
  11. replicas: 2
  12. template:
  13. metadata:
  14. labels:
  15. app: myweb
  16. spec:
  17. nodeSelector:
  18. disk: ssd
  19. containers:
  20. - name: myweb
  21. image: wangyanglinux/myapp:v1
  22. ports:
  23. - containerPort: 80
  24. ----
  25. kubectl apply -f pod1.yaml
  26. 必须存在labels diskssd 才能运行pod

image_1e4l7o90urpra5n1rda19hu1qjj5l.png-102.8kB

  1. node03.flyfish 打上 disk:ssd 标签
  2. kubectl label node node03.flyfish disk=sshd
  3. kubectl get pod -o wide

image_1e4l7ul8sonut3q1igl1ubu9ha62.png-30.7kB

image_1e4l7v73g1vpoial1lt19r2346f.png-167kB


添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注