Kubernetesのpodスケジューリング


PodのスケジューリングはデフォルトではScheduler Controllerがデフォルトアルゴリズムの全自動スケジューリングを採用しているが、実際の使用では我々のニーズを満たしていない.podがどのノードにスケジューリングされているかを事前に把握することはできないため、kubernetesはまた、NodeSelector(指向スケジューリング)、NodeAffinity(Node親和性)、PodAffinity(Pod親和性).
NodeSelectorスケジューリングアルゴリズムは比較的簡単で、NodeSelectorは特定のラベルを持つノードにのみスケジューリングされ、条件を満たすノードがなければ、このPodは実行されず、クラスタに使用可能なノードリストがある場合でも使用シーンが制限され、現在は基本的にNodeAffinityに取って代わられています.NodeAffinityは、NodeSelectorをベースに拡張され、スケジューリングがより柔軟になります.条件を満たす必要があるNodeのほかに、優先条件を設定することができます.次に、NodeAffinityの使用方法を見てみましょう.
一、NodeAffinity
NodeAffinity親和性には2つの表現があります.
◎R equiredDuringSchedulingIgnoredDuringExecution:Podをノードにスケジューリングするには、指定されたルールを満たす必要があります.ハード制限に相当します.
◎P r e f erredDuringSchedulingIgnoredDuringExecution:指定されたルールを優先的に満たすことを強調し、ソフトリミットに相当し、強要しない.複数の優先度ルールの場合、実行順序を定義するために重みを設定することもできる.
IgnoredDuringExecutionによると、podが存在するノードがPodの実行中にラベルが変更され、Podのノード親和性のニーズに合致しなくなった場合、システムはノード上のLabelの変化を無視し、podはノード上で動作し続ける.    
次に、いくつかの例を示します.
apiVersion: v1
kind: Pod
metadata:
 name: ubuntu-aff
 labels:
  os: centos
spec:
 affinity:  #     
  nodeAffinity: #  node   
   requiredDuringSchedulingIgnoredDuringExecution:
    nodeSelectorTerms:   
    - matchExpressions:   #  node     
     - key: disktype    
      operator: In
      values:
      - hdd
   #             (disktype=hdd) Node 。
   requiredDuringSchedulingIgnoredDuringExecution   preferredDuringSchedulingIgnoredDuringExecution
           disktype=hdd   Node,     ,        Node         ,            Node 

 
上の構成から分かるように、オペレータoperatorはInであり、NodeAffinity構文でサポートされているオペレータはIn、NotIn、Exists、
DoesNotExist,Gt,Ltはノード反発機能はないが,NotInとDoesNotExistで反発機能を実現できる.
     
NodeAffinityルールの設定に関する注意事項は次のとおりです.
◎nodeSelectorとnodeAffinityが同時に定義されている場合は、Podが最終的に指定された
ノード上.
◎nodeAffinityが複数のnodeSelectorTermsを指定している場合は、そのうちの1つだけがマッチングに成功する必要があります.
NodeSelectorTermsプロパティは、スケジューリングするnodeのラベルを設定するため、nodeSelectorTermsは、異なるラベル、すなわち異なるノードの上にスケジューリングできる複数の説明がある場合は、1つを一致させるだけでよい.     
◎1つのnodeSelectorTermsに複数のmatchExpressionsがある場合、1つのノードはすべての
matchExpressionsは、マッチングに成功します.
matchExpressionsは、nodeSelectorTermsの下で、特定のノードラベルを設定し、複数設定します.
NodeSelectorTermsは、一致するノードに複数のラベルが必要であり、複数のラベルが同時に必要であることを意味します.
   
上記の例では、node親和性条件は1つしかありません.複数の条件を設定できます.
apiVersion: v1
kind: Pod
metadata:
  name: ubuntu-aff
  labels:
    os: centos
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:   #    
        nodeSelectorTerms:
        - matchExpressions:
          - key: beta.kubernetes.io/arch
            operator: In
            values:
            - amd64
      preferredDuringSchedulingIgnoredDuringExecution:  #     
      - weight: 1
        preference:
          matchExpressions:
          - key: disktype
            operator: In
            values:
            - hdd
  containers:
  - name: ubuntu-aff
    image: 10.3.1.15:5000/ubuntu:16.04
    env:  #          
    - name: Test
      value: "7890"
    command: ["bash","-c","while true;do date;sleep 1;done"]

