Kubernetesの親和性と反親和性

通常、管理者はポッドがどのノードに割り当てられるかを心配する必要はありません。このプロセスはスケジューラによって自動的に実装されます。ただし、場合によっては、スケジュールの制限を指定する必要があります。たとえば、SSDストレージを備えたノードで実行するアプリケーションや、同じノードで実行するアプリケーションなどです。

nodeSelector
最初にノードのラベルを計画し、次にデプロイメントを作成するときに、nodeSelectorラベルを使用してポッドを実行するノードを指定します。

親和性(親和性)および反親和性(抗親和性):

  • アフィニティ:アプリケーションAとアプリケーションBの2つのアプリケーションは頻繁に相互作用するため、ネットワーク通信によって引き起こされるパフォーマンスの低下を減らすために、アフィニティを使用して2つのアプリケーションを1つのノード上でも可能な限り近づける必要があります。
  • 反親和性:アプリケーションが複数のコピーで展開される場合、HAを改善するために、反親和性を使用して各ノード上の各アプリケーションインスタンスを分散させる必要があります。

含まれるもの:nodeAffinity(ホストアフィニティ)、podAffinity(PODアフィニティ)、およびpodAntiAffinity(PODアンチアフィニティ)

戦略名 ターゲットを一致させる サポートされている演算子 トポロジドメインをサポート 設計目標
nodeAffinity ホストラベル In、NotIn、Exists、DoesNotExist、Gt、Lt サポートしません ポッドを展開できるホストを決定します
podAffinity ポッドタグ In、NotIn、Exists、DoesNotExist 待機する どのポッドをどのポッドと同じトポロジドメインに展開できるかを決定します
PodAntiAffinity ポッドタグ In、NotIn、Exists、DoesNotExist 待機する 同じ拡張機能にデプロイできないポッドを決定します

NodeAffinityの使用シナリオ

  • S1サービスのすべてのポッドを、ラベル付けルールを満たす指定されたホストに展開します。
  • S1サービスのすべてのポッドを、一部のホストを除く他のホストにデプロイします。
    PodAffinityの使用シナリオ:
  • 特定のトポロジドメインを指定せずに、同じトポロジドメインに特定のサービスポッドを展開します。
  • S1サービスがS2サービスを使用する場合、それらの間のネットワーク遅延(またはその他の理由)を減らすために、S1サービスのPODとS2サービスのポッドを同じトポロジドメインに展開します。
    PodAntiAffinityの使用シナリオ:

  • サービス自体の安定性を向上させるために、さまざまなホストまたはトポロジドメインにサービスのPODを分散させます。
  • PODにノードへの排他的アクセスを許可して、リソースの分離を確保し、他のポッドがノードリソースを共有しないようにします。
  • 異なるホスト上で相互に影響を与える可能性のあるサービスのPODを配布します。

オペレーターの関係:

  • で:ラベルの値はリストにあります
  • NotIn:ラベルの値がリストにありません
  • Gt:ラベルの値が特定の値より大きい
  • Lt:ラベルの値が特定の値未満です
  • 存在する:ラベルが存在する
  • DoesNotExist:ラベルが存在しません

nodeSelectorのスケジューリング方法は、わずかに単純です。アフィニティおよび非アフィニティ構成により、スケジューリングのより柔軟な戦略を提供できます。主な機能強化は次のとおりです。

  • ADDと完全一致だけでなく、より多くの式のサポート
  • 厳格な要件の代わりに、ソフト/プリファレンススケジューリング戦略を設定できます
  • スケジューリングの制約は、ノードタグだけでなく、ポッドタグを介して実行できます。

アフィニティ機能には、次の2つの方法があります。

  • requiredDuringSchedulingIgnoredDuringExecution:ハードで厳密に適用され、ルールのスケジュールを満たしています。それ以外の場合はスケジュールされず、事前選択段階で実行されるため、ハードアグリーメントに違反するようにスケジュールされません。
  • PreferredDuringSchedulingIgnoredDuringExecution:ソフト、実行に最善を尽くし、ルールのスケジューリングを満たすことを優先し、優先ステージで実行します
  • requiredDuringSchedulingRequiredDuringExecutionと同様に、requiredDuringSchedulingIgnoredDuringExecutionと同様です。違いは、ポッドの実行中にノードがポッドのアフィニティを満たさなくなった場合、ポッドはノードから削除されることです。

IgnoreDuringExecutionは、ポッド操作中にノードのラベルが変更され、アフィニティポリシーが満たされない場合、現在のポッドが引き続き実行されることを示します。


トポロジキーの制限

  • アフィニティーとソフトアンチアフィニティーの場合、空のtopologyKeyは許可されません。
  • ハードアンチアフィニティの場合、LimitPodHardAntiAffinityTopologyコントローラを使用して、topologyKeyをkubernetes.io/hostnameに制限します。
  • ソフトアンチアフィニティの場合、空のtopologyKeyは、kubernetes.io / hostname、failure-domain.beta.kubernetes.io / zone、failure-domain.beta.kubernetes.io / regionの組み合わせとして解釈されます。

例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-cache
spec:
  selector:
    matchLabels:
      app: redis
  replicas: 3
  template:
    metadata:
      labels:
        app: redis
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - redis
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: redis-server
        image: redis:latest

上記の例では、3つのインスタンスを使用した展開が作成され、ポッド間の非アフィニティ戦略が採用されます。作成されたインスタンスが制限されている場合、同じラベルのインスタンスがノードにすでに存在する場合、展開は実行されないため、回避されます。 1つのノードに複数の同一のインスタンスをデプロイします。

上記の例に基づく:

上記のRedis構成と同じように、さらに3つのWebサービスインスタンスを作成します。最初に2つのWebが同じノードにデプロイされないことを確認してから、ポッド間アフィニティポリシーを適用し、最初にRedisサービスを使用してノードにWebをデプロイします。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
spec:
  selector:
    matchLabels:
      app: web-store
  replicas: 3
  template:
    metadata:
      labels:
        app: web-store
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - web-store
            topologyKey: "kubernetes.io/hostname"
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - redis
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: web-app
        image: nginx:latest

⚠️注:

  • ポッド間のアフィニティ戦略にはかなりの量の計算が必要であり、クラスタのパフォーマンスが大幅に低下する可能性があります。100ノードを超える範囲で使用することはお勧めしません。
  • ポッド間の非アフィニティポリシーでは、すべてのノードに一貫したラベルが必要です。たとえば、クラスター内のすべてのノードには、topologyKeyに一致するラベルが必要です。一部のノードにこれらのラベルがない場合、異常な動作が発生する可能性があります。
  • nodeSelectorとnodeAffinityを同時に指定する場合、ポッドを候補ノードにスケジュールする前に、2つの条件を満たす必要があります。
  • ポッドがノードですでにスケジュールされている場合、ノードのラベルを削除または変更しても、ポッドは削除されません。つまり、アフィニティの選択はポッドのスケジューリング中にのみ有効です。
  • キーの下の値の1つが条件を満たしている限り、現在のキーは条件を満たしています
  • matchExpressionsの下に複数のキーリストがある場合、ポッドは、すべてのキーが満たされた場合にのみ、特定のノードにスケジュールできます[ハードアフィニティ用]。

おすすめ

転載: blog.51cto.com/14034751/2597734