Kubernetes Pod调度说明

简介

Scheduler 是 Kubernetes 的调度器,主要任务是把定义的Pod分配到集群的节点上,听起来非常简单,但要考虑需要方面的问题:

  • 公平:如何保证每个节点都能被分配到资源
  • 资源高效利用:集群所有资源最大化被使用
  • 效率:调度性能要好,能够尽快的对大批量的Pod完成调度工作
  • 灵活:允许用户根据自己的需求控制调度的流程

Scheduler 是作为单独的服务运行的,启动之后会一直监听API Server,获取 podSpec.NodeName为空的Pod,对每个Pod都会创建一个buiding,表明该Pod应该放在哪个节点上

调度过程

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

Predicate有一系列的算法可以使用:
  • PodFitsResources:节点上剩余的资源是否大于 Pod 请求的资源
  • PodFitsHost:如果Pod指定了nodeName,检查节点名称是否和nodeName匹配
  • PodFitsHostPort:节点上已经使用的port是否和Pod申请的port冲突
  • PodSelectorMatches:过滤和Pod指定的 label 不匹配的节点
  • NoDiskConflict:已经 mount 的 volume 和 Pod 指定的volume不冲突,除非他们都是只读

如果在predicate过程中没有适合的节点,Pod会一直处于Pending状态,不断重新调度,直到有节点满足条件,经过这个步骤,如果多个节点满足条件,就会进入priority过程:按照优先级大小对节点排序,优先级由一系列键值对组成,键是该优先级的名称,值是它的权重,这些优先级选项包括:

  • LeastRequestedPriority:通过计算CPU和Memory的使用率来决定权重,使用率越低权重越高,换句话说,这个优先级倾向于资源使用率低的节点
  • BalanceResourceAllocation:节点上CPU和Memory使用率非常及接近,权重就越高,这个要和上边的一起使用,不可单独使用
  • ImageLocalityPriority:倾向于已经要使用镜像的节点,镜像的总大小值越大,权重越高

通过算法对所有的优先级项目和权重进行计算,得出最终的结果

自定义调度器

除了Kubernetes自带的调度器,也可以编写自己的调度器,通过spec.schedulername参数指定调度器的名字,可以为Pod选择某个调度器进行调度,比如下边的Pod选择my-scheduler进行调度,而不是默认的default-scheduler

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: scheduler-test
  5. labels:
  6. name: example-scheduler
  7. spec:
  8. schedulername: my-scheduler
  9. containers:
  10. - name: Pod-test
  11. image: nginx:v1

一、亲和性

注意,以下所有的测试都是1Master、1Node的情况下:

  1. [root@Centos8 scheduler]# kubectl get node
  2. NAME STATUS ROLES AGE VERSION
  3. centos8 Ready master 134d v1.15.1
  4. testcentos7 Ready <none> 133d v1.15.1

1、节点亲和性

pod.spec.affinity.nodeAffinity

  • preferredDuringSchedulingIgnoredDuringExecution:软策略

    • 软策略是偏向于,更想(不)落在某个节点上,但如果实在没有,落在其他节点也可以
  • requiredDuringSchedulingIgnoredDuringExecution:硬策略
    • 硬策略是必须(不)落在指定的节点上,如果不符合条件,则一直处于Pending状态
requiredDuringSchedulingIgnoredDuringExecution硬策略

