スケジューリングを使用してデータベース クラスタをノードに割り当てる

ドキュメントのバージョンを選択してください。

AlloyDB Omni Kubernetes Operator では、スケジューリングは、新しいデータベース Pod をノードと照合して、クラスタ全体でノードの分散を均衡化し、パフォーマンスの最適化を促進するプロセスです。Pod とノードは、CPU やメモリなど、複数の条件と使用可能なリソースに基づいて照合されます。

スケジューリングの詳細については、Kubernetes ドキュメントのスケジューリング、プリエンプションと退避をご覧ください。

このページでは、Kubernetes マニフェストでプライマリ プール インスタンスと読み取りプール インスタンスの toleration、ノード アフィニティ、トポロジの分散の制約に関するスケジューリング構成を指定する方法について説明します。

ノードで taint を定義する方法については、Kubernetes ドキュメントの Taint と Toleration をご覧ください。

toleration を指定する

他のアプリケーション Pod が存在しないノードに AlloyDB Omni Pod をスケジュールするか、これらのノードで定義された特定の taint と一致させるには、次のように 1 つ以上の toleration をノードに適用します。

  1. AlloyDB Omni Kubernetes Operator クラスタのマニフェストを変更して、次のいずれかの schedulingConfig セクションに tolerations セクションを追加します。
    • プライマリ インスタンスの場合は primarySpec
    • 読み取りプール インスタンスの場合は spec
         tolerations:
          - key: "TAINT_KEY"
            operator: "OPERATOR_VALUE"
            value: "VALUE"
            effect: "TAINT_EFFECT"
       

    次のように置き換えます。

    • TAINT_KEY: taint キーの既存の一意の名前(ノードのホスト名や、toleration が適用されるローカルで推論された値など)。taint キーはノードですでに定義されています。フィールドが空で、OPERATOR_VALUEexists に設定されている場合、toleration はすべての値とすべてのキーと一致している必要があります。
    • OPERATOR_VALUE: キーと値のセットの関係を表します。パラメータを次のいずれかに設定します。
      • exists: taint が定義されている場合、Kubernetes は taint の値に関係なく任意の値と一致させます。
      • equal: 値が異なる場合、Kubernetes は Pod をノードにスケジュールしません。この演算子には taint true 値が必要です。
    • VALUE: toleration と照合される taint 値。演算子が Exists の場合、値は空になります。それ以外の場合は、通常の文字列になります。例: true
    • TAINT_EFFECT: 一致する taint の効果を示します。フィールドが空の場合、すべての taint 効果が一致する必要があることを意味します。パラメータを次のいずれかに設定します。
      • NoSchedule: Kubernetes は、taint が設定されたノードに新しい Pod をスケジュールしません。
      • PreferNoSchedule: Kubernetes は、必要でない限り、taint が追加されたノードに新しい Pod を配置しません。
      • NoExecute: Kubernetes は、taint を許容しない既存の Pod を強制排除します。
  2. マニフェストを再度適用します。

ノード アフィニティを定義する

Kubernetes スケジューラは、Pod の配置場所を決定するために、ノード アフィニティをルールセットとして使用します。ノード アフィニティは、ノードセレクタよりも柔軟で表現性に優れています。

データベースの実行にスケジュールを設定する必要があるノードを指定するには、次の操作を行います。

  1. データベース クラスタ マニフェストを変更し、primarySpec(プライマリ インスタンスの場合)または spec(読み取りプール インスタンスの場合)の schedulingConfig セクションの tolerations セクションの後に nodeaffinity セクションを追加します。
          nodeaffinity:
             NODE_AFFINITY_TYPE:
             - weight: WAIT_VALUE
               preference:
                 matchExpressions:
                 - key: LABEL_KEY
                   operator: OPERATOR_VALUE
                   values:
                   - LABEL_KEY_VALUE
        

    次のように置き換えます。

    • NODE_AFFINITY_TYPE: パラメータを次のいずれかに設定します。
      • requiredDuringSchedulingIgnoredDuringExecution: Kubernetes は、定義されたルールに厳格に従って Pod をスケジュールします。
      • preferredDuringSchedulingIgnoredDuringExecution: Kubernetes スケジューラは、定義されたスケジューリング ルールを満たすノードを探すことを試みます。そのようなノードがない場合、Kubernetes はクラスタ内の別のノードにスケジュールします。
    • WAIT_VALUE: 指定したノードの優先度の重み。値が大きいほど優先度が高くなります。有効な値は 1100 です。
    • LABEL_KEY: ロケーション インジケーターとして機能し、クラスタ全体に Pod を均等に分散するキーのノードのラベル。例: disktype=ssd
    • OPERATOR_VALUE: キーと値のセットの関係を表します。パラメータを次のいずれかに設定します。
      • In: values 配列は空にできません。
      • NotIn: values 配列は空にできません。
      • Exists: values 配列は空にする必要があります。
      • DoesNotExist: values 配列は空にする必要があります。
      • Gt: values 配列には、整数として解釈される単一の要素が必要です。
      • Lt: values 配列には、整数として解釈される単一の要素が必要です。
    • LABEL_KEY_VALUE: ラベルキーの値。次のように、パラメータに文字列値の配列を設定します。
      • 演算子が In または NotIn の場合、値の配列は空にできません。
      • 演算子が Exists または DoesNotExist の場合、値の配列は空にする必要があります。
      • 演算子が Gt または Lt の場合、値の配列には整数として解釈される単一の要素が必要です。
  2. マニフェストを再度適用します。

