# Dynamic EngineのアフィニティとnodeSelectorルールの設定

Dynamic Engine HelmチャートでnodeSelectorとアフィニティルールを使用することで、Kubernetesクラスター内の異なるノードグループ間でのPodのスケジューリングを制御できます。

Dynamic Engine v1.1.0以降では、セキュリティ、パフォーマンス、リソース最適化などの目的で、特定のノード上でサービスを分離するための特定のアフィニティルールを設定できます。たとえば、大規模なノードグループを確保して、集中的なポッド実行に使用できます。

Dynamic Engine v1.1.0は、Helm値ファイルにおいて、nodeSelector(シンプルなラベルベースの選択)とアフィニティルール(複雑なスケジューリングロジック)の両方をサポートしています。

情報メモ重要: このカスタマイズは、チャートの初回インストール時、またはアップグレード時に適用できます。

## 始める前に

* dynamic-engine-crdカスタムリソース定義は、oci://ghcr.io/talend/helm/dynamic-engine-crd Helmチャートを使用してインストールされている必要があります。インストールされていない場合は、次のコマンドを実行してインストールしてください。
  1. 使用するチャートのバージョンを見つけます。

     * 次のHelmコマンドを実行します:
       ```
       helm show chart oci://ghcr.io/talend/helm/dynamic-engine-crd --version <engine_version>
       ```
     * Talend Management Consoleから直接バージョンを見るか、自分のDynamic Engineバージョンに含まれているチャートバージョンの[Dynamic Engine変更ログ](https://help.qlik.com/talend/en-US/dynamic-engine-changelog/Cloud)をチェックしてください。
     * [Dynamic Engineバージョンエンドポイント](https://talend.qlik.dev/apis/dynamic-engine/2021-03/#operation_return-all-supported-dynamic-engine-versions)へのAPIコールを使用します。

  2. 次のコマンドを実行し、目的のバージョンのHelmチャートをインストールします。

     ```
     helm install dynamic-engine-crd oci://ghcr.io/talend/helm/dynamic-engine-crd --version <helm_chart_version>
     ```

     &lt;helm\_chart\_version&gt;を、お使いのDynamic Engineバージョンでサポートされているチャートのバージョンに置換します。

     バージョンを指定しないと、利用可能な最新のdynamic-engine-crdチャートバージョンがインストールされます。
* Kubernetesクラスターは、適切なラベルが付与された複数のノードグループ(ノードプール)で構成されている必要があります。この構成の設定方法については、使用中のクラウドプロバイダーが提供する関連ドキュメントを参照してください。例: KubernetesとGKEを使用している場合は、[クラスタとノードプールのラベルを作成して管理する](https://docs.cloud.google.com/kubernetes-engine/docs/how-to/creating-managing-labels)を参照してください。
* [Kubernetesのアフィニティルール](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node)に関する基本的な知識が必要です。

## このタスクについて

デフォルトでは、Dynamic Engineポッドはクラスター内の利用可能なすべてのノードにスケジュールされます。ノードアフィニティとノードセレクタールールを使用することで、ポッドの配置を制御し、次のような特定の目標を達成できます。

* 永続的なサービスを小規模な専用ノードに分離する
* ジョブ、ルート、データサービスなどのワークロードを、特定のインスタンスタイプを備えた大規模なノードで実行する

使用するノードラベルの例は次のとおりです。

* instanceType=large
* instanceType=medium
* qlik-dynamic-engine-tasks=true

## 手順

1. Kubernetesマシンで、ダウンロードしておいたHelmデプロイメントのzipファイルを解凍します。
2. グローバルスケジューリングルールにnodeSelectorを使用するカスタム値ファイルを作成します。
   ### 例

   この例では、インフラストラクチャ用の永続的なサービスをミディアムノードで実行するためのグローバルルールが定義されています。このルールは、instanceType=mediumというラベルが付いたノードに、すべてのDynamic Engineおよび環境ポッドをスケジュールします。
   ```
   cat <<EOF > custom-medium-instance-for-infrastructure-values.yaml
   global:
     nodeSelector:
       instanceType: medium
   EOF
   ```

   nodeSelectorは単純な完全一致に適していますが、論理式はサポートしていません。
3. または、アフィニティルールを使用してカスタム値ファイルを作成することで、より高度なスケジューリングロジックを用いて同じ結果を実現することもできます。
   ### 例

   この例は、nodeSelectorを使用した場合と同じ結果を、nodeAffinityを使用して実現しています。
   ```
   cat <<EOF > custom-medium-instance-for-infrastructure-values.yaml
   global:
     affinity:
       nodeAffinity:
         requiredDuringSchedulingIgnoredDuringExecution:
           nodeSelectorTerms:
             - matchExpressions:
                 - key: instanceType
                   operator: In
                   values: medium
   EOF
   ```

   情報メモヒント: nodeSelectorとアフィニティルールは組み合わせることができます。両方を指定した場合、ポッドがそのノードにスケジュールされるには、ノードが両方のルールを満たす必要があります。
4. グローバルスケジューリングルールを使用して、Dynamic Engine環境とDynamic Engine環境をデプロイします。
   ```
   helm upgrade --install dynamic-engine-$DYNAMIC_ENGINE_ID -f $DYNAMIC_ENGINE_ID-values.yaml  \
    -f custom-medium-instance-for-infrastructure-values.yaml \
    oci://ghcr.io/talend/helm/dynamic-engine \
    --version $DYNAMIC_ENGINE_VERSION

   helm upgrade --install dynamic-engine-environment-$DYNAMIC_ENGINE_ENVIRONMENT_ID -f $DYNAMIC_ENGINE_ENVIRONMENT_ID-values.yaml  \
    -f custom-medium-instance-for-infrastructure-values.yaml \
    oci://ghcr.io/talend/helm/dynamic-engine-environment \
    --version $DYNAMIC_ENGINE_VERSION
   ```
5. ワークロード固有のスケジューリングでは、Podが大規模なノードグループ上で実行されるように制約を設ける別のカスタム値ファイルを作成します。
   ### 例

   この例では、データ統合タスク、データサービス、およびルートタスクを、qlik-dynamic-engine-tasks=trueというラベルが付いた大規模ノードに限定するための特定のルールが定義されています。
   ```
   cat <<EOF > custom-jobDeployment-dataServiceRouteDeployment-nodeSelector-values.yaml
   configuration:
     jobDeployment:
       nodeSelector:
         instanceType: large
         qlik-dynamic-engine-tasks: "true"
     dataServiceRouteDeployment:
       nodeSelector:
         instanceType: large
         qlik-dynamic-engine-tasks: "true"
   EOF
   ```
6. ワークロード固有のスケジューリングルールを使用してDynamic Engine環境をデプロイします。
   ### 例

   このワークロードルールはタスク処理サービスに特化したものであり、Dynamic Engine環境でのみ適用されます。
   ```
   helm upgrade --install dynamic-engine-environment-$DYNAMIC_ENGINE_ENVIRONMENT_ID \
    -f $DYNAMIC_ENGINE_ENVIRONMENT_ID-values.yaml  \
    -f custom-jobDeployment-dataServiceRouteDeployment-nodeSelector-values.yaml \
    oci://ghcr.io/talend/helm/dynamic-engine-environment \
    --version $DYNAMIC_ENGINE_VERSION
   ```

## タスクの結果

デプロイが正常に完了すると、すべてのDynamic Engineと環境ポッドは、ユーザーが設定したアフィニティおよびnodeSelectorルールに従ってスケジュールされます。インフラストラクチャ向けの永続的なサービスは専用のノード上で実行され、顧客のワークロードはそれぞれのリソース要件に合わせて最適化されたノード上で実行されます。

トラブルシューティング:

ポッド(または複数のポッド)がノードにスケジュールできない場合は、次の手順に従って問題を診断し、解決してください。

1. スケジューリングの失敗を特定します。

   kubectl describe podコマンドを使用して、スケジューリングエラーに関する詳細情報を取得します。

   ```
   kubectl describe pod <pod-name> -n <namespace>
   ```

   [イベント]セクションを探します。スケジューラが失敗した理由に関する手がかりが記載されています。一般的な原因には次のようなものがあります。

   * ルールに一致するノードがない
   * 利用可能なノードのCPUまたはメモリリソースが不足している
   * ノードに設定されたtaintとtolerationの問題により、Podのスケジューリングが妨げられている

2. ルールの検証:

   ノードに、ルールで指定されている必要なラベルが付いていることを確認します。

   ```
   kubectl get nodes --show-labels
   ```

   ノードに付けられたラベルと、値ファイルで指定されているラベルを比較します。

3. リソース制約の検証:

   スケジューリングの失敗の原因の多くは、リソース(CPU、メモリ)の不足です。ポッドのリソース要求と制限を確認します。

   ```
   kubectl describe nodes
   ```

   クラスターにリソース要求を満たすのに十分なノードがない場合は、ノードを追加してクラスターをスケールアップしてください。

4. 指定されたノード上のtaintおよびtolerationの仕様を確認します。

   taintは、ノードが特定のポッドをスケジュールすることを妨げる可能性があります。ノードにtaintが設定されていて、ポッドに対応するtolerationが設定されていない場合、ポッドはスケジュールされません。Kubernetesのtaintとtolerationに関する詳細については、「[Taintと Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)を参照してください。

   Dynamic Engine v1.4.0 以降、Helmのvaluesファイルでtolerationがサポートされました。tolerationルールを設定し、taintが付与されたノードにPodがスケジュールされるようにするには、[Dynamic Engineのtolerationルールの設定](https://help.qlik.com/talend/ja-JP/dynamic-engine-configuration-guide/Cloud/configuring-toleration-rules "Dynamic Engine Helmチャートでtolerationを使用し、taintが付与されたKubernetesノードにPodがスケジュールされるようにします。")を参照してください。