以上のようにpodを作成する場合、ノード親和性は2つあります.すなわち、ノードがこのPodを実行する場合、このノードが満たす必要がある条件は2つあります.
第一条件は属性がr e q u i r e d D u r g S h e d u l i n g I gnoredDuringExecutionであり、これは硬性条件であり、満たさなければならない:beta.kubernetes.io/arch=amd64
2番目の条件属性はp r e f erredDuringSchedulingIgnoredDuringExecutionです.これはソフト条件です.つまり、優先的に満たす条件で、できるだけ満たすことができます.満たさない場合は後退して次を求め、他のノードの上で実行します.
では、スケジューリング時にどのノードにスケジューリングするかをどのように選択しますか?
なぜ2つの条件を設定するのかというと、最初の条件を満たすノードはbetaを持つことが多いからです.kubernetes.io/arch=amd 64のラベルの
ノードはたくさんありますが、ここで2番目の条件はdisktype=hddのノードでできるだけ実行することです.
総じて、arch=amd 64のnodeのみで実行され、この条件の下でdisktype=hddのNodeで優先的に実行される.
二、PodAffinity:Pod親和性と反発性のスケジューリング
ノード上で実行中のpodのラベルに基づいてスケジューリングされ、nodeのラベルではなく、ノードとPodの2つの条件を一致させる必要があります.このルールは、ラベルXを有するノード上で1つ以上の条件Yに合致するPodが実行された場合、Podはこのノード上で実行され、反発であれば、このノード上で実行されることを拒否することです.すなわち,ある既存のpodに基づいて,このpodとノード上にいるかどうかを決定し,一緒にいると親和性を設定し,一緒にいないと反発性を設定する必要がある.Xはクラスタ内のノード、ラック、領域などの概念を指し、Kubernetesがノードラベルのkeyを内蔵することによって宣言され、このkeyの名前はtopologyKeyであり、ノードが属するトポロジー構造の下を表現するために使用される.
podの親和性表現はNode親和性と同じ表現である.
kubernetes内蔵ラベル:
        ○ kubernetes.io/hostname
        ○ failure-domain.beta.kubernetes.io/zone
        ○ failure-domain.beta.kubernetes.io/region
        ○ beta.kubernetes.io/instance-type
        ○ beta.kubernetes.io/os
        ○ beta.kubernetes.io/arch
1、参照Podの作成
#pod affinity   Pod
apiVersion: v1
kind: Pod
metadata:
  name: pod-flag
  labels:    #       ,    pod       
    app: nginx
    security: s1
spec:
  containers:
  - name: nginx-1-10
    image: 10.3.1.15:5000/nginx:1.10
    ports:
    - containerPort: 80

#       Node  :
root@ubuntu:# kubectl get pod -o wide
NAME     READY     STATUS     RESTARTS  AGE     IP       NODE
pod-flag   1/1      Running      0     4m  192.168.150.232   10.3.1.16

#   Node 10.3.1.16 

2、参照するpodと同じnode上、すなわち親和性を持つpodを作成する.
apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
  labels:
    os: ubuntu
spec:
  affinity: #     
    podAffinity:  #  pod   
      requiredDuringSchedulingIgnoredDuringExecution: #        
      - labelSelector:  #   pod    ,     pod     
          matchExpressions:  #    pod ,    ,       matchExpressions,           。
          - key: security #   key
            operator: In  #   
            values:
            - s1  #    ,   label security=s1
        topologyKey: kubernetes.io/hostname #       
  #             Pod        security=s1 pod   Node .
  containers:
  - name: wish-pod-affinity
    image: 10.3.1.15:5000/ubuntu:16.04
    env: 
    - name: Test
      value: "7890"
    command: ["bash","-c","while true;do date;sleep 1;done"]
    
 
   #   pod          ,           Pod ,                    Pod,
   #  namespace    labelSelector  ,         ,       pod   namespace  
root@ubuntu:# kubectl get pod -o wide
NAME           READY   STATUS    RESTARTS   AGE      IP        NODE
with-pod-affinity     1/1    Running     0     11s   192.168.150.252   10.3.1.16
pod-flag          1/1    Running     0     1h    192.168.150.232   10.3.1.16

#       Node 。
#      ,pod      Pending  ,               Node。

3、参照したpodと同じノード上、すなわち反発性を持たないpodを作成する.
apiVersion: v1
kind: Pod
metadata:
  name: with-pod-antiffinity
  labels:
    os: ubuntu
spec:
  affinity: #     
   podAntiAffinity:  #  pod    
      requiredDuringSchedulingIgnoredDuringExecution: #        
      - labelSelector:  #   pod     ,   ,     pod     
          matchExpressions:
          - key: app #   key
            operator: In
            values:
            - nginx  #    ,   label app=nginx
        topologyKey: kubernetes.io/hostname  #       
  #             Pod        app=nginx pod      Node .     Node       ,    pod    Pending  。
  containers:
  - name: wish-pod-antiaffinity
    image: 10.3.1.15:5000/ubuntu:16.04
    env: 
    - name: Test
      value: "7890"
    command: ["bash","-c","while true;do date;sleep 1;done"]
root@ubuntu15:/data/yaml# kubectl get pod -o wide
NAME                       READY        STATUS    RESTARTS     AGE           IP                NODE
pod-flag                    1/1         Running      0          1h        192.168.150.232    10.3.1.16
with-pod-affinity           1/1         Running      0          1h        192.168.150.252    10.3.1.16
with-pod-antiffinity        1/1         Running      0          1m        192.168.77.204     10.3.1.17

#       pod     node  。

より多くのPod親和性スケジューリング情報は、公式ドキュメントを参照してください.