固定节点

我们到目前为止已经讲了很多的调度策略了,比如我们的亲和性、比如我们的污点 ,其实他们都比较含蓄。

亲和性:

  • 比如第一个亲和性,举例我们假如去相亲了希望找一个女朋友离我家近一点更好,这就是典型的软亲和。

  • 如果能和我家一起,这是一个硬性条件,那这就是我们所谓的硬亲和。

污点:

我能容忍他的身高能够比我高,但是不能代表身高比我高的能够看上我吧。

以及我不能容忍比我高的,这就是不能容忍。

但是这样讲的话我们现在都没有一个明确的目标,但是假如我非常喜欢小红,并且以后一定要和她结婚。这个就比较强硬。这和我们的 pod 一也是一样的方案,假如这个 pod 必须要运行在 node-1 这个节点上别的不好使,不能够运行在 node-1 上这个 pod 就不会运行了,那这个呢就是我们的固定节点选择。

固定节点就比较简单粗暴了,可以通过我们的节点名称去选择,以及我们的节点标签去选择。固定到某个节点上面去运行,这个就是所所谓的固定节点的调度。

9.4.1 固定节点的使用方案

使用方案是在pod.spec.nodeName字段上去指定我们节点的名称,或者使在我们的pod .spec.nodeSelector中去指定我们要选择的标签。可以去完成我们的节点选择,或叫做节点固定。那接下来我们去做下实验看一下效果。

9.4.1.1 根据节点名称选择 pod.spec.nodeName字段使用范例

Pod.spec.nodeName 将 pod 直接调度到指定的 Node 节点上,会跳过Scheduler 的调度策略,该匹配规则使强制匹配

yaml文件详解:

下面的 yaml 文件意味着这个 7 个 pod 都会运行在 K8S 的 node-1 节点上。

apiVersion: apps/v1                     # api 版本为 apps/v1 版
kind: Deployment                        # kind 类型为 deployment
metadata:                               # 这个 deployment 的元数据信息
  name: myweb                           # 这个 deployment 名为 myweb
spec:                                   # 这个 deployment 的描述信息
  selector:                             # 标签选择器
    matchLabels:                        # 匹配标签规则
      app: myweb                        # 匹配 app=mysql 的标签
  replicas: 7                           # 期望 pod 副本数目为7,理论上是会有几个运行在node-2 节点
  template:                             # 模板信息
    metadata:                           # 模板元数据信息
      labels:                           # 标签匹配规则
        app: myweb                      # 匹配 app=myweb 的标签
    spec:                               # pod 详细描述
      nodeName: node-1                  # pod 的 spec.nodeName 指定固定运行在 node-1 节点上
      containers:                       # pod 使用的容器信息
      - name: myweb                     # 这个容器名为 myweb
        image: nginx                    # 使用的镜像使 nginx
        imagePullPolicy: IfNotPresent   # 镜像下载策略为 ifnotpresent 有 nginx 镜像就不用下载
        ports:                          # 容器端口策略
        - containerPort: 80             # 暴露容器的 80 端口

实现范例:

1、创建一个 node 的目录,用于存放固定节点的 yaml资源清单文件

[15:40:44 root@master-1 ~]#mkdir node
[15:40:48 root@master-1 ~]# cd node/ 

2、编写 yaml资源清单

[15:53:56 root@master-1 node]#vim pod1.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myweb
spec:
  replicas: 7
  selector:
    matchLabels:
      app: myweb
  template:
    metadata:
      labels:
        app: myweb
    spec:
      nodeName: node-1
      containers:
      - name: myweb
        image: nginx
        imagePullPolicy: IfNotPresent  
        ports:
        - containerPort: 80

3、通过kubectl apply声明式创建

[15:53:55 root@master-1 node]#kubectl apply -f pod1.yaml 

4、通过kubectl get pod -o wide查看,会发现所有的 pod 对运行在了 node-1 节点上。如果不加上pod.spec.nodeName 字段是不可能所有 pod 都运行在 node-1 节点上的。

[15:59:08 root@master-1 node]#kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
myweb-6d7685575b-7ff4v   1/1     Running   0          6s    10.10.1.127   node-1   <none>           <none>
myweb-6d7685575b-8zfls   1/1     Running   0          6s    10.10.1.131   node-1   <none>           <none>
myweb-6d7685575b-bqdqk   1/1     Running   0          6s    10.10.1.133   node-1   <none>           <none>
myweb-6d7685575b-gnggs   1/1     Running   0          6s    10.10.1.130   node-1   <none>           <none>
myweb-6d7685575b-lm5s6   1/1     Running   0          6s    10.10.1.129   node-1   <none>           <none>
myweb-6d7685575b-m8nst   1/1     Running   0          6s    10.10.1.128   node-1   <none>           <none>
myweb-6d7685575b-mqd5x   1/1     Running   0          6s    10.10.1.132   node-1   <none>           <none>

9.4.1.2 根据标签选择Pod.spec.nodeSelector 字段使用范例

