我们知道,kubernetes 的 Scheduler 服务(kube-scheduler进程)负责实现 Pod 的调度,整个调度过程通过执行一系列的算法最终为每个 Pod 计算出一个最佳的目标节点,这一过程是自动完成的,我们无法知道 Pod 最终会被调度到哪个节点上。有时我们可能需要将 Pod 调度到一个指定的 Node 上,此时,我们可以通过 Node 的标签 (Label)和Pod 的 nodeSelector 属性相匹配,来达到上述目的。
首先,我们可以通过 kubectl label 命令给目标 Node 打上一个特定的标签,下面是此命令的完整用法:
kubectl label nodes
这里,我们为kubernetes-minion1 节点上打上一个 zone=north 的标签,表明它是 “北方”的一个节点:
$ kubectl label nodes kubernetes-minion1 zone=north
NAME LABELS STATUS
kubernetes-minion1 kubernetes.io/hostname=kubernetes-minion1,zone=north Ready
上述命令操作也可以通过修改资源定义文件的方式,并执行 kubectl replace -f xxx.yaml 命令来完成。
然后,在 Pod 的配置文件中加入 nodeSelector 定义,以 redis-master0controller.yaml 为例:
apiVersion: v1
kind: ReplicationController
metadata:
name: redis-master
lables:
name: redis-master
spec:
replicas: 1
selector:
name: redis-master
template:
metadata:
lables:
name: redis-master
spec:
containers:
- name: master
images: kubeguide/redis-master
ports:
- containerPort: 6379
nodeSelector:
zone: north
运行 kubectl create -f 命令创建 Pod,scheduler 会将该 Pod 调度到拥有 zone=north 标签的 node 上去。
使用 kubectl get pods -o wide
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE NODE
redis-master-1 1/1 Running 0 18s kubernetes-minion1
如果我们给多个 Node 都定义了相同的标签(如 zone=north),则scheduler 将会根据调度算法从这组 Node 中 挑选一个可用的 Node 进行Pod 调度。
这种基于 Node 标签的调度方式灵活性很高,比如我们可以把一组 Node 分别贴上 “开发环境” “测试环境” “用户验收环境” 这三组标签中的一种,此时一个 kubernetes集群就承载了3个环境,这将大大提高开发效率。
需要注意的是,如果我们指定了 Pod 的 nodeSelector 条件,且集群中不存在包含相应标签的 Node时,即使还有其他可供调度的 Node,这个 Pod 也最终会调度失败。