調度之nodeAffinity


1.簡介

我們知道默認的調度器在使用的時候,經過了 predicates 和 priorities 兩個階段,但是在實際的生產環境中,往往我們需要根據自己的一些實際需求來控制 Pod 的調度,這就需要用到 nodeAffinity(節點親和性)、podAffinity(pod 親和性) 以及 podAntiAffinity(pod 反親和性)。
親和性調度可以分成軟策略和硬策略兩種方式:

軟策略就是如果現在沒有滿足調度要求的節點的話,Pod 就會忽略這條規則,繼續完成調度過程,說白了就是滿足條件最好了,沒有的話也無所謂
硬策略就比較強硬了,如果沒有滿足條件的節點的話,就不斷重試直到滿足條件為止,簡單說就是你必須滿足我的要求,不然就不干了
對於親和性和反親和性都有這兩種規則可以設置: preferredDuringSchedulingIgnoredDuringExecution 和requiredDuringSchedulingIgnoredDuringExecution,前面的就是軟策略,后面的就是硬策略。

2.節點親和性

節點親和性(nodeAffinity)主要是用來控制 Pod 要部署在哪些節點上,以及不能部署在哪些節點上的,它可以進行一些簡單的邏輯組合了,不只是簡單的相等匹配。

比如現在我們用一個 Deployment 來管理3個 Pod 副本,現在我們來控制下這些 Pod 的調度,如下例子:(node-affinity-demo.yaml)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: node-affinity
  labels:
    app: node-affinity
spec:
  replicas: 3
  selector:
    matchLabels:
      app: node-affinity
  template:
    metadata:
      labels:
        app: node-affinity
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
          name: nginxweb
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:  # 硬策略
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/hostname
                operator: NotIn
                values:
                - k8s-node3
          preferredDuringSchedulingIgnoredDuringExecution:  # 軟策略
          - weight: 1
            preference:
              matchExpressions:
              - key: cm
                operator: In
                values:
                - test

上面這個 Pod 首先是要求不能運行在 k8s-node3 這個節點上,如果有個節點滿足 cm=test 的話就優先調度到這個節點上。

由於上面 k8s-node02 節點我們打上了 cm=test 這樣的 label 標簽,所以按要求會優先調度到這個節點來的,現在我們來創建這個 Pod,然后查看具體的調度情況是否滿足我們的要求。

[root@k8s-master01 ~]# kubectl create -f node-affinity-demo.yaml 
deployment.apps/node-affinity created
[root@k8s-master01 ~]# kubectl get pod -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          11d     172.25.244.200   k8s-master01   <none>           <none>
nginx-68db656dd8-znwgp           1/1     Running   1          11d     172.18.195.11    k8s-master03   <none>           <none>
node-affinity-7fc9bdc65c-8nzmk   1/1     Running   0          6s      172.27.14.229    k8s-node02     <none>           <none>
node-affinity-7fc9bdc65c-gchtc   1/1     Running   0          6s      172.27.14.231    k8s-node02     <none>           <none>
node-affinity-7fc9bdc65c-gzqsx   1/1     Running   0          7s      172.27.14.230    k8s-node02     <none>           <none>
test-busybox                     1/1     Running   0          15m     172.27.14.216    k8s-node02     <none>           <none>
web                              2/2     Running   0          3d17h   172.18.195.14    k8s-master03   <none>           <none>
[root@k8s-master01 ~]# kubectl get deployment
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
nginx           2/2     2            2           11d
node-affinity   3/3     3            3           56s

從結果可以看出有4個 Pod 被部署到了 ydzs-node2 節點上,但是可以看到並沒有一個 Pod 被部署到 node3 這個節點上,因為我們的硬策略就是不允許部署到該節點上,而 node2 是軟策略,所以會盡量滿足。這里的匹配邏輯是 label 標簽的值在某個列表中,現在 Kubernetes 提供的操作符有下面的幾種:

In:label 的值在某個列表中
NotIn:label 的值不在某個列表中
Gt:label 的值大於某個值
Lt:label 的值小於某個值
Exists:某個 label 存在
DoesNotExist:某個 label 不存在
但是需要注意的是如果 nodeSelectorTerms 下面有多個選項的話,滿足任何一個條件就可以了;如果 matchExpressions有多個選項的話,則必須同時滿足這些條件才能正常調度 Pod。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM