[TOC]
 
0x01 Scheduler-任务调度器 Q: 什么是Scheduler? 
答: Scheduler美 /ˈskedʒuːlər/是 kubernetes 中的调度器组件, 其主要任务是把指定的Pod分配到集群工作节点(或者说非污点节点)之上; 他是作为单独的程序运行的启动之后会一直和APIServer持续连接,当然有 pod 的资源清单中  Pod.Spec.NodeName 为空的时候,对每个pod都会创建一个binding,表明该 pod 应该放到哪个节点上
 
Tips: 由于Pod调度策略的随机性,其目的是自定义Pod调度到哪一个节点;
Q: 实现 Scheduler 调度器需要考虑的问题? 
1.公平: 如何保证每个节点都能被分配. 2.资源高效利用: 集群所有资源最大化被使用. 3.效率: 调度的性能要好,能够尽快地对大批量的pod 完成调度工作. 4.灵活: 允许用户根据自己的需求控制调度的逻辑.
 
 
1.调度基础概念 (1)调度过程(构成部分)说明: 
1.首先是过滤掉不满足条件的节点,这个过程称为 predicate 英 /ˈprɛdɪˌkeɪt/ - v. 使……基于; 
2.然后对通过的节点按照优先级排序,这个过程称为priority 英 /praɪˈɒrəti/ - n. 优先;优先权; 
3.最后从中选择优先级最高的节点。 
 
Tips: 如果中间任何一步骤有错误就直接返回错误;
Predicate 系列的算法 
PodFitsResources :节点上剩余的资源是否大于 pod请求的资源 
PodFitsHost :如果pod指定了NodeName,检查节点名称是否和NodeName相匹配 
PodFitsHostPorts :节点上已经使用的port是否和 pod申请的port冲突 
PodSelectorMatches : 过滤掉 和 pod 指定 的label 不匹配的节点 
NoDiskConflict : 已经 mount 的 volume 和 pod 指定的 volume 不冲突,除非它们都是只读 
 
 
 
priority 选项  描述: 优先级由一系列键值对组成,键是该优先级项的名称,值是它的权重(非常重要)一般得权重越高即优先级越高,通过算法对所有的优先级项目和权重进行计算得出最终的结果; 这些优先级选项包括:
LeastRequestedPriority : 通过计算CPU和 Memory 的使用率来决定权重,使用率越低权重越高。这个优先级指标倾向于资源使用比例更低的节点; 
BalancedResourceAllocation : 节点上 CPU 和 Memory 使用率越接近,权重越高,该项需要与LeastRequestedPriority一起使用不能单独使用;
      
  
      
        
      
        
        [TOC]
 
0x01 Scheduler-任务调度器 Q: 什么是Scheduler? 
答: Scheduler美 /ˈskedʒuːlər/是 kubernetes 中的调度器组件, 其主要任务是把指定的Pod分配到集群工作节点(或者说非污点节点)之上; 他是作为单独的程序运行的启动之后会一直和APIServer持续连接,当然有 pod 的资源清单中  Pod.Spec.NodeName 为空的时候,对每个pod都会创建一个binding,表明该 pod 应该放到哪个节点上
 
Tips: 由于Pod调度策略的随机性,其目的是自定义Pod调度到哪一个节点;
Q: 实现 Scheduler 调度器需要考虑的问题? 
1.公平: 如何保证每个节点都能被分配. 2.资源高效利用: 集群所有资源最大化被使用. 3.效率: 调度的性能要好,能够尽快地对大批量的pod 完成调度工作. 4.灵活: 允许用户根据自己的需求控制调度的逻辑.
 
 
1.调度基础概念 (1)调度过程(构成部分)说明: 
1.首先是过滤掉不满足条件的节点,这个过程称为 predicate 英 /ˈprɛdɪˌkeɪt/ - v. 使……基于; 
2.然后对通过的节点按照优先级排序,这个过程称为priority 英 /praɪˈɒrəti/ - n. 优先;优先权; 
3.最后从中选择优先级最高的节点。 
 
Tips: 如果中间任何一步骤有错误就直接返回错误;
Predicate 系列的算法 
PodFitsResources :节点上剩余的资源是否大于 pod请求的资源 
PodFitsHost :如果pod指定了NodeName,检查节点名称是否和NodeName相匹配 
PodFitsHostPorts :节点上已经使用的port是否和 pod申请的port冲突 
PodSelectorMatches : 过滤掉 和 pod 指定 的label 不匹配的节点 
NoDiskConflict : 已经 mount 的 volume 和 pod 指定的 volume 不冲突,除非它们都是只读 
 
 
 
priority 选项  描述: 优先级由一系列键值对组成,键是该优先级项的名称,值是它的权重(非常重要)一般得权重越高即优先级越高,通过算法对所有的优先级项目和权重进行计算得出最终的结果; 这些优先级选项包括:
LeastRequestedPriority : 通过计算CPU和 Memory 的使用率来决定权重,使用率越低权重越高。这个优先级指标倾向于资源使用比例更低的节点; 
BalancedResourceAllocation : 节点上 CPU 和 Memory 使用率越接近,权重越高,该项需要与LeastRequestedPriority一起使用不能单独使用;  
1 2 3 4 Node1:CPU 占用 20% , Memory 占用 60 %; Node2: CPU 占用 50% , Memory 占用 50 %; 
 
ImageLocalityPriority : 倾向于已经有要使用镜像的节点,镜像总大小值越大,权重越高 
 
 
 
Tips: 如果在 predicate 过程中没有合适的节点,pod 会一直在 pending 状态,不断重试调度直到有节点满足条件(后面将会进行实践)。之后如果有多个节点满足此条件就继续 priorities 过程按照优先级大小对节点排序;
2.自定义调度器 描述: 除了 kubernetes 自带的调度器开发者也可以编写自己的调度器, 通过 spec:schedulername 参数指定调度器的名字,可以为 pod 选择某个调度器进行调度;
Kubernetes也允许用户编写自己的调度器组件,并在创建资源的时候引用它。多个调度器可以同时运行和工作,只要名字不冲突, Kubernetes提供的调度器名字是default。
例如: 使用某个调度器就是在Pod的spec.schedulername字段中填写上调度器的名字。如果自定义的调度器名字是my-scheduler,那么只有当spec.schedulername字段是my-scheduler才会被调度;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #!/bin/bash SERVER='localhost:8001'  while  true ;do     for  PODNAME in  $(kubectl --server $SERVER  get pods -o json | jq '.items[] | select(.spec.schedulerName == "my-scheduler") | select(.spec.nodeName == null) | .metadata.name'  | tr -d '"' ) ;     do          NODES=($(kubectl --server $SERVER  get nodes -o json | jq '.items[].metadata.name'  | tr -d '"' ))         NUMNODES=${#NODES[@]}          CHOSEN=${NODES[$[ $RANDOM % $NUMNODES ]]}          curl --header "Content-Type:application/json"  --request POST --data '{"apiVersion":"v1", "kind": "Binding", "metadata": {"name": "' $PODNAME '"}, "target": {"apiVersion": "v1", "kind"  : "Node", "name": "' $CHOSEN '"}}'  http://$SERVER /api/v1/namespaces/default/pods/$PODNAME /binding/        echo  "Assigned $PODNAME  to $CHOSEN "      done      sleep 1 done 
 
 
3.nodeAffinity - 节点亲和性 资源对象: pod.spec.nodeAffinity1 2 软策略  :  ·preferredDuringSchedulingIgnoredDuringExecution:  【我想要去这个节点】  -  adj.  优先的;首选的 硬策略  :  ·requiredDuringschedulinglgnoredDuringExecution:  【我一定要去这个节点】  -  adj.  必需的;(美)必修的 
什么是Pod调度的软策略以及硬策略? 
1.软策略: 即希望 , 表示想到满足条件的节点上去,当不满足时候就到其它节点上去。 2.硬策略: 即强制 , 表示一定到某一个节点上去, 当不满足条件时候其哪一个节点也不去,注意其优先级高于软策略;
 
