Kubernetes系列-Pod的定向调度

1 概述

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

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

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

定向调度有两种方式

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

2 nodeName

2.1 nodeName调度节点存在

查看当前集群的所有节点。

# kubectl get nodes
NAME     STATUS   ROLES                  AGE   VERSION
master   Ready    control-plane,master   49d   v1.23.9
node01   Ready                     49d   v1.23.9
node02   Ready                     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信息。

# 启动
# kubectl create -f nginx-nodename.yaml 
pod/nginx-nodename created

# 查看Pod详情 已经运行成功并且调度到了node01
# 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              

上面流程是node节点存在,pod被成功调度。

2.2 nodeName调度节点不存在

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

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

启动Pod,观察详情

# kubectl apply -f nginx-nodename.yaml 
pod/nginx-nodename apply

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

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

3 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
# kubectl create -f nginx-nodeselector.yaml
pod/nginx-nodeselector created

# 查看详情,调度到了node01
# 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              

上海机房测试

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

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

# 查看详情,调度到了node02
# 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              

无匹配机房测试

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

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

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

# 查看启动过程,报错了
# 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的调度能力。

你可能感兴趣的:(#,Kubernetes系列,docker,容器,运维)