Pod の反アフィニティを定義する

Pod の反アフィニティにより、Kubernetes スケジューラは、同じノードまたは同じトポロジ ドメイン(ゾーンやリージョンなど)に Pod をスケジュールできなくなります。これにより、サービスのレプリカが分散され、単一障害点を回避できます。

本番環境では、次のラベルを使用して、このアンチアフィニティ ルールを使用して、オペレータ Pod とは異なるノードにデータベース Pod をスケジュールすることをおすすめします。

schedulingconfig:
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchLabels:
          app.kubernetes.io/component: controller
          app.kubernetes.io/name: alloydb-omni-operator
      namespaces:
      - alloydb-omni-system
      topologyKey: kubernetes.io/hostname

データベースに Pod 反アフィニティ ルールを追加する手順は次のとおりです。

  1. データベース クラスタのマニフェスト ファイルを変更して、podAntiAffinity フィールドを追加します。プライマリ インスタンスの primarySpec フィールドまたは読み取りプール インスタンスの spec フィールドのいずれかの schedulingConfig フィールドに podAntiAffinity を追加する必要があります。

    podAntiAffinity:
      POD_ANTI_AFFINITY_TYPE:
      - weight: WEIGHT_VALUE
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: LABEL_KEY
              operator: OPERATOR_VALUE
              values:
              - LABEL_VALUE
          topologyKey: "TOPOLOGY_KEY"
    

    次の変数を置き換えます。

    • POD_ANTI_AFFINITY_TYPE: 次の値のいずれかを使用します。
      • requiredDuringSchedulingIgnoredDuringExecution: Kubernetes は、定義されたルールにのみ基づいて Pod をスケジュールします。
      • preferredDuringSchedulingIgnoredDuringExecution: Kubernetes スケジューラは、定義されたルールを満たすノードを見つけようとします。そのようなノードが見つからない場合、Kubernetes はクラスタ内の別のノードに Pod をスケジュールします。
    • WEIGHT_VALUE: POD_ANTI_AFFINITY_TYPEpreferredDuringSchedulingIgnoredDuringExecution に設定されている場合に使用されます。指定されたノードの優先度を示します。値の範囲は 1100 です。
    • LABEL_KEY: ロケーション インジケーターとして機能し、クラスタ全体に Pod を均等に分散します。
    • OPERATOR_VALUE: 指定された Pod と照合するために使用される演算子。次の値のいずれかを使用できます。
      • In: values 配列は空にできません。
      • NotIn: values 配列は空にできません。
      • Exists: values 配列は空にする必要があります。
      • DoesNotExist: values 配列は空にする必要があります。
    • LABEL_VALUE: LABEL_KEY と照合する 0 個以上の Pod 値。
    • TOPOLOGY_KEY: トポロジ ドメインを定義します。たとえば、kubernetes.io/hostname は同じノード上の Pod を防ぎ、topology.kubernetes.io/zone は Pod を複数のゾーンに分散します。
  2. マニフェスト ファイルを再度適用します。

トポロジの分散の制約を定義する

Kubernetes Pod API の spec にあり、そのため AlloyDB Omni データベース クラスタ マニフェストの schedulingConfig にもある topologySpreadConstraints フィールドは、クラスタ内のゾーン、ノード、リージョンなどのさまざまなトポロジ ドメインに Pod を分散する方法を制御します。これにより、単一障害点に AlloyDB Omni データベース クラスタ Pod が過剰に配置されるのを防ぎ、高可用性とバランスの取れたリソース使用率の実現を促進できます。

AlloyDB Omni データベース クラスタがクラスタ トポロジ全体にどのように分散されるかを指定するには、プライマリ インスタンスの場合は primarySpec、読み取りプール インスタンスの場合は specschedulingConfigtopologySpreadConstraints セクションを追加します。

schedulingconfig:
      # Other scheduling configs like tolerations, nodeaffinity
      topologySpreadConstraints:
        - maxSkew: MAXSKEW_VALUE
          topologyKey: "TOPOLOGY_KEY"
          whenUnsatisfiable: WHEN_UNSATISFIABLE_VALUE
          # labelSelector: <object> # optional
          # minDomains: <integer> # optional
          # matchLabelKeys: <list> # optional
          # nodeAffinityPolicy: [Honor|Ignore] # optional
          # nodeTaintsPolicy: [Honor|Ignore] # optional