键值运算关系(即operator的可用值): 
In:     label 的值在某个列表中 
NotIn:  label 的值不在某个列表中 
Gt:     label 的值大于某个值 
Lt:     label 的值小于某个值 
Exists: 某个label存在 
DoesNotExist: 某个label不存在 
 
硬策略 资源清单: affinity-strong-demo.yaml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 cat  > affinity-strong-demo.yaml<<'EOF' apiVersion:  v1  kind:  Pod  metadata:   name:  strong-affinity    labels:     app:  node-strong-affinity-pod  spec:   containers:   - name:  with-strong-node-affinity      image:  harbor.weiyigeek.top/test/busbox:latest     imagePullPolicy:  IfNotPresent     command:  ["/bin/sh","-c","sleep  700 "]   restartPolicy: Never          # 重启策略   affinity:                     # 亲和性     nodeAffinity:               # 节点亲和性       requiredDuringSchedulingIgnoredDuringExecution:  # 硬策略(必须得)         nodeSelectorTerms:          # 节点选择条件         - matchExpressions:         # 匹配表达式           - key: kubernetes.io/hostname   # Key 值             operator: NotIn          # 表达式 表示 Node主机名称不能是k8s-node-4即表示不能在node-4的节点上运行该Pod;             values:             - k8s-node-4             # Value 值 EOF 
操作示例: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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 ~/K8s/Day9/demo1$ kubectl create -f affinity-strong-demo.yaml    $ kubectl get pod -o wide --show-labels       ~/K8s/Day9/demo1$ kubectl delete -f affinity-strong-demo.yaml       $ vim affinity-strong-demo.yaml ~/K8s/Day9/demo1$ kubectl create -f affinity-strong-demo.yaml ~/K8s/Day9/demo1$ kubectl get pod -o wide --show-labels       ~/K8s/Day9/demo1$ kubectl create -f affinity-strong-demo-2.yaml    ~/K8s/Day9/demo1$ kubectl get pod -o wide       
软策略 资源清单: affinity-soft-demo.yaml1 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 cat  > affinity-soft-demo.yaml<<'EOF' apiVersion:  v1  kind:  Pod  metadata:   name:  soft-affinity    labels:     app:  node-soft-affinity-pod  spec:   containers:   - name:  with-soft-node-affinity      image:  harbor.weiyigeek.top/test/busbox:latest     imagePullPolicy:  IfNotPresent     command:  ["/bin/sh","-c","sleep  700 "]   restartPolicy: Never          # 重启策略   affinity:                     # 亲和性     nodeAffinity:               # 节点亲和性       preferredDuringSchedulingIgnoredDuringExecution:  # 软策略(优先级首选得)       - weight: 1               # 权重(越高其匹配优先级越高)         preference:             # 偏向           matchExpressions:     # 匹配表达式           - key: source         # Key 值             operator: In        # 表达式               values:              - k8s-node-3        # Value 值  表示 最想匹配到node3节点       - weight: 2               # 权重(越高其匹配优先级越高)         preference:             # 偏向           matchExpressions:     # 匹配表达式           - key: source         # Key 值             operator: NotIn        # 表达式               values:              - k8s-node-4        # Value 值  表示 不想匹配到node4节点 EOF 
操作示例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ~/K8s/Day9/demo1$ kubectl create -f affinity-soft-demo.yaml    ~/K8s/Day9/demo1$ kubectl get pod -o wide                                                          ~/K8s/Day9/demo1$ kubectl delete -f affinity-soft-demo-1.yaml && kubectl create -f affinity-soft-demo-1.yaml && sleep 10 && kubectl get pod -o wide       
硬软策略联使 描述 : 硬策略与软策略(required & preferred)可以组合相互进行使用; 资源清单: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 cat  > requiredpreferred-strategy.yaml<<'END' apiVersion:  v1  kind:  Pod  metadata:   name:  affinity    labels:     app:  node-affinity-pod  spec:   containers:   - name:  with-node-affinity      image:  harbor.weiyigeek.top/test/busbox:latest     imagePullPolicy:  IfNotPresent     command:  ["/bin/sh","-c","sleep  700 "]   affinity:     nodeAffinity:                                         # 节点亲和性       requiredDuringSchedulingIgnoredDuringExecution:     # 硬策略         nodeSelectorTerms:         - matchExpressions:           - key: kubernetes.io/hostname              operator: NotIn              values:             - k8s-node02        preferredDuringSchedulingIgnoredDuringExecution:    # 软策略       - weight: 1          preference:           matchExpressions:           - key: kubernetes.io/hostname             operator: In              values:             - k8s-node03 END 
Tips : 该Pod一定不能调度到k8s-node02节点,但如果k8s-node03可以被调度时便会调度到k8s-node03节点;
固定节点调度策略(fixed) 描述: 上述讲了亲和性来选择运行的节点,如果想要Pod运行在指定的节点之上就需要按照下述进行设置固定调度的节点;
主要有以下资源对象字段设置Pod运行的固定节点:
1) spec.template.spec.nodeName 
2) pod.spec.nodeSelector 
 
