Kubernetes之NodeSelector定向调度

Kubernetes之NodeSelector定向调度

Kubernetes Master上的Scheduler服务(kube-scheduler进程)负责实现Pod的调度,整个调度过程通过执行一系列复杂的算法,最终为每个Pod都计算出一个最佳的目标节点,这一过程是自动完成的,通常我们无法知道Pod最终会被调度到哪个节点上。在实际情况下,也可能需要将Pod调度到指定的一些Node上,可以通过Node的标签(Label)和Pod的nodeSelector属性相匹配,来达到上述目的。

1.首先通过kubectl label命令给目标Node打上一些标签:

kubectl label nodes <node-name> <label-key>=<label-value>

这里,我们为k8s-node-1节点打上一个zone=north标签,表明它是“北方”的一个节点:

kubectl label nodes k8s-node1 zone=north

上述命令行操作也可以通过修改资源定义文件的方式,并执行kubectl replace -f xxx.yaml命令来完成。

apiVersion: vl
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上

如果我们给多个Node都定义了相同的标签(例如zone=north),则scheduler会根据调度算法从这组Node中挑选一个可用的Node进行Pod调度。通过基于Node标签的调度方式,我们可以把集群中具有不同特点的Node都贴上不同的标签,例如“role=frontend”“role=backend”“role=database”等标签,在部署应用时就可以根据应用的需求设置NodeSelector来进行指定Node范的调度。需要注意的是,如果我们指定了Pod的nodeSelector条件,且在集群中不存在包含相应标签的Node,则即使在集群中还有其他可供使用的Node,这个Pod也无法被成功调度。除了用户可以自行给Node添加标签,Kubernetes也会给Node预定义一些标签,包括:

  • kubernetes.io/hostname
  • beta.kubernetes.io/os(从1.14版本开始更新为稳定版,到1.18版本删除)
  • beta.kubernetes.io/arch(从1.14版本开始更新为稳定版,到1.18版本删除)
  • kubernetes.io/os(从1.14版本开始启用)
  • kubernetes.io/arch(从1.14版本开始启用)

用户也可以使用这些系统标签进行Pod的定向调度。NodeSelector通过标签的方式,简单实现了限制Pod所在节点的方法。亲和性调度机制则极大扩展了Pod的调度能力,主要的增强功能如下。

  • 更具表达力(不仅仅是“符合全部”的简单情况)。
  • 可以使用软限制、优先采用等限制方式,代替之前的硬限制,这样调度器在无法满足优先需求的情况下,会退而求其次,继续运行该Pod。
  • 可以依据节点上正在运行的其他Pod的标签来进行限制,而非节点本身的标签。这样就可以定义一种规则来描述Pod之间的亲和或互斥关系。

亲和性调度功能包括节点亲和性(NodeAffinity)和Pod亲和性(PodAffinity)两个维度的设置。节点亲和性与NodeSelector类似,增强了上述前两点优势;Pod的亲和与互斥限制则通过Pod标签而不是节点标签来实现,也就是上面第4点内容所陈述的方式,同时具有前两点提到的优点。
NodeSelector将会继续使用,随着节点亲和性越来越能够表达nodeSelector的功能,最终NodeSelector会被废弃。

留下评论