次のように置き換えます。

  • MAXSKEW_VALUE: 任意の 2 つのトポロジ ドメイン間で一致する Pod の数の許容される最大差を定義します。このパラメータは 0 より大きい値にする必要があります。
  • TOPOLOGY_KEY: トポロジ ドメインを定義するノードラベルのキー(例: ゾーンの場合の topology.kubernetes.io/zone)。スケジューラは、これらのドメイン間で Pod のバランスを取ろうとします。
  • WHEN_UNSATISFIABLE_VALUE: Pod がスプレッド制約を満たしていない場合に、スケジューラが Pod をどのように処理するかを示します。パラメータを次のいずれかに設定します。
    • DoNotSchedule: スプレッド制約が満たされていない場合、スケジューラは Pod をノードにスケジュールしません。これはデフォルト値です。
    • ScheduleAnyway: スケジューラは引き続き Pod をスケジュールしますが、スキューを最小限に抑えるノードを優先します。

Pod トポロジの分散の制約の詳細については、公式の Kubernetes ドキュメントをご覧ください。

次の例は、AlloyDB Omni Kubernetes Operator プライマリ インスタンスと読み取りプール インスタンスで Pod をスケジュールする方法を示しています。このようなスケジューリングにより、データベース クラスタのプライマリ インスタンスが適切なノードにスケジュールされ、ノードの選択に柔軟性を持たせることができます。この柔軟性は、負荷の分散、リソース使用量の最適化、特定のノードロールと特性の遵守に役立ちます。

    schedulingconfig:
      tolerations:
      - key: "node-role.kubernetes.io/control-plane"
        operator: "Exists"
        effect: "NoSchedule"
      nodeaffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 1
          preference:
            matchExpressions:
            - key: another-node-label-key
              operator: In
              values:
              - another-node-label-value
      podAntiAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - my-app
          topologyKey: "kubernetes.io/hostname"
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: "topology.kubernetes.io/zone"
          whenUnsatisfiable: DoNotSchedule

この toleration の例ではコントロール プレーン ノードとしてマークされているノードで Pod をスケジュールできます。その理由の詳細は以下のとおりです。

  • node-role.kubernetes.io/control-plane taint キーは、ノードにコントロール プレーン ノードがあることを示します。
  • Exists 演算子は、toleration が値に関係なく、指定された taint キーを持つ任意の taint と一致することを意味します。
  • NoSchedule の効果は、一致する toleration がなければ、Pod がコントロール プレーン ノードにスケジュールされないことを意味します。

preferredDuringSchedulingIgnoredDuringExecution ノード アフィニティ タイプは、ノード アフィニティに定義されたルールが優先されることを指定しますが、スケジュール時に必須ではありません。優先ノードが使用できない場合、Pod が他のノードにスケジュールされることがあります。1 の重み値は、優先度が低いことを示します。ノードの選択条件は preference セクションで定義されています。matchExpressions セクションには、ノードとの照合に使用される式の配列が含まれています。another-node-label-key キーは、一致するノードラベルのキーを表します。In 演算子は、ノードに指定された値のいずれかを含むキーが必ず存在することを意味します。another-node-label-key キーには another-node-label-value の値を設定する必要があります。

ノード アフィニティ ルールの例は、another-node-label-value 値の another-node-label-key ラベルを持つノードで Pod をスケジュールすることを示しています。優先度は低く、必須ではありません。

この例の podAntiAffinity ルールは、ラベル app: my-app を持つ Pod が同じホスト名でスケジュールされないようにします。これにより、my-app のレプリカが異なるノードに分散され、フォールト トレランスが向上します。

この例の topologySpreadConstraints は、Pod を異なる Kubernetes ゾーンに分散します。1maxSkew 値は、任意のゾーンで、他のゾーンの最小 Pod 数と比較して、最大 1 つ多くの Pod を配置できることを示します。whenUnsatisfiable 設定の値が DoNotSchedule の場合、この制約を満たせないと、Pod はスケジュールされていない状態のままになります。

この例では、次のものを組み合わせています。

  • NoSchedule taint を許容して Pod をコントロール プレーン ノードにスケジュールできるようにする toleration。
  • 特定のラベルを持つノードを優先するが、厳密に要求するものではないノード アフィニティ。これにより、スケジューリングの柔軟性が向上します。
  • ラベル app: my-app の Pod が同じホスト名にスケジュールされないようにする Pod の反アフィニティ ルール。
  • アベイラビリティ ゾーン間で Pod のバランスの取れた分散を強制し、復元性を高め、リソース使用率を向上させるトポロジの分散の制約。

次のステップ