方式1.资源清单示例: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 cat  > fixed-node-test.yaml <<'EOF' apiVersion:  apps/v1 kind:  Deployment  metadata:   name:  fixed-node-test   labels:     app:  fixed-node spec:   replicas:  5   selector:                       matchLabels:         app:  fixed-node           template:     metadata:       labels:         app:  fixed-node     spec:       nodeName:  k8s-node-4             containers:       - name:  fixed-node          image:  harbor.weiyigeek.top/test/busbox:latest         imagePullPolicy:  IfNotPresent         command:  ["/bin/sh","-c","sleep  700 "]         ports:         - containerPort: 80 EOF 
操作流程:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ~/K8s/Day9/demo2$ kubectl create -f fixed-node-test.yaml    ~/K8s/Day9/demo2$ kubectl get pod                      ~/K8s/Day9/demo2$ kubectl get pod -o wide                   
方式2.资源清单示例: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 cat  > fixed-node-test-1.yaml <<'EOF' apiVersion:  apps/v1 kind:  Deployment metadata:   name:  fixed-node-test-1   labels:     app:  fixed-node-1 spec:   replicas:  5   selector:                         matchLabels:         app:  fixed-node-1           template:     metadata:       labels:         app:  fixed-node-1     spec:       nodeSelector:         nodetype:  fixed                  containers:       - name:  fixed-node-1         image:  harbor.weiyigeek.top/test/busbox:latest         imagePullPolicy:  IfNotPresent         command:  ["/bin/sh","-c","sleep  700 "]         ports:         - containerPort: 80       # 容器暴露端口  EOF 
部署流程:
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 34 35 36 37 38 39 ~/K8s/Day9/demo2$ kubectl label node k8s-node-5 nodetype=fixed kubectl get node --show-labels              ~/K8s/Day9/demo2$ kubectl create -f fixed-node-test-1.yaml ~/K8s/Day9/demo2$ kubectl get pod -o wide                     kubectl label node k8s-node-4 nodetype=fixed    ~/K8s/Day9/demo2$ kubectl scale --replicas=7 deploy fixed-node-test-1    ~/K8s/Day9/demo2$ kubectl get pod -o wide | grep "fixed-node-test-1"                       
 
 
4.podAffinity - Pod 亲和性 描述: 同样PodAffinity也有软策略和硬策略其解释与节点亲和性相同;1 2 3 软策略 :* preferredDuringSchedulinglgnoredDuringExecution 硬策略 : * requiredDuringSchedulinglgnoredDuringExecution 
资源清单示例: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 34 35 36 cat  > pod-affinity-demo-1.yaml <<'EOF' apiVersion:  v1  kind:  Pod  metadata:   name:  pod-affinity-demo1    labels:     app:  pod-affinity spec:   containers:   - name:  pod-affinity     image:  harbor.weiyigeek.top/test/busbox:latest     imagePullPolicy:  IfNotPresent     command:  ["/bin/sh","-c","sleep  700 "]   affinity:     podAffinity:  # Pod 亲和性       requiredDuringSchedulingIgnoredDuringExecution: # 硬亲和       - labelSelector:       # 标签选择器           matchExpressions:  # 匹配规则           - key: app                operator: In     # 表示 匹配标签为app=node-soft-affinity-pod 的Pod在哪一个节点之上             values:             - node-soft-affinity-pod           topologyKey: kubernetes.io/hostname      podAntiAffinity:  # Pod 反亲和       preferredDuringSchedulingIgnoredDuringExecution:  # 软亲和       - weight: 1          podAffinityTerm:           labelSelector:             matchExpressions:             - key: app                operator: In             # 表示 匹配标签为`app=node-strong-affinity-pod`的 Pod 在哪一个节点之上               values:               - node-strong-affinity-pod           topologyKey: kubernetes.io/hostname EOF 
温馨提示: 什么是 topologyKey? 个人理解 pod affinity 的调度范围为 topology。
官方解释:如果该X已经在运行一个或多个满足规则Y的Pod,则该Pod应该(或者在非亲和性的情况下不应该)在 X 中运行,Y 表示为LabelSelector规则, X 是一个拓扑域,例如节点,机架,云提供者区域,云提供者区域等。您可以使用topologyKey这是系统用来表示这种拓扑域的节点标签的密钥。
操作流程: 1 2 3 4 5 6 7 8 9 10 ~/K8s/Day9/demo1$ kubectl create -f pod-affinity-demo-1.yaml    ~/K8s/Day9/demo1$ kubectl get pod --show-labels -o wide             
PS : 在使用Pod亲和性时有一个问题需要非常重视即,与之匹配Pod必须是RUNNING状态,否则认为不满足调度条件则Pod将会被置为Pending状态;
节点与Pod的Affinity亲和性总结:  描述: 节点与Pod亲和性/反亲和性调度策略比较如下。1 2 3 4 nodeAffinity    主机     In, NotIn, Exists,DoesNotExist, Gt, Lt  否     指定主机 podAffinity     POD      In, NotIn, Exists,DoesNotExist          是     POD与指定POD同一拓扑域 podAnitAffinity POD      In, NotIn, Exists,DoesNotExist          是     POD与指定POD不在同一拓扑域 
补充说明.解决负载不均衡的问题, 可以给Pod容器设置反亲和,让这些容器平均的分布在各个节点上(不要聚在一起) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 affinity:   nodeAffinity:     requiredDuringSchedulingIgnoredDuringExecution:       nodeSelectorTerms:       - matchExpressions:         - key:  node           operator:  In           values:           -  work   podAntiAffinity:     preferredDuringSchedulingIgnoredDuringExecution:     - podAffinityTerm:         labelSelector:           matchExpressions:           - key:  app             operator:  In             values:             -  nginx         topologyKey:  kubernetes.io/hostname       weight:  100 
5.Priority - Pod 优先级 描述: 与前面所讲的调度优选策略中的优先级(Priorities)不同,前文所讲的优先级指的是节点优先级,而pod priority指的是Pod的优先级,高优先级的Pod会优先被调度,或者在资源不足低情况牺牲低优先级的Pod以便于重要的Pod能够得到资源部署。
为了定义Pod优先级,需要先定义PriorityClass对象,该对象没有Namespace限制,官网示例:1 2 3 4 5 6 7 8 9 10 11 12 ~$ kubectl api-resources | grep "priorityclasses"  priorityclasses   pc   scheduling.k8s.io   false    PriorityClass apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata:   name: high-priority value: 1000000 globalDefault: false  description: "This priority class should be used for XYZ service pods only."  
然后通过在Pod的spec. priorityClassName中指定已定义的PriorityClass名称即可:1 2 3 4 5 6 7 8 9 10 11 12 apiVersion: v1 kind: Pod metadata:   name: nginx   labels:     env: test  spec:   containers:   - name: nginx     image: nginx     imagePullPolicy: IfNotPresent   priorityClassName: high-priority 
6.Preemption - Pod 抢占 描述: 当节点没有足够的资源供调度器调度Pod、导致Pod处于pending时,抢占(preemption)逻辑会被触发。Preemption会尝试从一个节点删除低优先级的Pod,从而释放资源使高优先级的Pod得到节点资源进行部署。
 
