前言

默认情况下,Pod的调度完全由Master节点的Scheduler组件经过一系列的算法计算得出的,这个过程是不能人工干预的。但是实际情况中我们的业务非常复杂,可能需要自己控制Pod到达某个节点,于是k8s也给我们提供了一些更加细粒度的调度策略设置。如NodeSelector,NodeAffinity,PodAffinity,污点和容忍等。

本文主要介绍定向调度 NodeSelector ,其它调度后续文章更新。

定向调度可以将Pod调度到指定的Node上,这个过程是强制的,如果调度的目标节点不存在,那么Pod会运行失败,并不会调度到其它节点。

定向调度有两种方式

  • nodeName 调度到指定名称的节点,这种方式跳过了Scheduler的调度逻辑
  • nodeSelector 通过 label-selector机制 将Pod调度到指定标签的Node节点上
nodeName

查看当前集群的所有节点

[root@master ~]# kubectl get nodes
NAME     STATUS   ROLES                  AGE   VERSION
master   Ready    control-plane,master   49d   v1.23.9
node01   Ready    <none>                 49d   v1.23.9
node02   Ready    <none>                 49d   v1.23.9

编写 nginx-nodename.yaml 内容如下,通过nodeName调度到node01节点

apiVersion: v1
kind: Pod
metadata:
  name: nginx-nodename
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeName: node01

启动Pod,查看Pod详情注意观察NODE信息

# 启动
[root@master scheduler]# kubectl create -f nginx-nodename.yaml 
pod/nginx-nodename created

# 查看Pod详情 已经运行成功并且调度到了node01
[root@master scheduler]# kubectl get pod -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
nginx-nodename   1/1     Running   0          11s   10.244.1.69   node01   <none>           <none>

上面是正常流程,前面我们提到,这个调度是强制性的,如果没有该node节点是否运行不成功,下面我们来验证下,修改上面yaml,将 nodeName: node01修改为 nodeName: node03

启动Pod,观察详情

# 查看pod看到Node虽然在node03但是并没有运行成功
[root@master scheduler]# kubectl get pod -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
nginx-nodename   0/1     Pending   0          14s   <none>   node03   <none>           <none>

# 等待一会,因为没有节点的原因,该pod会自动删除
[root@master scheduler]# kubectl get pod -o wide
No resources found in default namespace.
nodeSelector

在Pod创建之前,会通过 MatchNodeSelector 调度策略进行节点标签匹配,如果找到对应节点含有此标签,则调度到该节点,如果找到多个挑选一个即可,如果没有找到则Pod运行失败(前面提到了该机制是强制性的)

通过kubectl label命令给node01打上北京机房的标签,给node02打上上海机房的标签

kubectl label nodes node01 area=bj
kubectl label nodes node02 area=shanghai

# 查看标签是否设置成功
kubectl get nodes --show-labels

编写 nginx-nodeselector.yaml 内容如下 通过 nodeSelector指定调度到bj机房

apiVersion: v1
kind: Pod
metadata:
  name: nginx-nodeselector
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    area: bj #指定调度到北京机房
北京机房测试

启动Pod,查看Pod详情注意观察NODE信息

# 启动Pod
[root@master scheduler]# kubectl create -f nginx-nodeselector.yaml
pod/nginx-nodeselector created

# 查看详情,调度到了node01
[root@master scheduler]# kubectl get pod -o wide
NAME                 READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
nginx-nodeselector   1/1     Running   0          41s   10.244.1.70   node01   <none>           <none>
上海机房测试

修改area为shanghai 再次启动Pod,查看Pod详情注意观察NODE信息

# 删除之前的pod
[root@master scheduler]# kubectl delete -f nginx-nodeselector.yaml
pod "nginx-nodeselector" deleted
# 启动修改后的Pod
[root@master scheduler]# kubectl create -f nginx-nodeselector.yaml
pod/nginx-nodeselector created

# 查看详情,调度到了node02
[root@master scheduler]# kubectl get pod -o wide
NAME                 READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
nginx-nodeselector   1/1     Running   0          5s    10.244.2.23   node02   <none>           <none>
无匹配机房测试

修改area为changsha 再次启动Pod,查看Pod详情

# 删除之前的pod
[root@master scheduler]# kubectl delete -f nginx-nodeselector.yaml
pod "nginx-nodeselector" deleted
# 启动修改后的Pod
[root@master scheduler]# kubectl create -f nginx-nodeselector.yaml
pod/nginx-nodeselector created

# 查看详情,并没有启动成功
[root@master scheduler]# kubectl get pod -o wide                                  
NAME                 READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
nginx-nodeselector   0/1     Pending   0          12s   <none>   <none>   <none>           <none>

# 查看启动过程,报错了
[root@master scheduler]# kubectl describe  pod nginx-nodeselector|grep -A 100 Event
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  64s   default-scheduler  0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 node(s) didn't match Pod's node affinity/selector.

由于找不到匹配的node几点,前面提到了该机制是强制性的,所以pod是运行不起来的,这种方式调度失败了是不会删除pod,我们需要手动删除下。


如果需要删除节点标签,执行如下命令

kubectl label node node01 area-
kubectl label node node02 area-

Pod的定向调度就介绍到这里,该方式只是一个简单的限制了Pod所在节点的方法,后面我们介绍亲和性调度,它极大的扩展了Pod的调度能力。


欢迎关注,学习不迷路!

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