Container Service for Kubernetes では、ギャングスケジューリングとトポロジー対応スケジューリングを組み合わせることで、Pod が適切なトポロジードメインを見つけるまで複数のドメイン間でスケジューリングをリトライできるようにします。また、ノードプールと ECS のデプロイメントセット機能を組み合わせることで、同じ低レイテンシーデプロイメントセット内の ECS インスタンスに Pod をスケジューリングできるため、きめ細かいトポロジードメインでのアフィニティスケジューリングが可能になります。このトピックでは、トポロジー対応スケジューリングを実装する方法について説明します。
概要
機械学習やビッグデータ分析のジョブでは、Pod に高いネットワーク通信要件が必要なことがよくあります。デフォルトでは、ネイティブの Kubernetes スケジューラーはクラスター全体に Pod を均等に分散させます。これにより、通信距離が長くなり、ジョブの完了時間が長くなります。ジョブの実行を最適化するために、同じアベイラビリティーゾーンまたは同じラックに Pod をデプロイすることで、ネットワークホップとレイテンシーを削減できます。Kubernetes は、NodeAffinity と PodAffinity を通じてアフィニティスケジューリングをネイティブにサポートしています。しかし、このネイティブのアフィニティスケジューリングには、以下の制限があります。
-
Pod は、異なるトポロジードメイン間でスケジューリングをリトライできません。ネイティブの Kubernetes アフィニティスケジューリングでは、ジョブ全体のスケジューリングは最初の Pod の配置によって決定されます。最初の Pod の場所がジョブ内のすべての Pod を収容できない場合、一部の Pod は Pending 状態のままになります。別のトポロジードメインがジョブ全体を収容できる場合でも、スケジューラーは自動的に別のアベイラビリティーゾーンに切り替えません。
-
現在、ノードにはアベイラビリティーゾーンレベルのラベルしかありません。その結果、Pod のアフィニティは単一のアベイラビリティーゾーンに限定され、Pod をよりきめ細かいトポロジードメインに固定することはできません。
複数のトポロジードメイン間でのスケジューリングのリトライ
ジョブにギャングスケジューリング識別子を追加することで、すべての Pod のリソースを同時に割り当て、複数のトポロジードメイン間でスケジューリングをリトライできるようになります。
-
Pod のラベルにギャングスケジューリング識別子を追加します。ギャングスケジューリングの詳細については、「ギャングスケジューリングの操作」をご参照ください。
... labels: pod-group.scheduling.sigs.k8s.io/name: tf-smoke-gpu # tf-smoke-gpu は PodGroup の名前です。カスタム値を指定します。 pod-group.scheduling.sigs.k8s.io/min-available: "3" # この値はジョブ内の Pod 数に設定できます。 ... -
トポロジー対応スケジューリングの制約を Pod のアノテーションに追加します。
annotations: alibabacloud.com/topology-aware-constraint: {\"name\":\"test\",\"required\":{\"topologies\":[{\"key\":\"kubernetes.io/hostname\"}],\"nodeSelectors\":[{\"matchLabels\":{\"test\":\"abc\"}}]}}alibabacloud.com/topology-aware-constraintの値は、以下の構造を持つ有効な JSON 文字列である必要があります。{ "name": xxx, # 任意の名前。 "required": { "topologies": [ { "key": xxx # アフィニティのトポロジードメインを指定するキー。 } ], "nodeSelectors": [ { # この構造は、ネイティブ Kubernetes の nodeAffinity の labelSelector 形式に従います。 "matchLabels": {}, "matchExpressions": {} } ] } }この設定を適用すると、スケジューラーは
pod-group.scheduling.sigs.k8s.io/name: tf-smoke-gpuラベルを持つすべての Pod を、test=abcラベルに一致するノードに配置します。次の出力は一例です:kubectl get pod -ojson | jq '.items[] | {"name":.metadata.name,"ann":.metadata.annotations["alibabacloud.com/topology-aware-constraint"], "node": spec.nodeName}' { "name": "nginx-deployment-basic-69f47fc6db-6****", "ann": "{\"name\": \"test\", \"required\": {\"topologies\":[{\"key\": \"kubernetes.io/hostname\"}], \"nodeSelectors\": [{\"matchLabels\": {\"test\": \"abc\"}}]}} ", "node": "cn-shenzhen.10.0.2.4" } { "name":"nginx-deployment-basic-69f47fc6db-h****", "ann": "{\"name\": \"test\", \"required\": {\"topologies\":[{\"key\": \"kubernetes.io/hostname\"}], \"nodeSelectors\": [{\"matchLabels\": {\"test\": \"abc\"}}]}} ", "node": "cn-shenzhen.10.0.2.4" }
低レイテンシーデプロイメントセットへのスケジューリング
シナリオによっては、ジョブが最適なパフォーマンスを達成するために、よりきめ細かいトポロジードメイン内でのアフィニティを必要とする場合があります。ECS は、ECS ノードの配置を制約する低レイテンシーデプロイメントセットを提供します。詳細については、「デプロイメントセットとノードプールの関連付けに関するベストプラクティス」をご参照ください。
低レイテンシーデプロイメントセットを使用するノードプールを作成する際には、他のノードプールと区別するためにカスタムノードラベルも追加する必要があります。
上記の手順を完了したら、次のアノテーションとラベルを使用して、低レイテンシーデプロイメントセット内にジョブをスケジューリングします。
-
Pod のラベルにギャングスケジューリング識別子を追加します。ギャングスケジューリングの詳細については、「ギャングスケジューリングの操作」をご参照ください。
labels: pod-group.scheduling.sigs.k8s.io/name: xxx # xxx は PodGroup の名前です。カスタム値を指定します。 pod-group.scheduling.sigs.k8s.io/min-available: "x" # この値はジョブ内の Pod 数に設定できます。 -
トポロジー対応スケジューリングの制約を Pod のアノテーションに追加します。
重要低レイテンシーデプロイメントセットのカスタムノードラベルで
matchLabelsを置き換え、必要に応じてnameを変更してください。annotations: alibabacloud.com/topology-aware-constraint: {\"name\":\"test\",\"required\":{\"topologies\":[{\"key\":\"alibabacloud.com/nodepool-id\"}],\"nodeSelectors\":[{\"matchLabels\":{\"np-type\":\"low-latency\"}}]}}