vim node-affinity-required.yaml

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: affinity-required
  5. labels:
  6. app: node-affinity-pod
  7. spec:
  8. containers:
  9. - name: with-node-required
  10. image: nginx:1.2.1
  11. imagePullPolicy: IfNotPresent
  12. affinity:
  13. nodeAffinity:
  14. requiredDuringSchedulingIgnoredDuringExecution:
  15. nodeSelectorTerms:
  16. - matchExpressions:
  17. - key: kubernetes.io/hostname #节点名称
  18. operator: NotIn #不是
  19. values:
  20. - testcentos7 #node节点
  1. [root@Centos8 ~]# kubectl get node --show-labels #查看node节点标签
  2. NAME STATUS ROLES AGE VERSION LABELS
  3. centos8 Ready master 133d v1.15.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=centos8,kubernetes.io/os=linux,node-role.kubernetes.io/master=
  4.  
  5. testcentos7 Ready <none> 133d v1.15.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=testcentos7,kubernetes.io/os=linux
  6.  
  7. ## 目前只有两个节点,一个master 一个node,策略中表示此Pod不在testcentos7这个节点上
  8. ## Pod创建之后,因为除去testcentos7节点已再无其他node,所以一直处于Pending状态

  9. [root@Centos8 scheduler]# kubectl create -f node-affinity-required.yaml
  10. pod/affinity-required created
  11. [root@Centos8 scheduler]# kubectl get pod
  12. NAME READY STATUS RESTARTS AGE
  13. affinity-required / Pending 4s
  14.  
  15. [root@Centos8 scheduler]# kubectl describe pod affinity-required
  16. default-scheduler / nodes are available: node(s) didn't match node selector, 1 node(s) had taints that the pod didn't tolerate.

将yaml文件中,NotIn改为In

  1. affinity:
  2. nodeAffinity:
  3. requiredDuringSchedulingIgnoredDuringExecution:
  4. nodeSelectorTerms:
  5. - matchExpressions:
  6. - key: kubernetes.io/hostname #节点名称
  7. operator: In #是,存在
  8. values:
  9. - testcentos7 #node节点

再次创建,已经落在指定node节点中

  1. [root@Centos8 scheduler]# kubectl get pod -o wide
  2. NAME READY STATUS RESTARTS AGE IP NODE
  3. affinity-required / Running 11s 10.244.3.219 testcentos7
preferredDuringSchedulingIgnoredDuringExecution软策略

vim node-affinity-preferred.yaml

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: affinity-preferred
  5. labels:
  6. app: node-affinity-pod
  7. spec:
  8. containers:
  9. - name: with-node-preferred
  10. image: nginx:1.2.
  11. imagePullPolicy: IfNotPresent
  12. affinity:
  13. nodeAffinity:
  14. preferredDuringSchedulingIgnoredDuringExecution:
  15. - weight: #权重为1,软策略中权重越高匹配到的机会越大
  16. preference: #更偏向于
  17. matchExpressions:
  18. - key: kubernetes.io/hostname #node名称
  19. operator: In #等于,为
  20. values:
  21. - testcentos7 #node真实名称
  1. ## 更想落在node节点名称为testcentos7的node中
  2. [root@Centos8 scheduler]# kubectl create -f node-affinity-prefered.yaml
  3. pod/affinity-prefered created
  4.  
  5. [root@Centos8 scheduler]# kubectl get pod -o wide
  6. NAME READY STATUS RESTARTS AGE IP NODE
  7. affinity-prefered / Running 9s 10.244.3.220 testcentos7

更改一下策略,将node节点名称随便更改为不存在的node名称,例如kube-node2

  1. affinity:
  2. nodeAffinity:
  3. preferredDuringSchedulingIgnoredDuringExecution:
  4. - weight: #权重为1,软策略中权重越高匹配到的机会越大
  5. preference: #更偏向于
  6. matchExpressions:
  7. - key: kubernetes.io/hostname #node名称
  8. operator: In #等于,为
  9. values:
  10. - kube-node2 #node真实名称
  1. [root@Centos8 scheduler]# kubectl create -f node-affinity-prefered.yaml
  2. pod/affinity-prefered created
  3.  
  4. ##创建后,同样是落在了testcentos7节点上,虽然它更想落在kube-node2节点上,但没有,只好落在testcentos7节点中
  5. [root@Centos8 scheduler]# kubectl get pod -o wide
  6. NAME READY STATUS RESTARTS AGE IP NODE
  7. affinity-prefered / Running 17s 10.244.3.221 testcentos7
