このトピックでは、Container Service for Kubernetes (ACK) クラスターでSlurmとKubernetesの同時配置スケジューリングを実装する方法について説明します。 このソリューションは、クラスター内のハイパフォーマンスコンピューティング (HPC) ジョブとコンテナ化アプリケーションのリソース割り当てとワークロードスケジューリングを最適化するのに役立ちます。 さらに、このソリューションは、リソース使用率、クラスターの安定性、およびワークロードのパフォーマンスを向上させます。 このソリューションを使用して、さまざまなコンピューティングシナリオの要件を満たし、高い効率と柔軟性を備えたコンピューティングプラットフォームを構築できます。
概要
ACKクラスターにコロケートスケジューリングを実装する必要があるのはなぜですか?
デフォルトのスケジューリングソリューション: ACKはリソースを静的に割り当てます。 ACKとSlurmは、ワークロードを個別にスケジュールします。 Slurmクラスターでは、各Slurmポッドはクラスターリソースを事前に占有します。 Kubernetesは、Slurmポッドによって事前に占有されているアイドルリソースを使用できません。 これは、クラスタリソース断片をもたらす。 Slurmポッドのリソース構成を変更する場合は、ポッドを削除してから再作成する必要があります。 したがって、Slurmクラスターが占有するリソースとKubernetesクラスターが占有するリソースの間に大きなギャップがあるシナリオでは、ワークロードを他のノードに移行することは困難です。
コロケートされたスケジューリングソリューション: ACKは、ackクラスター内のslurmとKubernetesのコロケートされたスケジューリングを実装するためのACK-Slurm-operatorコンポーネントを提供します。 このソリューションは、Kubernetesクラスターで副操縦士を実行し、Slurmクラスターで拡張リソースプラグインを実行します。 これにより、KubernetesとSlurmはクラスターリソースを共有でき、リソースの繰り返し割り当てを回避できます。
次の図は、前述のリソース共有ソリューションを示しています。
静的リソース割り当てと個別のワークロードスケジューリング | SlurmとKubernetesの一括スケジューリング |
次の図は、共同配置スケジューリングソリューションの動作を示しています。

キーコンポーネント | 説明 |
SlurmOperator | このコンポーネントは、ACKクラスターでSlurmクラスターを起動します。 Slurmクラスターはコンテナー化され、各Slurmワーカーポッドは別のノードで実行されます。 他のSlurmシステムコンポーネントは、ランダムノードにスケジュールされる。 |
SlurmCopilot | このコンポーネントは、クラスタートークンを使用して、リソース割り当てのslurmctldと調整します。 デフォルトでは、slurmctldが起動されると、コンポーネントは自動的にトークンを生成し、kubectlを使用してトークンをSecretに更新します。 手動でトークンを更新するには、カスタム初期化スクリプトを使用するか、シークレットの更新権限を取り消すことができます。 次に、トークンをack-slurm-operator名前空間のack-slurm-jwt-tokenに手動で更新する必要があります。 ack-slurm-jwt-tokenはキーと値のペアです。 キーはクラスター名で、値は生成されたトークンのBase64-encoded内容です (base64 -- wrap=0) 。 承認チェックがGenericNodeに追加された後、このコンポーネントはslurmctId内の対応するノード上の利用可能なリソースの量を変更します。 変更が完了すると、リソースステータスがGenericNodeに更新されます。 次に、このコンポーネントは、ACKスケジューラにワークロードスケジューリングを実行するように通知する。 |
Slurmctld | Slurmの中央マネージャー。 このコンポーネントは、Slurmクラスター内のリソースとジョブを監視し、ジョブをスケジュールし、リソースを割り当てます。 slurmctldの可用性を向上させるために、slurmctldのセカンダリポッドを構成できます。 |
GenericNodes | このコンポーネントは、KubernetesとSlurm間のリソース台帳として機能するカスタムリソースです。 ACKスケジューラがポッドをノードにスケジュールする場合、許可チェックがノードのGenericNodeに追加され、Slurmシステムにリソース割り当ての確認を要求します。 |
Slurmd | 各コンピューティングノードで実行されるデーモン。 このコンポーネントはジョブを実行し、ノードとジョブのステータスをslurmctldに報告します。 |
Slurmdbd | Slurmデータベースデーモン。 このコンポーネントは、さまざまなジョブの台帳情報を記録および管理し、データクエリと統計のAPI操作を提供します。 slurmdbdはオプションのコンポーネントです。 slurmdbdをインストールしない場合は、元帳情報をファイルに記録できます。 |
Slurmrested | RESTful APIを呼び出してSlurmと対話し、Slurmの機能を使用できるRESTful APIデーモン。 slurmrestdはオプションのコンポーネントです。 slurmrestdをインストールしない場合は、コマンドラインツールを使用してSlurmと対話できます。 |
1. 環境の配置
1.1 ack-slurm-operatorのインストール
Kubernetes 1.26以降を実行するACKクラスターが作成されます。 詳細については、「GPU高速化ノードを使用したACKクラスターの作成」および「クラスターの更新」をご参照ください。
ack-slurm-operatorをインストールし、Copilot機能を有効にします。 これにより、Slurmを使用してジョブをスケジュールし、Kubernetesを使用して同じバッチの物理サーバー上のポッドをスケジュールすることができます。
ACK コンソールにログインします。 作成したクラスターの名前をクリックします。 クラスターの詳細ページで、コールアウトを順番にクリックしてack-slurm-operatorをインストールします。
[アプリケーション名] および [名前空間] パラメーターはオプションです。 [次へ] (コールアウト ④) をクリックします。 [確認] メッセージで、[はい] をクリックします。 この場合、デフォルトのアプリケーションack-slurm-operatorとデフォルトの名前空間ack-slurm-operatorが使用されます。

