Kubernetes Master 上 的Scheduler 服务(kube-scheduler进程)负责实现Pod 的调度,整个调度过程通过一系列复杂的算法,最终为每个Pod 都计算出一个最佳的目标节点,这一过程自动完成的,通常我们无法知道一些Node上,可以通过Node 的标签(Label)和Pod 的nodeSelector 属性相匹配,来达到上述目的。
(1)首先通过kubectl label 命令给目标Node 打上一些标签:
kubectl label nodes -name>
这里为k8s-node-1 节点打上一个 zone=north标签 ,表明它是一个北方的节点。
[root@k8s-master ~]# kubectl label nodes k8s-node-1 zone=north
node/k8s-node-1 labeled
查看给node 添加的标签:
[root@k8s-master ~]# kubectl get node --show-labels
NAME STATUS ROLES AGE VERSION LABELS
k8s-node-1 Ready 32d v1.23.2 zone=north
上述命令行操作也可以通过修改资源定义文件的方式,并运行如下命令来完成:
kubectl replace -f xxxx.yaml
(2)然后,在Pod 的定义中加上NodeSelector 的设置,以redis-master-controller.yaml为例:
apiVersion: v1
kind: ReplicationController
metadata:
name: redis-master
labels:
name: redis-master
spec:
replicas: 1
selector:
name: redis-master
template:
metadata:
labels:
name: redis-master
spec:
containers:
- name: master
image: kubeguide/redis-master
ports:
- containerPort: 6379
nodeSelector:
zone: north
运行kubectl create -f 命令创建Pod,scheduler 就会将该Pod 调度到拥有 "zone=north"标签的Node上:
[root@k8s-master ~]# kubectl create -f redis-master-controller.yaml
replicationcontroller/redis-master created
使用kubectl get pods -o wide 命令可以验证Pod 所在的Node:
[root@k8s-master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
redis-master-d86n2 1/1 Running 0 3m22s 10.244.109.112 k8s-node-1
如果我们给多个Node 都定义了相同的标签(例如zone=north),则scheduler 会根据调度算法从这组Node 中挑选一个可用的Node 进行Pod调度。
通过基于Node 标签的调度方式,我们可以把集群中具有不同特点的Node 都贴上不同的标签,例如:role=frontend,role=backend,role=database等标签,在部署应用时就可以根据应用的需求设置NodeSelector 来进行指定Node 范围的调度。
需要注意的是,如果我们指定了Pod 的nodeSelector 条件,且在集群中不存在包含相应标签的Node,则即使在集群中还有其他可供使用的Node,这个Pod 也无法被成功调度。