软硬策略合体

vim node-affinity-common.yaml

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: affinity-node
  5. labels:
  6. app: node-affinity-pod
  7. spec:
  8. containers:
  9. - name: with-affinity-node
  10. image: nginx:v1
  11. imagePullPulicy: IfNotPresent
  12. affinity:
  13. nodeAffinity:
  14. requiredDuringSchedulingIgnoredDuringExecution:
  15. nodeSelectorTerms:
  16. - matchExpressions:
  17. - key: kubernetes.io/hostname
  18. operator: NotIn
  19. values:
  20. - k8s-node2
  21. preferredDuringSchedulingIgnoredDuringExecution:
  22. - weight:
  23. preference:
  24. matchExpressions:
  25. - key: source
  26. operator: In
  27. values:
  28. - hello

软硬结合达到一个更为准确的node选择,以上文件意思为此Pod必须不存在k8s-node2节点中,其他的节点都可以,但最好落在label中source的值为hello的节点中

键值运算关系
  • In:label 的值在某个列表里
  • NotIn:label 的值不在某个列表中
  • Gt:label 的值大于某个值
  • Lt:label 的值小于某个值
  • Exists:某个 label 存在
  • DoesNotExist:某个 label 不存在

如果nodeSelectorTerms下面有多个选项,满足任何一个条件就可以了;如果matchExpressions有多个选项,则必须满足这些条件才能正常调度

2、Pod亲和性

pod.spec.affinity.podAffinity/podAntiAffinity

  • preferedDuringSchedulingIgnoredDuringExecution:软策略

    • 软策略是偏向于,更想(不)落在某个节点上,但如果实在没有,落在其他节点也可以
  • requiredDuringSchedulingIgnoredDuringExecution:硬策略
    • 硬策略是必须(不)落在指定的节点上,如果不符合条件,则一直处于Pending状态
先创建一个测试Pod

vim pod.yaml

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: pod-
  5. labels:
  6. app: nginx
  7. type: web
  8. spec:
  9. containers:
  10. - name: pod-
  11. image: nginx:1.2.
  12. imagePullPolicy: IfNotPresent
  13. ports:
  14. - name: web
  15. containerPort:
  1. [root@Centos8 scheduler]# kubectl create -f pod.yaml
  2. pod/pod- created
  3.  
  4. [root@Centos8 scheduler]# kubectl get pod --show-labels
  5. NAME READY STATUS RESTARTS AGE LABELS
  6. pod- / Running 4s app=nginx,type=web
requiredDuringSchedulingIgnoredDuringExecution Pod硬策略

vim pod-affinity-required.yaml

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: affinity-required
  5. labels:
  6. app: pod-
  7. spec:
  8. containers:
  9. - name: with-pod-required
  10. image: nginx:1.2.
  11. imagePullPolicy: IfNotPresent
  12. affinity:
  13. podAffinity: #在同一域下
  14. requiredDuringSchedulingIgnoredDuringExecution:
  15. - labelSelector:
  16. matchExpressions:
  17. - key: app #标签key
  18. operator: In
  19. values:
  20. - nginx #标签value
  21. topologyKey: kubernetes.io/hostname #域的标准为node节点的名称

以上文件策略为:此必须要和有label种app:nginx的pod在同一node下

创建测试:
  1. [root@Centos8 scheduler]# kubectl create -f pod-affinity-required.yaml
  2. pod/affinity-required created
  3.  
  4. [root@Centos8 scheduler]# kubectl get pod -o wide
  5. NAME READY STATUS RESTARTS AGE IP NODE
  6. affinity-required / Running 43s 10.244.3.224 testcentos7
  7. pod- / Running 10m 10.244.3.223 testcentos7
  8.  
  9. # 和此标签Pod在同一node节点下

将podAffinity改为podAnitAffinity,使它们不在用于node节点下

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: required-pod2
  5. labels:
  6. app: pod-
  7. spec:
  8. containers:
  9. - name: with-pod-required
  10. image: nginx:1.2.
  11. imagePullPolicy: IfNotPresent
  12. affinity:
  13. podAntiAffinity:
  14. requiredDuringSchedulingIgnoredDuringExecution:
  15. - labelSelector:
  16. matchExpressions:
  17. - key: app #标签key
  18. operator: In
  19. values:
  20. - nginx #标签value
  21. topologyKey: kubernetes.io/hostname #域的标准为node节点的名称

此策略表示,必须要和label为app:nginx的pod在不用的node节点上

创建测试:
  1. [root@Centos8 scheduler]# kubectl create -f pod-affinity-required.yaml
  2. pod/required-pod2 created
  3.  
  4. [root@Centos8 scheduler]# kubectl get pod
  5. NAME READY STATUS RESTARTS AGE
  6. affinity-required / Running 9m40s
  7. pod- / Running 19m
  8. required-pod2 / Pending 51s
  9.  
  10. ## 由于我这里只有一个节点,所以required-pod2只能处于Pending状态
preferedDuringSchedulingIgnoredDuringExecution Pod软策略
  1. vim pod-affinity-prefered.yaml
  2. ...
  3. apiVersion: v1
  4. kind: Pod
  5. metadata:
  6. name: affinity-prefered
  7. labels:
  8. app: pod-
  9. spec:
  10. containers:
  11. - name: with-pod-prefered
  12. image: nginx:v1
  13. imagePullPolicy: IfNotPresent
  14. affinity:
  15. podAntiAffinity: #不在同一个域下
  16. preferedDuringSchedulingIgnoredDuringExecution:
  17. - weight:
  18. podAffinityTerm:
  19. labelSelector:
  20. matchExpressions:
  21. - key: app
  22. operator: In
  23. values:
  24. - pod-
  25. topologyKey: kubernetes.io/hostname
  26. ...

软策略和硬策略的方法基本类似,只是添加了权重,表示更喜欢而已,也可以接受其他,在此就不再演示

亲和性/反亲和性调度策略比较如下:
调度策略 匹配标签 操作符 拓扑域支持 调度目标
nodeAffinity 主机 In,NotIn,Exists,DoesNotExists,Gt,Lt 指定主机
podAffinity Pod In,NotIn,Exists,DoesNotExists,Gt,Lt pod与指定pod在一拓扑域
podAnitAffinity Pod In,NotIn,Exists,DoesNotExists,Gt,Lt pod与指定pod不在一拓扑域

二、污点(Taint)和容忍(Toleration)

节点亲和性,是Pod的一种属性(偏好或硬性要求),它使Pod被吸引到一类特定的节点,Taint则相反,它使节点能够 排斥 一类特定的Pod

Taint与Toleration相互配合,可以用来避免Pod被分配到不合适的节点上,每个节点上都可以应用一个或两个taint,这表示对那些不能容忍这些taint和pod,是不会被该节点接受的,如果将toleration应用于pod上,则表示这些pod可以(但不要求)被调度到具有匹配taint的节点上

注意,以下所有的测试都是1Master、1Node的情况下:

  1. [root@Centos8 scheduler]# kubectl get node
  2. NAME STATUS ROLES AGE VERSION
  3. centos8 Ready master 134d v1.15.1
  4. testcentos7 Ready <none> 133d v1.15.1

1、污点(Taint)

(1)污点的组成

使用kubectl taint 命令可以给某个node节点设置污点,Node被设置上污点之后就和Pod之间存在了一种相斥的关系,可以让Node拒绝Pod的调度执行,甚至将已经存在得Pod驱逐出去

每个污点的组成如下:

  1. key=value:effect

每个污点有一个 key 和 value 作为污点标签,其中 value 可以为空,effect描述污点的作用,当前 taint effect 支持如下三个选项:

  • NoSchedule:表示 k8s 不会将Pod调度到具有该污点的Node上
  • PreferNoSchedule:表示 k8s 将尽量避免将Pod调度到具有该污点的Node上
  • NoExecute:表示 k8s 将不会将Pod调度到具有该污点的Node上,同时会将Node上已有的Pod驱逐出去
(2)污点的设置、查看和去除

k8s的master节点本身就带有污点,这也是为什么k8s在调度Pod时,不会调度到master节点的原因,具体查看如下:

  1. [root@Centos8 scheduler]# kubectl describe node centos8
  2. Taints: node-role.kubernetes.io/master:NoSchedule
  3. ## 设置污点
  4. kubectl taint nodes [node name] key1=value:NoSchedule
  5.  
  6. ## 节点说明中,查看Taint字段
  7. kubectl describe node [node name]
  8.  
  9. ## 去除污点
  10. kubectl taint nodes [node name] key1:NoSchedule-

测试效果:

  1. ## 查看当前节点所拥有Pod,都在testcentos7中
  2. [root@Centos8 scheduler]# kubectl get pod -o wide
  3. NAME READY STATUS RESTARTS AGE IP NODE
  4. affinity-required / Running 68m 10.244.3.224 testcentos7
  5. pod- / Running 78m 10.244.3.223 testcentos7
  6. required-pod2 / Pending 59m <none> <none>
  7.  
  8. ## 给testcentos7设置NoExecute污点
  9. [root@Centos8 scheduler]# kubectl taint nodes testcentos7 check=vfan:NoExecute
  10. node/testcentos7 tainted
  11.  
  12. ## 查看Pod有没被驱逐出去
  13. [root@Centos8 scheduler]# kubectl get pod
  14. NAME READY STATUS RESTARTS AGE
  15. required-pod2 / Pending 62m
  16.  
  17. ## 只剩一个Pending状态的Pod,因为他还没创建,所以还未分配Node

查看 testcentos7 节点信息

  1. [root@Centos8 scheduler]# kubectl describe node testcentos7
  2. Taints: check=vfan:NoExecute

目前所有的节点都被打上了污点,新建Pod测试下效果:

  1. [root@Centos8 scheduler]# kubectl create -f pod.yaml
  2. pod/pod- created
  3.  
  4. [root@Centos8 scheduler]# kubectl get pod
  5. NAME READY STATUS RESTARTS AGE
  6. pod- / Pending 4s
  7. required-pod2 / Pending 7h18m

新建的Pod会一直处于Pending状态,因为没有可用的Node节点,这时候就可以使用容忍(Toleration)了

2、容忍(Toleration)

设置了污点的Node将根据 taint 的 effect:NoSchedule、PreferNoSchedule、NoExecute和Pod之间产生互斥的关系,Pod将在一定程度上不会被调度到 Node 上。但我们可以在 Pod 上设置容忍(Toleration),意思是设置了容忍的 Pod 将可以容忍污点的存在,可以被调度到存在污点的Node上

Pod.spec.tolerations

  1. tolerations:
  2. - key: "key1"
  3. operator: "Equal"
  4. value: "value1"
  5. effect: "NoSchedule"
  6. tolerationSeconds:
  7. - key: "key1"
  8. operator: "Equal"
  9. value: "value1"
  10. effect: "NoExecute"
  11. - key: "key2"
  12. operator: "Exists"
  13. effect: "NoSchedule"
  • 其中 key、value、effect 要与Node中的 taint 保持一致
  • operator 的值为 Exists 将会忽略 value 的值
  • tolerationSeconds 用于描述当Pod需要驱逐时可以在Node上继续保留运行的时间

(1)当不指定key时,表示容忍所有污点的key:

  1. tolerations
  2. - operator: "Exists"

例如:

vim pod3.yaml

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: pod-
  5. labels:
  6. app: nginx
  7. type: web
  8. spec:
  9. containers:
  10. - name: pod-
  11. image: nginx:1.2.
  12. imagePullPolicy: IfNotPresent
  13. ports:
  14. - name: web
  15. containerPort:
  16. tolerations:
  17. - operator: "Exists"
  18. effect: "NoSchedule"
  1. [root@Centos8 scheduler]# kubectl create -f pod3.yaml
  2. pod/pod- created
  3.  
  4. [root@Centos8 scheduler]# kubectl get pod -o wide
  5. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  6. pod- / Pending 14m <none> <none>
  7. pod- / Running 11m 10.244.3.229 testcentos7
  8. pod- / Running 9s 10.244.0.107 centos8

yaml策略为:可以容忍所有为NoSchedule的污点,因为centos8为master节点,污点默认为NoSchedule,所以Pod-3被调度到master节点

(2)当不指定 offect 值时,表示容忍所有的污点类型

  1. tolerations:
  2. - key: "key1"
  3. value: "value1"
  4. operator: "Exists"

(3)Pod容忍测试用例:

vim pod2.yaml

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: pod-
  5. labels:
  6. app: nginx
  7. type: web
  8. spec:
  9. containers:
  10. - name: pod-
  11. image: nginx:1.2.
  12. imagePullPolicy: IfNotPresent
  13. ports:
  14. - name: web
  15. containerPort:
  16. tolerations:
  17. - key: "check"
  18. operator: "Equal"
  19. value: "vfan"
  20. effect: "NoExecute"
  1. [root@Centos8 scheduler]# kubectl create -f pod2.yaml
  2. pod/pod- created
  3.  
  4. [root@Centos8 scheduler]# kubectl get pod
  5. NAME READY STATUS RESTARTS AGE
  6. pod- / Pending 3m25s
  7. pod- / Running 4s

设置容忍的Pod,可以正常调度到Node节点,而没有设置容忍的,还一直处于Pending状态

最后将Node污点去除:

  1. kubectl taint nodes testcentos7 check=vfan:NoExecute-

去除node污点仅需在创建命令的最后加一个 - 即可

三、指定调度节点

注意,以下所有的测试都是1Master、1Node的情况下:

  1. [root@Centos8 scheduler]# kubectl get node
  2. NAME STATUS ROLES AGE VERSION
  3. centos8 Ready master 134d v1.15.1
  4. testcentos7 Ready <none> 133d v1.15.1

1、Pod.spec.nodeName 将 Pod 直接调度到指定的 Node 节点上,会跳过 Schedule 的调度策略,该匹配规则是强制匹配

vim nodeName1.yaml

  1. apiVersion: extensions/v1beta1
  2. kind: Deployment
  3. metadata:
  4. name: nodename-
  5. labels:
  6. app: web
  7. spec:
  8. replicas:
  9. template:
  10. metadata:
  11. labels:
  12. app: web
  13. spec:
  14. nodeName: testcentos7
  15. containers:
  16. - name: nodename-
  17. image: nginx:1.2.
  18. imagePullPolicy: IfNotPresent
  19. ports:
  20. - containerPort:
  1. [root@Centos8 scheduler]# kubectl apply -f nodeName1.yaml
  2. deployment.extensions/nodename- created
  3.  
  4. [root@Centos8 scheduler]# kubectl get pod -o wide
  5. NAME READY STATUS RESTARTS AGE IP NODE
  6. nodename--7f4c7db4d4-hdcjv / Running 92s 10.244.3.240 testcentos7
  7. nodename--7f4c7db4d4-xxrj8 / Running 93s 10.244.3.238 testcentos7
  8. nodename--7f4c7db4d4-zkt2c / Running 92s 10.244.3.239 testcentos7

以上策略表示,所有Deployment所有的副本,均要调度到testcentos7节点上

为了对比效果,修改yaml文件中Node节点为centos8

  1. nodeName: centos8

