企业实战-Kubernetes(九)kubernetes调度

本文详细介绍了Kubernetes中的调度机制,包括NodeName、nodeSelector、节点亲和与反亲和、Taints污点与容忍。通过实例展示了如何设置节点选择、亲和性规则以及如何处理污点,解释了不同调度策略的效果及其应用场景。
摘要由CSDN通过智能技术生成


调度器
调度器通过 kubernetes 的 watch 机制来发现集群中新创建且尚未被调度到 Node 上的 Pod。调度器会将发现的每一个未调度的 Pod 调度到一个合适的 Node 上来运行。
kube-scheduler 是 Kubernetes 集群的默认调度器,并且是集群控制面的一部分。kube-scheduler 在设计上是允许你自己写一个调度组件并替换原有的 kube-scheduler。
在做调度决定时需要考虑的因素包括:单独和整体的资源请求、硬件/软件/策略限制、亲和以及反亲和要求、数据局域性、负载间的干扰等等。

k8s调度
1.NodeName

NodeName 是节点选择约束的最简单方法,它优先于其他的节点选择方法。
缺点
如果指定的节点不存在。
如果指定的节点没有资源来容纳 pod,则pod 调度失败。
云环境中的节点名称并非总是可预测或稳定的。

2.nodeSelector

nodeSelector 是节点选择约束的最简单推荐形式。
给选择的节点添加标签:
kubectl label nodes server2 disktype=ssd

3.亲和与反亲和

nodeSelector 提供了一种非常简单的方法来将 pod 约束到具有特定标签的节点上。亲和/反亲和功能极大地扩展了你可以表达约束的类型。
你可以发现规则是“软”/“偏好”,而不是硬性要求,因此,如果调度器无法满足该要求,仍然调度该 pod
你可以使用节点上的 pod 的标签来约束,而不是使用节点本身的标签,来允许哪些 pod 可以或者不可以被放置在一起。

4.节点亲和

requiredDuringSchedulingIgnoredDuringExecution #必须满足
preferredDuringSchedulingIgnoredDuringExecution #倾向满足

节点亲合

创建目录、编写资源清单
在这里插入图片描述

[root@server2 schedu]# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disktype: ssd

拉起容器并查看,发现pod节点处于pending状态,且不在任意node上运行
在这里插入图片描述

为server3添加标签后,查看pod节点状态,发现运行在server3上

kubectl label nodes server3 disktype=ssd
kubectl get pod -o wide

在这里插入图片描述
删除标签后不会消失,因为容器已经运行

kubectl label nodes server3 disktype-
kubectl get node --show-labels

在这里插入图片描述
节点亲和性pod示例

vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: node-affinity
spec:
  containers:
  - name: nginx
    image: nginx
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution: #必须满足
           nodeSelectorTerms:
           - matchExpressions:
             - key: kubernetes.io/hostname
               operator: In
               values:
               - server3
               - server4
      preferredDuringSchedulingIgnoredDuringExecution: #倾向满足
      - weight: 1
        preference:
          matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd     

先注释掉倾向满足

[root@server2 schedu]# kubectl apply -f pod1.yaml 
[root@server2 schedu]# kubectl get pod -o wide

发现亲合到server4
在这里插入图片描述
打开倾向满足,删除节点,重新拉起容器,还在server4

在这里插入图片描述
删除pod1.yaml
为server3增加标签ssd并重新拉起,发现运行在有标签的server3上
在这里插入图片描述

pod 亲和性和反亲和性

podAffinity 主要解决POD可以和哪些POD部署在同一个拓扑域中的问题(拓扑域用主机标签实现,可以是单个主机,也可以是多个主机组成的cluster、zone等。)
podAntiAffinity主要解决POD不能和哪些POD部署在同一个拓扑域中的问题。它们处理的是Kubernetes集群内部POD和POD之间的关系。
Pod 间亲和与反亲和在与更高级别的集合(例如 ReplicaSets,StatefulSets,Deployments 等)一起使用时,它们可能更加有用。可以轻松配置一组应位于相同定义拓扑(例如,节点)中的工作负载。

亲合

[root@server2 schedu]# vim pod2.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
---
apiVersion: v1
kind: Pod
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  containers:
  - name: mysql
    image: mysql:5.7
    env:
     - name: "MYSQL_ROOT_PASSWORD"
       value: "westos"
  affinity:
    podAffinity:  #亲合
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - nginx
        topologyKey: kubernetes.io/hostname

[root@server2 schedu]# kubectl apply -f pod2.yaml 

拉起并查看,nginx与mysql运行在同一node上
在这里插入图片描述
反亲和