0x02 Taints - 污点 描述: 前面我们讲述到节点亲和性是pod的一种属性(偏好或硬性要求), 它可以使得pod运行在满足条件的特定节点之上;
Q: 那什么又是Taint(污点)? 
答: Taint 恰恰与之相反, 它使节点能够排斥一类特定的pod。注意每个节点上都可以应用一个或多个taint, 如果设置了容忍的Pod将可以容忍污点的存在,可以被调度到存在污点的 Node 上;
 
Tips : 使用 kubectl 的 taint 命令可以给某个Node节点设置污点,Node被设置上污点之后就和Pod之间存在了一种相斥的关系,可以让Node拒绝 Pod 的调度执行,甚至将Node已经存在的Pod驱逐出去;1 2 3 4 5 6 7 8 kubectl taint node [nodeName] key=value:[effect]    * NoSchedule : 表示k8s将不会将Pod 调度到具有该污点的 Node 上; * PreferNoSchedule : 表示k8s将尽量避免将Pod调度到具有该污点的 Node 上; * NoExecute : 表示k8s将不会将 Pod调度到具有该污点的Node上,同时会将Node上已经存在的 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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 $ kubectl describe node master1| grep "Taints"       $ kubectl get no -o yaml | grep taint -A 5   $ kubectl taint nodes node1 key1=value1:NoSchedule  $ kubectl taint nodes master1 node-role.kubernetes.io/master=:NoSchedule kubectl taint nodes node1 key1:NoSchedule-      $ kubectl taint nodes k8s-master-1 node-role.kubernetes.io/master=:NoSchedule-    $ kubectl describe node k8s-master-1 | grep "Taints"     $ kubectl get node --show-labels             ~/K8s/Day9/demo1$ kubectl get no k8s-node-5 -o yaml | grep "key"  -C 3                      $ kubectl taint nodes k8s-node-5 node-role.kubernetes.io/master-    
补充操作: 1 2 3 4 5 6 7 8 9 [root@master1 ~]$ kubectl taint nodes --all node-role.kubernetes.io/master-                kubectl get no -o yaml | grep taint -A 5 
Tips : 为 master 设置的这个 taint 中node-role.kubernetes.io/master为 key/value 为空 effect 为NoSchedule; Tips : 如果输入命令时你丢掉了= 符号, 写成了node-role.kubernetes.io/master:NoSchedule, 会报 error: at least one taint update is required 错误;
 