再次创建测试

  1. [root@Centos8 scheduler]# kubectl delete -f nodeName1.yaml
  2.  
  3. [root@Centos8 scheduler]# kubectl apply -f nodeName1.yaml
  4. deployment.extensions/nodename- created
  5.  
  6. NAME READY STATUS RESTARTS AGE IP NODE
  7. nodename--7d49bd7849-ct9w5 / Running 2m2s 10.244.0.112 centos8
  8. nodename--7d49bd7849-qk9mm / Running 2m2s 10.244.0.113 centos8
  9. nodename--7d49bd7849-zdphd / Running 2m2s 10.244.0.111 centos8

全部落在了centos8节点中

2、Pod.spec.nodeSelector:通过 kubernetes 的 label-selector 机制选择节点,由调度策略匹配 label,而后调度 Pod 到目标节点,该匹配规则属于强制约束

vim nodeSelect1.yaml

  1. apiVersion: extensions/v1beta1
  2. kind: Deployment
  3. metadata:
  4. name: node-
  5. labels:
  6. app: web
  7. spec:
  8. replicas:
  9. template:
  10. metadata:
  11. labels:
  12. app: myweb
  13. spec:
  14. nodeSelector:
  15. type: ssd # Node包含的标签
  16. containers:
  17. - name: myweb
  18. image: nginx:1.2.
  19. ports:
  20. - containerPort:
  1. [root@Centos8 scheduler]# kubectl apply -f nodeSelect1.yaml
  2. deployment.extensions/node- created
  3.  
  4. [root@Centos8 scheduler]# kubectl get pod
  5. NAME READY STATUS RESTARTS AGE
  6. node--684b6cc685-9lzbn / Pending 3s
  7. node--684b6cc685-lwzrm / Pending 3s
  8. node--684b6cc685-qlgjq / Pending 3s
  9.  
  10. [root@Centos8 scheduler]# kubectl get node --show-labels
  11. NAME STATUS ROLES AGE VERSION LABELS
  12. centos8 Ready master 135d v1.15.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=centos8,kubernetes.io/os=linux,node-role.kubernetes.io/master=
  13. testcentos7 Ready <none> 134d v1.15.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=testcentos7,kubernetes.io/os=linux

以上策略表示:将Deployment的三个副本全部调度到标签为type:ssd的Node节点上,因为没有Node节点有此标签,所以一直处于Pending状态

下面我们将testcentos7节点打上标签type:ssd

  1. [root@Centos8 scheduler]# kubectl label node testcentos7 type=ssd
  2. node/testcentos7 labeled
  3.  
  4. [root@Centos8 scheduler]# kubectl get pod
  5. NAME READY STATUS RESTARTS AGE
  6. node--684b6cc685-9lzbn / Running 4m30s
  7. node--684b6cc685-lwzrm / Running 4m30s
  8. node--684b6cc685-qlgjq / Running 4m30s

打上标签后,Pod恢复Running状态

文中有不足之处欢迎指出,不胜感激!

