• 调度之nodeSelector


    1.简介:

    一般情况下我们部署的 Pod 是通过集群的自动调度策略来选择节点的,默认情况下调度器考虑的是资源足够,并且负载尽量平均,但是有的时候我们需要能够更加细粒度的去控制 Pod 的调度,比如我们希望一些机器学习的应用只跑在有 GPU 的节点上;但是有的时候我们的服务之间交流比较频繁,又希望能够将这服务的 Pod 都调度到同一个的节点上。这就需要使用一些调度方式来控制 Pod 的调度了,主要有两个概念:亲和性和反亲和性,亲和性又分成节点亲和性(nodeAffinity)和 Pod 亲和性(podAffinity)。

    2.nodeSelector:

    在了解亲和性之前,我们先来了解一个非常常用的调度方式:nodeSelector。我们知道 label 标签是 kubernetes 中一个非常重要的概念,用户可以非常灵活的利用 label 来管理集群中的资源,比如最常见的 Service 对象通过 label 去匹配 Pod 资源,而 Pod 的调度也可以根据节点的 label 来进行调度。

    我们可以通过下面的命令查看我们的 node 的 label:

    [root@k8s-master01 ~]# kubectl get nodes --show-labels
    NAME           STATUS   ROLES    AGE   VERSION   LABELS
    k8s-master01   Ready    <none>   11d   v1.20.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master01,kubernetes.io/os=linux,node.kubernetes.io/node=
    k8s-master02   Ready    <none>   11d   v1.20.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master02,kubernetes.io/os=linux,node.kubernetes.io/node=
    k8s-master03   Ready    <none>   11d   v1.20.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master03,kubernetes.io/os=linux,node.kubernetes.io/node=
    k8s-node01     Ready    <none>   11d   v1.20.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node01,kubernetes.io/os=linux,node.kubernetes.io/node=
    k8s-node02     Ready    <none>   11d   v1.20.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node02,kubernetes.io/os=linux,node.kubernetes.io/node=
    

    现在我们先给节点k8s-node01增加一个cm=test的标签,命令如下:

    [root@k8s-master01 ~]# kubectl label nodes k8s-node01 cm=test # 创建标签
    node/k8s-node01 labeled
    [root@k8s-master01 ~]# kubectl label nodes k8s-node01 cm- # 删除标签
    node/k8s-node01 labeled
    
    [root@k8s-master01 ~]# kubectl get nodes --show-labels
    NAME           STATUS   ROLES    AGE   VERSION   LABELS
    k8s-master01   Ready    <none>   11d   v1.20.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master01,kubernetes.io/os=linux,node.kubernetes.io/node=
    k8s-master02   Ready    <none>   11d   v1.20.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master02,kubernetes.io/os=linux,node.kubernetes.io/node=
    k8s-master03   Ready    <none>   11d   v1.20.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master03,kubernetes.io/os=linux,node.kubernetes.io/node=
    k8s-node01     Ready    <none>   11d   v1.20.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,cm=test,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node01,kubernetes.io/os=linux,node.kubernetes.io/node=
    k8s-node02     Ready    <none>   11d   v1.20.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node02,kubernetes.io/os=linux,node.kubernetes.io/node=
    

    我们可以通过上面的 --show-labels 参数可以查看上述标签是否生效。当节点被打上了相关标签后,在调度的时候就可以使用这些标签了,只需要在 Pod 的 spec 字段中添加 nodeSelector 字段,里面是我们需要被调度的节点的 label 标签,比如,下面的 Pod 我们要强制调度到 node2 这个节点上去,我们就可以使用 nodeSelector 来表示了:(node-selector-demo.yaml)

    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        app: busybox-pod
      name: test-busybox
    spec:
      containers:
      - command:
        - sleep
        - "3600"
        image: busybox
        imagePullPolicy: Always
        name: test-busybox
      nodeSelector:
        com: test # 这里可以写我们定义的标签,或者hostname
    

    我们可以通过命令查看调度结果

    [root@k8s-master01 ~]# kubectl apply  -f node-selector-demo.yaml 
    pod/test-busybox created
    [root@k8s-master01 ~]# kubectl get  pods -owide
    NAME                     READY   STATUS    RESTARTS   AGE     IP               NODE           NOMINATED NODE   READINESS GATES
    busybox                  1/1     Running   261        11d     172.17.125.9     k8s-node01     <none>           <none>
    nginx-68db656dd8-qjhs9   1/1     Running   1          10d     172.25.244.200   k8s-master01   <none>           <none>
    nginx-68db656dd8-znwgp   1/1     Running   1          10d     172.18.195.11    k8s-master03   <none>           <none>
    test-busybox             1/1     Running   0          19s     172.27.14.215    k8s-node02     <none>           <none>
    web                      2/2     Running   0          3d17h   172.18.195.14    k8s-master03   <none>           <none>
    
    [root@k8s-master01 ~]# kubectl describe pod test-busybox 
    Name:         test-busybox
    Namespace:    default
    Priority:     0
    Node:         k8s-node02/192.168.0.111
    Start Time:   Tue, 30 Mar 2021 18:37:27 +0800
    Labels:       app=busybox-pod
    Annotations:  <none>
    Status:       Running
    IP:           172.27.14.215
    IPs:
      IP:  172.27.14.215
    Containers:
      test-busybox:
        Container ID:  docker://f85fa6688eb7b014b5c710354243528c6c0df555b3300f168773bc0f461581d1
        Image:         busybox
        Image ID:      docker-pullable://busybox@sha256:ce2360d5189a033012fbad1635e037be86f23b65cfd676b436d0931af390a2ac
        Port:          <none>
        Host Port:     <none>
        Command:
          sleep
          3600
        State:          Running
          Started:      Tue, 30 Mar 2021 18:37:44 +0800
        Ready:          True
        Restart Count:  0
        Environment:    <none>
        Mounts:
          /var/run/secrets/kubernetes.io/serviceaccount from default-token-pn9sp (ro)
    Conditions:
      Type              Status
      Initialized       True 
      Ready             True 
      ContainersReady   True 
      PodScheduled      True 
    Volumes:
      default-token-pn9sp:
        Type:        Secret (a volume populated by a Secret)
        SecretName:  default-token-pn9sp
        Optional:    false
    QoS Class:       BestEffort
    Node-Selectors:  cm=test # 
    Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                     node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
    Events:
      Type    Reason     Age   From               Message
      ----    ------     ----  ----               -------
      Normal  Scheduled  55s   default-scheduler  Successfully assigned default/test-busybox to k8s-node02
      Normal  Pulling    54s   kubelet            Pulling image "busybox"
    

    我们可以看到 Events 下面的信息,我们的 Pod 通过默认的 default-scheduler 调度器被绑定到了 node2 节点。不过需要注意的是nodeSelector 属于强制性的,如果我们的目标节点没有可用的资源,我们的 Pod 就会一直处于 Pending 状态。

  • 相关阅读:
    LOJ#10106. 「一本通 3.7 例 2」单词游戏
    小木棍(爆搜减枝)
    倍增求lca(模板)
    2018年第九届蓝桥杯C/C++A组省赛(最后一题)
    LOJ#10172. 「一本通 5.4 练习 1」涂抹果酱
    【[APIO/CTSC2007]动物园】状压DP
    c++滚动数组
    状态压缩入门(附经典题目和题解)
    小 M 的算式(dfs)
    P与NP问题详解
  • 原文地址:https://www.cnblogs.com/Applogize/p/14595786.html
Copyright © 2020-2023  润新知