0x03 Toleration - 容忍 Q: 什么是Toleration容忍? 
答: 即表示这些 pod 可以(但不要求)被调度到具有匹配 taint 的节点上, 简单的说
 
Tips: Taint 和 Toleration 相互配合可以用来避免pod被分配到不合适的节点上。表示对于那些不能容忍这些 taint 的 pod 是不会被该节点接受的, 但是针对 Pod 没有节点运行时可以选一台污点的节点运行Pod;
在 pod 的 spec 中设置 tolerations 字段:1 2 3 4 5 6 7 8 9 10 11 12 13 tolerations: - operator:  "Exists" tolerations: - key:  "key"   operator:  "Exists" ~$  kubectl  describe  pod Tolerations:  node.kubernetes.io/not-ready:NoExecute  op=Exists  for  300 s              node.kubernetes.io/unreachable:NoExecute  op=Exists  for  300 s  
Tolerations 资源清单演示:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 tolerationstolerations: - 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:  "node-role.kubernetes.io/master"     operator:  "Equal"       value:  ""    effect:  "PreferNoSchedule"              
操作实例: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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 kubectl  taint  nodes  Node-Name  node-role.kubernetes.io/master=:PreferNoSchedule kubectl  taint  nodes  k8s-master-4  node-role.kubernetes.io/master=:NoExecute    $  kubectl  get  pod  -o  wide       ~/K8s/Day9/demo1$  kubectl  get  no  k8s-node-4  -o  yaml  | grep "key" -C 3   - 10.244.1.0/24   taints:   - effect:  NoSchedule     key:  node-role.kubernetes.io/master   status:   addresses:   - address:  10.10 .107 .214 cat  > taint-Tolerations-mode.yaml <<'EOF' apiVersion:  v1 kind:  Pod metadata:   name:  taint-tolerations   labels:     app:  taint-tolerations-mode spec:   containers:   - name:  with-soft-node-affinity     image:  harbor.weiyigeek.top/test/busbox:latest     imagePullPolicy:  IfNotPresent     command:  ["/bin/sh","-c","sleep  700 "]   restartPolicy: Never                # 重启策略(绝不除非移除退出)   tolerations:                           - key: " kubernetes.io/hostname"     operator:  "Equal"                      value:  "k8s-node-5"     effect:  "NoExecute" EOF ~/K8s/Day9/demo1$  kubectl  create  -f  taint-Tolerations-mode.yaml    ~/K8s/Day9/demo1$  kubectl  get  pod  -o  wide       ~/K8s/Day9/demo1$  kubectl  taint  nodes  k8s-node-4  node-role.kubernetes.io/master=:NoSchedule ~/K8s/Day9/demo1$  kubectl  taint  nodes  k8s-node-5  node-role.kubernetes.io/master=:NoSchedule ~/K8s/Day9/demo1$  kubectl  delete  -f  taint-Tolerations-mode.yaml ~/K8s/Day9/demo1$  kubectl  get  pod  -o  wide       
 
