[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