19.kubernetes筆記 Pod資源調度(二) podAffinity、podAntiAffinity Pod親和與反親和

目錄
概述
查看 podAffinity的詳細說明
示例1: podAffinity Pod硬親和
示例2: podAffinity 硬親和
示例3: podAntiAffinity 硬反親和

概述:

  • 先來了解 topology key 字段
    pod親和性調度需要各個相關的pod對象運行于"同一位置", 而反親和性調度則要求他們不能運行于"同一位置",
    這里指定“同一位置” 是通過 topologyKey 來定義的,topologyKey 對應的值是 node 上的一個標簽名稱,比如各別節(jié)點zone=A標簽,各別節(jié)點有zone=B標簽,pod affinity topologyKey定義為zone,那么調度pod的時候就會圍繞著A拓撲,B拓撲來調度,而相同拓撲下的node就為“同一位置”。

顧名思義,topology 就是 拓撲的意思,這里指的是一個 拓撲域,是指一個范圍的概念,比如一個 Node、一個機柜、一個機房或者是一個地區(qū)(如杭州、上海)等,實際上對應的還是 Node 上的標簽。這里的 topologyKey 對應的是 Node 上的標簽的 Key(沒有Value),可以看出,其實 topologyKey 就是用于篩選 Node 的。通過這種方式,我們就可以將各個 Pod 進行跨集群、跨機房、跨地區(qū)的調度了。

查看 podAffinity的詳細說明
[root@k8s-master Scheduler]# kubectl explain pods.spec.affinity
KIND:     Pod
VERSION:  v1

RESOURCE: affinity <Object>

DESCRIPTION:
     If specified, the pod's scheduling constraints

     Affinity is a group of affinity scheduling rules.

FIELDS:
   nodeAffinity <Object>   #節(jié)點親和
     Describes node affinity scheduling rules for the pod.

   podAffinity  <Object>  #Pod親和
     Describes pod affinity scheduling rules (e.g. co-locate this pod in the
     same node, zone, etc. as some other pod(s)).

   podAntiAffinity  <Object> #Pod反親和
     Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod
     in the same node, zone, etc. as some other pod(s)).

 #親和與反親和中又分硬親和 軟親和前一節(jié)提到的Node親和一樣不在累述
[root@k8s-master Scheduler]# kubectl explain pods.spec.affinity.podAffinity 

FIELDS:
   preferredDuringSchedulingIgnoredDuringExecution  <[]Object>
...

   requiredDuringSchedulingIgnoredDuringExecution   <[]Object>
...
#Pod反親和
[root@k8s-master Scheduler]# kubectl explain pods.spec.affinity.podAntiAffinity
FIELDS:
   preferredDuringSchedulingIgnoredDuringExecution  <[]Object>
...ffinityTerm; the
     node(s) with the highest sum are the most preferred.

   requiredDuringSchedulingIgnoredDuringExecution   <[]Object>
...

[root@k8s-master Scheduler]# kubectl explain pods.spec.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution

   labelSelector    <Object>
     A label query over a set of resources, in this case pods.

   namespaces   <[]string>  
     namespaces specifies which namespaces the labelSelector applies to (matches
     against); null or empty list means "this pod's namespace"

   topologyKey  <string> -required-  #拓撲標簽 使用哪一個標簽為位置標簽(必選字段)
     This pod should be co-located (affinity) or not co-located (anti-affinity)
     with the pods matching the labelSelector in the specified namespaces, where
     co-located is defined as running on a node whose value of the label with
     key topologyKey matches that of any node on which any of the selected pods
     is running. Empty topologyKey is not allowed.

示例1: podAffinity Pod硬親和

requiredDuringSchedulingIgnoredDuringExecution

[root@k8s-master Scheduler]# cat pod-affinity-required-demo.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis 
spec:
  replicas: 1  #redis為有狀態(tài)應用 為了測試只運行1個副本
  selector:
    matchLabels:
      app: redis
      ctlr: redis
  template:
    metadata:
      labels:
        app: redis
        ctlr: redis
    spec:
      containers:
      - name: redis
        image: redis:6.0-alpine
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pod-affinity-required
spec:
  replicas: 5
  selector:
    matchLabels:
      app: demoapp
      ctlr: pod-affinity-required
  template:
    metadata:
      labels:
        app: demoapp
        ctlr: pod-affinity-required
    spec:
      containers:
      - name: demoapp
        image: ikubernetes/demoapp:v1.0
      affinity:
        podAffinity: #Pod親和
          requiredDuringSchedulingIgnoredDuringExecution:  #硬親和
          - labelSelector:
              matchExpressions:
              - {key: app, operator: In, values: ["redis"]}   #復雜表示達匹配標簽 app=reids、ctlr=redis
              - {key: ctlr, operator: In, values: ["redis"]}    #兩個表達式為與關系 同時滿足
            topologyKey: rack   #節(jié)點標簽 位置標簽 rack可以理解為同一個機架上 與labelSelector同樣是與關系同時滿足

[root@k8s-master Scheduler]# kubectl apply -f pod-affinity-required-demo.yaml 
deployment.apps/redis unchanged
deployment.apps/pod-affinity-required unchanged

[root@k8s-master Scheduler]# kubectl get pod -o wide  #節(jié)點還沒有打上標簽pod-affinity掛機
NAME                                     READY   STATUS    RESTARTS   AGE    IP              NODE        NOMINATED NODE   READINESS GATES
pod-affinity-required-5dd44f5d45-6vvhd   0/1     Pending   0          6m7s   <none>          <none>      <none>           <none>
pod-affinity-required-5dd44f5d45-c4hzl   0/1     Pending   0          6m7s   <none>          <none>      <none>           <none>
pod-affinity-required-5dd44f5d45-qm6zb   0/1     Pending   0          6m7s   <none>          <none>      <none>           <none>
pod-affinity-required-5dd44f5d45-t4mm5   0/1     Pending   0          6m7s   <none>          <none>      <none>           <none>
pod-affinity-required-5dd44f5d45-vs7dg   0/1     Pending   0          6m7s   <none>          <none>      <none>           <none>
redis-55f46d9795-r7pkz                   1/1     Running   0          10m    192.168.51.23   k8s-node3   <none>           <none>

  • 模擬同一機架不同節(jié)點
[root@k8s-master Scheduler]# kubectl label node k8s-node1 rack=foo  #為節(jié)點1把rack標簽
node/k8s-node1 labeled
[root@k8s-master Scheduler]# kubectl label node k8s-node2 rack=bar  #為節(jié)點2把rack標簽
node/k8s-node2 labeled
[root@k8s-master Scheduler]# kubectl label node k8s-node3 rack=baz #為節(jié)點3把rack標簽
node/k8s-node3 labeled
  • 硬親和與redis運行在相同節(jié)點 都運行在node3上
[root@k8s-master Scheduler]# kubectl get pod  -o wide 
NAME                                     READY   STATUS    RESTARTS   AGE   IP              NODE        NOMINATED NODE   READINESS GATES
pod-affinity-required-5dd44f5d45-6vvhd   1/1     Running   0          21m   192.168.51.28   k8s-node3   <none>           <none>
pod-affinity-required-5dd44f5d45-c4hzl   1/1     Running   0          21m   192.168.51.26   k8s-node3   <none>           <none>
pod-affinity-required-5dd44f5d45-qm6zb   1/1     Running   0          21m   192.168.51.24   k8s-node3   <none>           <none>
pod-affinity-required-5dd44f5d45-t4mm5   1/1     Running   0          21m   192.168.51.25   k8s-node3   <none>           <none>
pod-affinity-required-5dd44f5d45-vs7dg   1/1     Running   0          21m   192.168.51.27   k8s-node3   <none>           <none>
redis-55f46d9795-r7pkz                   1/1     Running   0          25m   192.168.51.23   k8s-node3   <none>           <none>
示例2: podAffinity Pod軟親和

preferredDuringSchedulingIgnoredDuringExecution

[root@k8s-master Scheduler]# cat pod-affinity-preferred-demo.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-preferred
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
      ctlr: redis-preferred
  template:
    metadata:
      labels:
        app: redis
        ctlr: redis-preferred
    spec:
      containers:
      - name: redis
        image: redis:6.0-alpine
        resources:
          requests:
            cpu: 200m
            memory: 512Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pod-affinity-preferred
spec:
  replicas: 4
  selector:
    matchLabels:
      app: demoapp
      ctlr: pod-affinity-preferred
  template:
    metadata:
      labels:
        app: demoapp
        ctlr: pod-affinity-preferred
    spec:
      containers:
      - name: demoapp
        image: ikubernetes/demoapp:v1.0
        resources:
          requests:
            cpu: 500m
            memory: 100Mi
      affinity:
        podAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:   #軟親和以不同權重計算分值重出最終的親和節(jié)點
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - {key: app, operator: In, values: ["redis"]}     
                - {key: ctlr, operator: In, values: ["redis-prefered"]}  #Pod包含標簽為app=redis、ctlr=redis-prefered同時滿足
              topologyKey: kubernetes.io/hostname  #節(jié)點位置標簽 以不同節(jié)點為位置 表示在相同節(jié)點權重為100 所有同一節(jié)點權重最高
          - weight: 50
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - {key: app, operator: In, values: ["redis"]}
                - {key: ctlr, operator: In, values: ["redis-prefered"]}
              topologyKey: rack  #節(jié)點標簽 位置標簽 以機架為位置  表示在相同機架權重為50

[root@k8s-master Scheduler]# kubectl apply -f  pod-affinity-preferred-demo.yaml 

[root@k8s-master Scheduler]# kubectl get pod -o wide   #運行在不同的節(jié)點
NAME                                      READY   STATUS    RESTARTS   AGE    IP               NODE        NOMINATED NODE   READINESS GATES
pod-affinity-preferred-57d457968f-4lxvq   1/1     Running   0          5m6s   192.168.113.21   k8s-node1   <none>           <none>
pod-affinity-preferred-57d457968f-krb2f   1/1     Running   0          5m6s   192.168.113.20   k8s-node1   <none>           <none>
pod-affinity-preferred-57d457968f-mzckm   1/1     Running   0          5m6s   192.168.12.24    k8s-node2   <none>           <none>
pod-affinity-preferred-57d457968f-v8n8g   1/1     Running   0          5m6s   192.168.51.37    k8s-node3   <none>           <none>
redis-preferred-5d775df679-wtpgs          1/1     Running   0          5m6s   192.168.51.38    k8s-node3   <none>           <none>

示例3: podAntiAffinity 硬反親和

requiredDuringSchedulingIgnoredDuringExecution

  • Deployment 4個副本必須運行在不同的節(jié)點上 因為node節(jié)點只有3個所有會有個掛起 內部相斥
[root@k8s-master Scheduler]# cat pod-antiaffinity-required-demo.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pod-antiaffinity-required
spec:
  replicas: 4  #運行4個副本
  selector:
    matchLabels:
      app: demoapp
      ctlr: pod-antiaffinity-required
  template:
    metadata:
      labels:
        app: demoapp
        ctlr: pod-antiaffinity-required
    spec:
      containers:
      - name: demoapp
        image: ikubernetes/demoapp:v1.0
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - {key: app, operator: In, values: ["demoapp"]}
              - key: ctlr
                operator: In
                values: ["pod-antiaffinity-required"]   #Pod包含標簽app=demoapp、ctlr=pod-antiaffinity-required 同時滿足
            topologyKey: kubernetes.io/hostname  #以節(jié)點為位置  表示每個節(jié)點只能運行1個Pod

[root@k8s-master Scheduler]# kubectl apply -f  pod-antiaffinity-required-demo.yaml 

[root@k8s-master Scheduler]# kubectl get pod -o wide  
NAME                                         READY   STATUS    RESTARTS   AGE    IP               NODE        NOMINATED NODE   READINESS GATES
pod-antiaffinity-required-697f7d764d-hgkxj   1/1     Running   0          5m5s   192.168.113.34   k8s-node1   <none>           <none>
pod-antiaffinity-required-697f7d764d-n4zt9   1/1     Running   0          5m5s   192.168.12.34    k8s-node2   <none>           <none>
pod-antiaffinity-required-697f7d764d-psqfb   1/1     Running   0          5m5s   192.168.51.53    k8s-node3   <none>           <none>
pod-antiaffinity-required-697f7d764d-q6t7m   0/1     Pending   0          5m5s   <none>           <none>      <none>           <none>  #掛起 因為只有3個node節(jié)點
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容