为何要控制Pod应该如何调度
集群中有些机器的配置高(SSD,更好的内存等),我们希望核心的服务(比如说数据库)运行在上面
某两个服务的网络传输很频繁,我们希望它们最好在同一台机器上
……
NodeSelector调度 label
是kubernetes
中一个非常重要的概念,用户可以非常灵活的利用 label 来管理集群中的资源,POD 的调度可以根据节点的 label 进行特定的部署。
查看节点的label:
1 $ kubectl get nodes --show-labels
为节点打label:
1 $ kubectl label node k8s-master disktype=ssd
当 node 被打上了相关标签后,在调度的时候就可以使用这些标签了,只需要在spec 字段中添加nodeSelector
字段,里面是我们需要被调度的节点的 label。
1 2 3 4 5 6 7 8 9 10 11 12 13 ... spec: hostNetwork: true volumes: - name: mysql-data hostPath: path: /opt/mysql/data nodeSelector: component: mysql containers: - name: mysql image: 172.21 .32 .6 :5000/demo/mysql:5.7 ...
测试可参见:mysql on k8s持久化
nodeAffinity节点亲和性调度 节点亲和性,比上面的nodeSelector
更加灵活,它可以进行一些简单的逻辑组合,不只是简单的相等匹配 。分为两种,软策略和硬策略。
preferredDuringSchedulingIgnoredDuringExecution
:软策略,如果你没有满足调度要求的节点的话,Pod就会忽略这条规则,继续完成调度过程,说白了就是满足条件最好了,没有满足就忽略掉的策略。
requiredDuringSchedulingIgnoredDuringExecution
: 硬策略,如果没有满足条件的节点的话,就不断重试直到满足条件为止,简单说就是你必须满足我的要求,不然我就不会调度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 ... spec: containers: - name: demo image: 172.21 .32 .6 :5000/demo/myblog ports: - containerPort: 8002 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: NotIn values: - 192.168 .56 .20 - 192.168 .56 .30 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: disktype operator: In values: - ssd - sas ...
这里的匹配逻辑是 label 的值在某个列表中,现在Kubernetes
提供的操作符有下面的几种:
In:label 的值在某个列表中
NotIn:label 的值不在某个列表中
Gt:label 的值大于某个值
Lt:label 的值小于某个值
Exists:某个 label 存在
DoesNotExist:某个 label 不存在
如果nodeSelectorTerms
下面有多个选项的话,满足任何一个条件就可以了;如果matchExpressions
有多个选项的话,则必须同时满足这些条件才能正常调度 Pod
污点(Taints)与容忍(tolerations) 对于nodeAffinity
无论是硬策略还是软策略方式,都是调度 Pod 到预期节点上,而Taints
恰好与之相反,如果一个节点标记为 Taints ,除非 Pod 也被标识为可以容忍污点节点,否则该 Taints 节点不会被调度Pod。
Taints(污点)是Node的一个属性,设置了Taints(污点)后,因为有了污点,所以Kubernetes是不会将Pod调度到这个Node上的。于是Kubernetes就给Pod设置了个属性Tolerations(容忍),只要Pod能够容忍Node上的污点,那么Kubernetes就会忽略Node上的污点,就能够(不是必须)把Pod调度过去。
比如用户希望把 Master 节点保留给 Kubernetes 系统组件使用,或者把一组具有特殊资源预留给某些 Pod,则污点就很有用了,Pod 不会再被调度到 taint 标记过的节点。在K8s集群搭建 时就利用污点与容忍特性,将master也当作了工作节点加入到了k8s集群当中
taint 标记节点举例如下: 设置污点:
1 2 3 4 5 6 $ kubectl taint node [node_name ] key=value:[effect ] 其中[effect ] 可取值: [ NoSchedule | PreferNoSchedule | NoExecute ] NoSchedule:一定不能被调度。 PreferNoSchedule:尽量不要调度。 NoExecute:不仅不会调度,还会驱逐Node上已有的Pod。 示例:kubectl taint node k8s-master smoke=true:NoSchedule
去除污点:
1 2 3 4 5 6 7 8 9 10 去除指定key及其effect: kubectl taint nodes [node_name] key:[effect]- 去除指定key所有的effect: kubectl taint nodes node_name key- 示例: kubectl taint node k8s-master smoke=true :NoSchedule kubectl taint node k8s-master smoke:NoExecute- kubectl taint node k8s-master smoke-
污点演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 $ kubectl taint node k8s-master smoke=true :NoSchedule $ kubectl taint node k8s-slave1 drunk=true :NoSchedule $ kubectl taint node k8s-slave2 perm=true :NoSchedule 此时,master节点打上了污点抽烟,slave1节点打上了污点喝酒,slave2节点打上了污点烫头。 $ kubectl -n demo scale deploy myblog --replicas=3 $ kubectl -n demo get po -w NAME READY STATUS RESTARTS AGE myblog-749b5dbc4b-6lgwm 1/1 Running 0 66m myblog-749b5dbc4b-jx5j2 1/1 Running 0 65m myblog-749b5dbc4b-vtb57 0/1 Pending 0 15s mysql-5fcb655cc9-q48f9 1/1 Running 0 156m $ kubectl -n demo describe po myblog-749b5dbc4b-vtb57 Warning FailedScheduling <unknown> default-scheduler 0/3 nodes are available: 3 node(s) had taints that the pod didn't tolerate. # 扩容的pod由于受不了三个节点的抽烟喝酒烫头污点,从而无法调度到任何一个节点😄
Pod容忍污点示例:myblog/deployment/deploy-myblog-taint.yaml
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 ... apiVersion: apps/v1 kind: Deployment metadata: name: myblog namespace: demo spec: replicas: 3 selector: matchLabels: app: myblog template: metadata: labels: app: myblog spec: tolerations: - key: "smoke" operator: "Equal" value: "true" effect: "NoSchedule" containers: - name: myblog image: 192.168 .56.10 :5000 /myblog:v3 imagePullPolicy: IfNotPresent ...
或者在线更新
1 $ kubectl -n demo edit deploy myblog
1 2 3 4 5 6 7 8 9 10 11 $ kubectl apply -f deploy-myblog-taint.yaml $ kubectl -n demo get po -o wide NAME READY STATUS RESTARTS AGE IP NODE myblog-7fc47887f9-h5529 1/1 Running 0 2m56s 10.244.0.4 k8s-master myblog-7fc47887f9-k85mr 1/1 Running 0 3m27s 10.244.0.2 k8s-master myblog-7fc47887f9-v6qbf 1/1 Running 0 3m13s 10.244.0.3 k8s-master mysql-5fcb655cc9-q48f9 1/1 Running 0 170m 192.168.56.20 k8s-slave1 发现所有的myblogpod 和 其副本都调度到了master节点上面
1 2 3 4 5 6 spec: containers: - name: demo image: 172.21 .32 .6 :5000/demo/myblog tolerations: - operator: "Exists"
k8s企业级DevOps实践-k8s调度策略:NodeSelector/nodeAffinity/污点与容忍
转载前请阅读本站 版权协议 ,文章著作权归 饼铛 所有,转载请注明出处。