0x04 Cordon - Node 隔离与恢复 描述: 在某些场景下需要对Node进行隔离,比如硬件升级或者维护,目前隔离的Node有两种方式。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 $ kubectl get node | grep "224"     $ kubectl cordon weiyigeek-224    $ kubectl get node        $ ansible weiyigeek-224 -m shell -a "docker ps"                          ~$ kubectl uncordon weiyigeek-224    ~$ kubectl get node | grep "224"     
 
FAQ - 知识扩展 Q:普通用户有自定义Pod优先级的权限吗? 
A:可以,Pod优先级定义与创建普通Pod类似,并没有特别权限控制。定义Pod优先级,需要先定义kind为PriorityClass类型的资源对象,然后通过在Pod的spec. priorityClassName中指定已定义的PriorityClass名称即可。
 
Q:Kubernetes scheduler extender能介绍一下么? 
A:extender可理解为Kubernetes调度策略和算法的扩展,属于自定义调度器的一种方式,与Kubernetes默认调度器的过程类似,主要是针对一些不算受集群本身控制的资源(比如网络),需要通过外部调用来进行调度的情况。
 
Q:用户使用了NodeSelector指定了Pod调度的node节点后,如果node不可用,那么scheduler会采用别的策略吗? 
A:nodeSelector是目前最为简单的一种pod运行时调度限制,目前在Kubernetes 1.7.x及以下版本可用。Pod.spec.nodeSelector通过kubernetes的label-selector机制选择节点,由调度器调度策略匹配label,而后调度Pod到目标节点,该匹配规则属于强制约束,如果node不可用,Pod会一直处于pending状态。nodeAffinity具备nodeSelector的全部功能,所以未来Kubernetes会将nodeSelector废除。
 
Q: 如何让多个Pod均匀部署到各个节点上? 描述: 通过前面学习我们知道在K8S中kube-scheduler组件负责Pod的调度对每一个新创建的 Pod 或者是未被调度的 Pod,kube-scheduler 会选择一个最优的节点去运行这个 Pod,那我们如何将Pod部署到各个节点上呢?
通常两种方式,首先考虑使用工作负载反亲和特性让Pod之间尽量“互斥”,其次是可以使用daemonsets.apps资源控制器管理Pod资源,这样就能尽量均匀的分布在各节点上。1 2 3 4 5 6 7 8 9 10 11 12 13 14 affinity:   podAntiAffinity:                                           preferredDuringSchedulingIgnoredDuringExecution:           - podAffinityTerm:           labelSelector:                                             matchExpressions:               - key: app                 operator: In                 values:                   - nginx           namespaces:             - default           topologyKey: kubernetes.io/hostname