Kubernetes-14:一文详解Pod、Node调度规则(亲和性、污点、容忍、固定节点)的更多相关文章

  1. Docker Kubernetes 服务发现原理详解

    Docker Kubernetes  服务发现原理详解 服务发现支持Service环境变量和DNS两种模式: 一.环境变量 (默认) 当一个Pod运行到Node,kubelet会为每个容器添加一组环境 ...

  2. 一文详解Hexo+Github小白建站

    作者:玩世不恭的Coder时间:2020-03-08说明:本文为原创文章,未经允许不可转载,转载前请联系作者 一文详解Hexo+Github小白建站 前言 GitHub是一个面向开源及私有软件项目的托 ...

  3. 一文详解 Linux 系统常用监控工一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop)具(top,htop,iotop,iftop)

    一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop)     概 述 本文主要记录一下 Linux 系统上一些常用的系统监控工具,非常好用.正所谓磨刀不误砍柴工,花点时间 ...

  4. Kubernetes K8S之Ingress详解与示例

    K8S之Ingress概述与说明,并详解Ingress常用示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2C ...

  5. Kubernetes,kubectl常用命令详解

    kubectl概述 祭出一张图,转载至 kubernetes-handbook/kubectl命令概述 ,可以对命令族有个整体的概念. 环境准备 允许master节点部署pod,使用命令如下: kub ...

  6. 从零开始入门 K8s| 详解 Pod 及容器设计模式

    作者|张磊 阿里云容器平台高级技术专家,CNCF 官方大使 一.为什么需要 Pod 容器的基本概念 我们知道 Pod 是 Kubernetes 项目里面一个非常重要的概念,也是非常重要的一个原子调度单 ...

  7. kubernetes Traefik ingress配置详解

    理解Ingress 简单的说,ingress就是从kubernetes集群外访问集群的入口,将用户的URL请求转发到不同的service上.Ingress相当于nginx.apache等负载均衡方向代 ...

  8. Mysql高手系列 - 第14篇:详解事务

    这是Mysql系列第14篇. 环境:mysql5.7.25,cmd命令中进行演示. 开发过程中,会经常用到数据库事务,所以本章非常重要. 本篇内容 什么是事务,它有什么用? 事务的几个特性 事务常见操 ...

  9. Kubernetes架构及相关服务详解

    11.1.了解架构 K8s分为两部分: 1.Master节点 2.node节点 Master节点组件: 1.etcd分布式持久化存储 2.api服务器 3.scheduler 4.controller ...

随机推荐

  1. Servlet容器启动过程

    参考:https://blog.csdn.net/fredaq/article/details/9366043 一.概念 所谓Servlet容器其实说白了是符合Servlet规范的Java web容器 ...

  2. XSSFWorkbook

    支持2007以后的 此类与HSSFWorkbook(支持2007之前) 类似,读取文件时把全部的内容都存放到内存中,关闭输入流后. 内存与硬盘完全是毫无关系的两份数据,所有的操作都是对内存的操作,最后 ...

  3. MVVM 框架

    问题: 1.MVVM 的定义 M (Model): 数据来源,服务器上业务逻辑操作 V (View): 界面,页面 VM (ViewModel): view 和 model 的核心枢纽,如 vue.j ...

  4. Java入门到实践系列(1)——Java简介

    一.Java的发展历史 Java是由SUN公司的开发人员James Gosling及其领导的一个开发小组与1995年开发并推出的一门高级编程语言.经过二十几年的发展已经成为最受程序员欢迎.使用最为普遍 ...

  5. Linux本地套接字(Unix域套接字)----SOCK_DGRAM方式

    目录 简述 创建服务端代码: 创建客户端代码 接收函数封装 发送封装 服务端测试main函数 客户端测试main函数 编译运行结果 简述 这里介绍一下Linux进程间通信的socket方式---Loc ...

  6. 「查缺补漏」巩固你的Redis知识体系

    Windows Redis 安装 链接: https://pan.baidu.com/s/1MJnzX_qRuNXJI09euzkPGA 提取码: 2c6w 复制这段内容后打开百度网盘手机App,操作 ...

  7. LeetCode 91,点赞和反对五五开,这题是好是坏由你来评判

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题的第57篇文章,我们一起来看看LeetCode第91题,解码方法(Decode ways). 这道题官方给定的难度 ...

  8. 精讲RestTemplate第7篇-自定义请求失败异常处理

    本文是精讲RestTemplate第7篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用 精讲RestTemplate第2篇-多种底层H ...

  9. Tun/Tap接口使用指导

    Tun/Tap接口指导 目录 Tun/Tap接口指导 概述 工作机制 创建接口 举例 简单的程序 隧道 拓展 参考 概述 对tun接口的了解需求主要来自于openshift的网络,在openshift ...

  10. [Hei-Ocelot-Gateway ].Net Core Api网关Ocelot的开箱即用版本

    写在前面 很多neter都有在用Ocelot做Api网关,但是Ocelot又不像kong或者其他网关一样,开箱即用.它需要你单独开一个web项目来部署,这样很多同学都在做重复的事了. 这里[Hei.O ...