Pod.spec.nodeSelector 通过 kubernetes 的 label-selector机制选择节点,由调度器调度策略匹配 label,而后调度 pod 到标签匹配的目标节点上运行,该匹配规则属于强制约束

yaml文件详解:

下面这个 yaml资源清单想要实现的就是,创建一个 deployment 并且在这个 deployment 中有两个 pod ,然后通过nodeSelector标签选择,运行在 node 标签是 disk: ssd的 node 节点上

apiVersion: apps/v1             # api 使用 apps/v1 版本
kind: Deployment                # kind 类型是 deployment
metadata:                       # 这个 deployment 信息
  name: myweb-2                 # 这个 deployment 名称为 myweb-2
spec:                           # 这个 deployment 的详细字段描述
  replicas: 2                   # 运行 pod 副本数目期望值为 2
  selector:                     # 标签选择器
    matchLabels:                # 标签匹配规则
      app: myweb-2              # 匹配 app=myweb-2 的标签
  template:                     # 模板信息
    metadata:                   # 元数据信息
      labels:                   # 标签匹配规则
      app: myweb-2              # 匹配 app=myweb-2 的标签下运行 pod
    spec:                       # pod 详细描述
      nodeSelector:             # 根据标签选择固定在某 node 节点上
        disk: ssd               # 标签的键名为 disk,值是 ssd 也就是当 node 上有标签正好是 disk=ssd 那么 pod 就会被运行在有该标签的 node 上
      containers:               # pod 使用的容器信息
      - name: myweb-2           # 容器名为 myweb-2
        image: nginx            # 镜像是 nginx
        ports:                  # 暴露端口策略
        - containerPort: 80     # 暴露容器的 80 端口

实现范例:

1、编写yaml资源清单文件

[15:59:14 root@master-1 node]#vim pod2.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myweb-2
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myweb-2
  template:
    metadata:
      labels:
        app: myweb-2
    spec:
      nodeSelector:
        disk: ssd
      containers:
      - name: myweb-2
        image: nginx
        ports:
        - containerPort: 80

2、通过kubectl apply声明式创建 pod

[16:20:38 root@master-1 node]#kubectl apply -f pod2.yaml 

3、通过kubectl get pod -o wide 命令观察到当前的这两个 pod 状态是 pending 等待,而且还没有调度到节点上去。因为没有合适的标签给他们匹配

[16:23:50 root@master-1 node]#kubectl get pod -o wide
NAME                      READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
myweb-2-f8d8957dd-csbp9   0/1     Pending   0          12s   <none>   <none>   <none>           <none>
myweb-2-f8d8957dd-vm647   0/1     Pending   0          12s   <none>   <none>   <none>           <none>

4、所以我现在给我们的 node-2 节点上添加 disk:ssd的标签

[16:24:02 root@master-1 node]#kubectl label node node-2 disk=ssd
 
kubectl label:      # 添加标签
node node-2:        # 指定 node 节点为 node-2
disk=ssd:           # 标签为 disk=ssd

5、再次通过kubectl get pod -o wide就会发现我们的这两个 pod 状态为 runnig 并且绑定在了 node-2 节点上

[16:26:11 root@master-1 node]#kubectl get pod -o wide
NAME                      READY   STATUS    RESTARTS   AGE     IP           NODE     NOMINATED NODE   READINESS GATES
myweb-2-f8d8957dd-csbp9   1/1     Running   0          3m14s   10.10.2.94   node-2   <none>           <none>
myweb-2-f8d8957dd-vm647   1/1     Running   0          3m14s   10.10.2.93   node-2   <none>           <none>

当然它也可以自由选择,比如现在我们去给 node-1 节点上也打上这个标签

6、给 node-1 节点打赏 disk=ssd 的标签。

[16:27:10 root@master-1 node]#kubectl label node node-1 disk=ssd

这时候我们的两个 node 节点都有 disk=ssd 的标签,所以这时候我们将该 deployment 的 pod 数目增大。它的有些 pod 就会运行在我们的 node-1 节点上

7、通过kubectl edit deployment修改 deployment 信息,找到副本期望值这行,我将他的副本数目改为 4

[16:28:43 root@master-1 node]#kubectl edit deployment myweb-2 

kubectl edit deployment myweb-2 :       # 指定编辑 deployment 为 myweb-2 的信息

8、再次通过kubectl get pod -o wide查看就会发现有两个 pod 运行在了 node-1 节点上

[16:36:01 root@master-1 node]#kubectl get pod -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
myweb-2-8459c54d66-242lb   1/1     Running   0          20s   10.10.1.143   node-1   <none>           <none>
myweb-2-8459c54d66-5xnmv   1/1     Running   0          20s   10.10.2.95    node-2   <none>           <none>
myweb-2-8459c54d66-jwqbr   1/1     Running   0          18s   10.10.1.144   node-1   <none>           <none>
myweb-2-8459c54d66-tvddm   1/1     Running   0          18s   10.10.2.96    node-2   <none>           <none>

原因是我这时候连个 node 节点都有 disk:ssd的键名和键值对。这个就是相对比较理性的一种调度方式,把 pod 固定到那个节点上面去运行

点赞