[root@server2 schedu]# vim pod2.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
---
apiVersion: v1
kind: Pod
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  containers:
  - name: mysql
    image: mysql:5.7
    env:
     - name: "MYSQL_ROOT_PASSWORD"
       value: "westos"
  affinity:
    podAntiAffinity:   #反亲合
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - nginx
        topologyKey: kubernetes.io/hostname

[root@server2 schedu]# kubectl apply -f pod2.yaml 

拉起并查看,nginx与mysql运行在不同node上
在这里插入图片描述

Taints污点与容忍

NodeAffinity节点亲和性,是Pod上定义的一种属性,使Pod能够按我们的要求调度到某个Node上.
Taints污点则恰恰相反,它可以让Node拒绝运行Pod,甚至驱逐Pod。

Taints(污点)是Node的一个属性,设置了Taints后,所以Kubernetes是不会将Pod调度到这个Node上的,于是Kubernetes就给Pod设置了个属性Tolerations(容忍),只要Pod能够容忍Node上的污点,那么Kubernetes就会忽略Node上的污点,就能够(不是必须)把Pod调度过去。

可以使用命令 kubectl taint 给节点增加一个 taint:

$ kubectl taint nodes node1 key=value:NoSchedule	//创建
$ kubectl describe nodes  server1 |grep Taints		//查询
$ kubectl taint nodes node1 key:NoSchedule-		    //删除

其中[effect] 可取值: [ NoSchedule | PreferNoSchedule | NoExecute ]

NoSchedule:POD 不会被调度到标记为 taints 节点。
PreferNoSchedule:NoSchedule 的软策略版本。
NoExecute:该选项意味着一旦 Taint 生效,如该节点内正在运行的 POD 没有对应 Tolerate 设置,会直接被逐出。

server2为k8s调度端,默认不参加集群调度
在这里插入图片描述
测试
1:Nodename可以无视任何污点
编辑资源清单创建pod,采用nodename指定node节点

[root@server2 schedu]# vim pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeName: server2

拉起容器,查看节点所在node为server2

kubectl apply -f pod.yaml
kubectl get pod -o wide

在这里插入图片描述
server2作为master且设置了污点,但是nodename可以无视污点。
测试完成删除测试pod

为server2设置标签,使用标签方式测试污点

kubectl label nodes server2 roles=master
kubectl get nodes --show-labels

在这里插入图片描述

编辑资源清单,使用标签方式选择node

[root@server2 schedu]# vim pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    roles: master

[root@server2 schedu]# kubectl apply -f pod.yaml 
[root@server2 schedu]# kubectl get pod -o wide

拉起容器,发现pod处于pending,不能成功
在这里插入图片描述
测试证明,标签选择无法覆盖污点

添加容忍

[root@server2 schedu]# vim pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    roles: master
  tolerations:
  - operator: "Exists"
    effect: "NoSchedule"

添加容忍,NoSchedule:POD 不会被调度到标记为 taints 节点。

kubectl taint nodes server3 key=value:NoSchedule

server3上存在污点

kubectl describe nodes server3|grep Taint

在这里插入图片描述
注释容忍,拉起容器,发现容器在server4端运行,说明污点生效。

[root@server2 schedu]# vim pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
#  nodeSelector: 
#    roles: master
#  tolerations:
#  - operator: "Exists"
#    effect: "NoSchedule"

在这里插入图片描述
删除pod.yaml后,打开容忍,通过标签选择server3

[root@server2 schedu]# vim pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disktype: ssd
  tolerations:
  - operator: "Exists"
    effect: "NoSchedule"

在这里插入图片描述
完成后取消NoSchedule的值

kubectl taint node server3 key:NoSchedule-

NoExecute:该选项意味着一旦 Taint 生效,如该节点内正在运行的 POD 没有对应 Tolerate 设置,会直接被逐出。被驱逐到其他node节点。

kubectl taint nodes server3 key=value:NoExecute

在这里插入图片描述
测试完成,取消NoExecute的值

kubectl taint nodes server3 key:NoExecute-

在这里插入图片描述
关闭server3的所有调度

kubectl cordon server3
kubectl get node

在这里插入图片描述
重新开启server3的调度

kubectl uncordon server3
kubectl get node

在这里插入图片描述
关闭server3的调度,但不关闭部分必要pod

kubectl drain server3
kubectl get node

在这里插入图片描述
删除node

kubectl delete node server3

在这里插入图片描述
server3重新加入k8s集群

[root@server3 ~]# systemctl restart kubelet.service 

控制端查看,server3加入集群
在这里插入图片描述
删除node的步骤为:先驱逐pod,再删除node

拓展
当有新的node想加入k8s集群中,我们就需要生成新的token,注意,每一次生成的token只有24小时有效期

在控制端上生成token
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

热到想喝冰阔落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值