チャートバージョンの最新バージョンを選択します。
enableCopilot(callout ②) をtrueに、watchNamespace(callout ③) をdefaultに設定します。 ビジネス要件に基づいて、watchNamespaceをカスタム名前空間に設定できます。 次に、[OK] をクリックしてack-slurm-operatorをインストールします。
オプション: ack-slurm-operatorを更新します。
ACK コンソールにログインします。 [クラスター情報] ページで、[アプリケーション]> [ヘルム] を選択します。 [アプリケーション] ページで、[ack-slurm-operator] を見つけ、[更新] をクリックします。
1.2 ack-slurm-clusterのインストールと構成
Slurmクラスターを迅速にデプロイおよび管理し、クラスターの設定を柔軟に変更するために、Helmを使用してAlibaba Cloudが提供するSlurmClusterartパッケージをインストールできます。 チャートインキュベーターからSlurmクラスターのHelmチャートをダウンロードし、関連するパラメーターを設定します。 次に、Helmはロールベースのアクセス制御 (RBAC) リソース、ConfigMaps、Secrets、およびSlurmクラスターを作成します。
次の操作を実行します。
次のコマンドを実行して、Alibaba Cloudが提供するチャートリポジトリをHelmクライアントに追加します。リポジトリの追加後、Alibaba Cloudが提供するHelmチャート (ack-slurm-clusterコンポーネントのチャートなど) にアクセスできます。
helm repo add aliyun https://aliacs-app-catalog.oss-cn-hangzhou.aliyuncs.com/charts-incubator/次のコマンドを実行して、ack-slurm-clusterチャートをプルして解凍します。 この操作により、現在のディレクトリに
ack-slurm-clusterという名前のサブディレクトリが作成されます。 ack-slurm-clusterディレクトリには、チャートに含まれるすべてのファイルとテンプレートが含まれます。helm pull aliyun/ack-slurm-cluster --untar=true次のコマンドを実行して、values.yamlファイルのグラフパラメーターを変更します。
values.yamlファイルには、グラフのデフォルト設定が含まれています。 ビジネス要件に基づいて、ファイル内のパラメーター設定を変更できます。 設定には、Slurm設定、リソース要求と制限、およびストレージ設定が含まれます。
cd ack-slurm-cluster vi values.yaml次のコマンドを実行して、ack-slurm-clusterチャートをインストールします。 ack-slurm-clusterチャートが既にインストールされている場合は、helm upgradeコマンドを実行して、インストールされているチャートを更新できます。 インストールされたチャートを更新した後、既存のポッドとslurmctld用に作成されたStatefulSetを手動で削除して、更新を有効にする必要があります。
cd .. helm install my-slurm-cluster ack-slurm-cluster # Replace my-slurm-cluster with the actual value.チャートをインストールした後、
helm listコマンドを実行して、ack-slurm-clusterチャートが正常にインストールされているかどうかを確認します。helm list想定される出力:
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION ack-slurm-cluster default 1 2024-07-19 14:47:58.126357 +0800 CST deployed ack-slurm-cluster-2.0.0 2.0.0slurmrestdとslurmdbdが期待どおりに実行されるかどうかを確認します。
kubectlを使用してクラスターに接続し、slurmdbdポッドが期待どおりに実行されるかどうかを確認します。
kubectl get pod次のサンプル出力は、1つのワーカーポッドと3つの制御プレーンポッドがクラスターで実行されることを示しています。
NAME READY STATUS RESTARTS AGE slurm-test-slurmctld-dlncz 1/1 Running 0 3h49m slurm-test-slurmdbd-8f75r 1/1 Running 0 3h49m slurm-test-slurmrestd-mjdzt 1/1 Running 0 3h49m slurm-test-worker-cpu-0 1/1 Running 0 166m次のコマンドを実行してログを照会します。 ログを表示して、slurmdbdが期待どおりに実行されるかどうかを確認できます。
kubectl exec slurm-test-slurmdbd-8f75r cat /var/log/slurmdbd.log | head想定される出力:
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. [2024-07-22T19:52:55.727] accounting_storage/as_mysql: _check_mysql_concat_is_sane: MySQL server version is: 8.0.34 [2024-07-22T19:52:55.737] error: Database settings not recommended values: innodb_lock_wait_timeout [2024-07-22T19:52:56.089] slurmdbd version 23.02.7 started
[Show the steps to build a Slurm image] をクリックして、Slurmに依存関係をインストールする方法を表示します。
2. 共同配置されたスケジューリングのテスト
2.1 共同配置されたスケジューリングのテスト
GenericNodesのステータスを確認して、SlurmワークロードとKubernetesワークロードを表示します。
kubectl get genericnode想定される出力:
NAME CLUSTERNAME ALIAS TYPE ALLOCATEDRESOURCES cn-hongkong.10.1.0.19 slurm-test-worker-cpu-0 Slurm [{"allocated":{"cpu":"0","memory":"0"},"type":"Slurm"},{"allocated":{"cpu":"1735m","memory":"2393Mi"},"type":"Kubernetes"}]次のコマンドを実行して、Slurmクラスターにジョブを送信し、GenericNodesをクエリします。 返されたGenericNodeは、Slurmクラスター内のジョブのリソース使用量とKubernetesクラスター内のジョブのリソース使用量を記録します。
root@iZj6c1wf3c25dbynbna3qgZ ~]# kubectl exec slurm-test-slurmctld-dlncz -- nohup srun --cpus-per-task=3 --mem=4000 --gres=k8scpu:3,k8smemory:4000 sleep inf & [1] 4132674 [root@iZj6c1wf3c25dbynbna3qgZ ~]# kubectl scale deployment nginx-deployment-basic --replicas 2 deployment.apps/nginx-deployment-basic scaled [root@iZj6c1wf3c25dbynbna3qgZ ~]# kubectl get genericnode NAME CLUSTERNAME ALIAS TYPE ALLOCATEDRESOURCES cn-hongkong.10.1.0.19 slurm-test-worker-cpu-0 Slurm [{"allocated":{"cpu":"3","memory":"4000Mi"},"type":"Slurm"},{"allocated":{"cpu":"2735m","memory":"3417Mi"},"type":"Kubernetes"}]この場合、別のジョブをSlurmクラスターに送信すると、2番目のジョブはPending状態になります。
[root@iZj6c1wf3c25dbynbna3qgZ ~]# kubectl exec slurm-test-slurmctld-dlncz -- nohup srun --cpus-per-task=3 --mem=4000 sleep inf & [2] 4133454 [root@iZj6c1wf3c25dbynbna3qgZ ~]# srun: job 2 queued and waiting for resources [root@iZj6c1wf3c25dbynbna3qgZ ~]# kubectl exec slurm-test-slurmctld-dlncz -- squeue JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON) 2 debug sleep root PD 0:00 1 (Resources) 1 debug sleep root R 2:34 1 slurm-test-worker-cpu-0
この例では、GREは手動で指定されません。 ただし、前のsrunコマンドではGREが表示されます。 これは、Slurmクラスターにはjob_resource_completionプラグインがプリインストールされており、CPUリクエストとメモリリクエストに基づいて自動的にGREが追加されるためです。 job_resource_completionがインストールされていない場合は、GREを手動で指定する必要があります。 この例では、次のGRE設定が指定されています。-- gres=k8scpu:3,k8smemory:4000。 [Slurmジョブスクリプトの説明を表示] をクリックして、Slurmジョブスクリプトでパラメーターを指定する方法を表示します。
オプション: 2.2コンテナ化されていないSlurmクラスターで同一場所に配置されたスケジューリングを実装する
SlurmCopilotはSlurm APIを使用してSlurmと対話します。 この相互作用方法は、非コンテナ化Slurmクラスターシナリオにも適用されます。
コンテナ化されていないSlurmクラスターシナリオでは、特定のKubernetesリソースを手動でのみ作成できます。 次のセクションでは、手動で作成する必要があるKubernetesリソースについて説明します。
Slurmクラスターごとにサービスを作成します。
SlurmCopilotは、クラスターからサービスに関する情報を照会し、APIリクエストを
${.metadata.name}.${.metadata.nameスペース}.svc.cluster.local :${.spec.ports[0].port}のエンドポイントに送信します。 コンテナー化されていないSlurmクラスターのシナリオでは、Slurmクラスターごとにサービスを作成する必要があります。 次のコードブロックは、サービス構成の例を示しています。 Slurmクラスターのサービスの名前は、${slurmCluster}-slurmrestd形式でなければなりません。 ${slurmCluster} の値は、SlurmクラスターのGenericNodesと一致する必要があります。apiVersion: v1 kind: Service metadata: name: slurm-slurmrestd namespace: default spec: ports: - name: slurmrestd port: 8080 protocol: TCP targetPort: 8080各SlurmクラスターのDNSレコードを設定します。
slurmrestdプロセスへのアクセスを有効にするには、SlurmCopilot設定で、
${.metadata.name}.${.metadata.name空間}.svc.cluster.local :${.spec.ports[0].port}をslurmrestdプロセスのIPアドレスにポイントするようにDNSレコードを設定する必要があります。Slurmクラスター内のノードのGenericNodesを作成します。
SlurmCopilotは、SlurmクラスターのノードのエイリアスとしてGenericNodesを使用します。 Slurmクラスター内のノードのGenericNodeを作成しない場合、SlurmCopolitはノードに関する情報を取得できません。 ノードのGenericNodeの名前は、Kubernetesシステムのノード名と同じである必要があります。 の値は、
. spec.aliasパラメーターはSlurmシステムのノード名と同じである必要があります。kai.alibabacloud.com/cluster-nameラベルとkai.alibabacloud.com/cluster-namespaceラベルは、Slurmクラスターのサービスと一致する必要があります。apiVersion: kai.alibabacloud.com/v1alpha1 kind: GenericNode metadata: labels: kai.alibabacloud.com/cluster-name: slurm-test kai.alibabacloud.com/cluster-namespace: default name: cn-hongkong.10.1.0.19 spec: alias: slurm-test-worker-cpu-0 type: Slurm
概要
ワークロードコロケーション環境では、Slurmを使用してHPCジョブをスケジュールし、Kubernetesを使用してコンテナ化されたワークロードを調整できます。 このコロケートされたスケジューリングソリューションでは、Helmチャート、継続的インテグレーション /継続的デリバリー (CI/CD) パイプライン、モニタリングツールなど、Kubernetesエコシステムとサービスを使用できます。 さらに、統合プラットフォームを使用して、HPCジョブとコンテナ化されたワークロードの両方をスケジュール、送信、および管理できます。 これにより、HPCジョブとKubernetesコンテナ化ワークロードを同じクラスターにデプロイして、ハードウェアリソースを最大限に活用できます。