すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:ACKクラスターでSlurmとKubernetesの同時配置スケジューリングを実装する

最終更新日:Feb 17, 2025

このトピックでは、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の一括スケジューリング

次の図は、共同配置スケジューリングソリューションの動作を示しています。

yuque_diagram (2)

キーコンポーネント

説明

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を使用して同じバッチの物理サーバー上のポッドをスケジュールすることができます。

  1. ACK コンソールにログインします。 作成したクラスターの名前をクリックします。 クラスターの詳細ページで、コールアウトを順番にクリックしてack-slurm-operatorをインストールします。

    [アプリケーション名] および [名前空間] パラメーターはオプションです。 [次へ] (コールアウト ④) をクリックします。 [確認] メッセージで、[はい] をクリックします。 この場合、デフォルトのアプリケーションack-slurm-operatorとデフォルトの名前空間ack-slurm-operatorが使用されます。

    image

  2. チャートバージョンの最新バージョンを選択します。 enableCopilot (callout ) をtrueに、watchNamespace (callout ) をdefaultに設定します。 ビジネス要件に基づいて、watchNamespaceをカスタム名前空間に設定できます。 次に、[OK] をクリックしてack-slurm-operatorをインストールします。image

  3. オプション: ack-slurm-operatorを更新します。

    ACK コンソールにログインします。 [クラスター情報] ページで、[アプリケーション]> [ヘルム] を選択します。 [アプリケーション] ページで、[ack-slurm-operator] を見つけ、[更新] をクリックします。image

1.2 ack-slurm-clusterのインストールと構成

Slurmクラスターを迅速にデプロイおよび管理し、クラスターの設定を柔軟に変更するために、Helmを使用してAlibaba Cloudが提供するSlurmClusterartパッケージをインストールできます。 チャートインキュベーターからSlurmクラスターのHelmチャートをダウンロードし、関連するパラメーターを設定します。 次に、Helmはロールベースのアクセス制御 (RBAC) リソース、ConfigMaps、Secrets、およびSlurmクラスターを作成します。

Helmチャートの内容とパラメーターの説明

Helmチャートには、次のリソースの設定が含まれています。

リソースタイプ

リソース名

機能と特徴

ConfigMap

{{ .Values.slurmConfigs.configMapName }}

とき。Values.slurmConfigs.createConfigsByConfigMapパラメーターをTrueに設定すると、ConfigMapが作成され、ユーザー定義のSlurm設定の保存に使用されます。 ConfigMapは、で指定されたパスにマウントされます。Values. slurmConfiggs. slurmConfigPathInPodパラメーター。 指定されたパスもにレンダリングされます。SlurmクラスターのSpec.SlurmConfPathパラメーターとポッドの起動コマンド。 ポッドを起動すると、ConfigMapが /etc/slurm /パスにコピーされ、ConfigMapへのアクセスが制限されます。

ServiceAccount

{{ .Release.Namespace }}/{{ .Values.clusterName }}

このリソースにより、slurmctldポッドはSlurmクラスターの設定を変更できます。 Slurmクラスターはこのリソースを使用して、クラウドノードの自動スケーリングを有効にできます。

ロール

{{ .Release.Namespace }}/{{ .Values.clusterName }}

このリソースにより、slurmctldポッドはSlurmクラスターの設定を変更できます。 Slurmクラスターはこのリソースを使用して、クラウドノードの自動スケーリングを有効にできます。

RoleBinding

{{ .Release.Namespace }}/{{ .Values.clusterName }}

このリソースにより、slurmctldポッドはSlurmクラスターの設定を変更できます。 Slurmクラスターはこのリソースを使用して、クラウドノードの自動スケーリングを有効にできます。

ロール

{{ .Values.slurmOperatorNamespace }}/{{ .Values.clusterName }}

このリソースにより、slurmctldポッドはSlurmOperator名前空間のSecretsを変更できます。 SlurmとKubernetesが同じバッチの物理サーバーにデプロイされている場合、Slurmクラスターはこのリソースを使用してトークンを更新できます。

RoleBinding

{{ .Values.slurmOperatorNamespace }}/{{ .Values.clusterName }}

このリソースにより、slurmctldポッドはSlurmOperator名前空間のSecretsを変更できます。 SlurmとKubernetesが同じバッチの物理サーバーにデプロイされている場合、Slurmクラスターはこのリソースを使用してトークンを更新できます。

シークレット

{{ .Values.mungeConfigs.secretName }}

このリソースは、相互に通信するときの認証のためにSlurmコンポーネントによって使用されます。 とき。Values.mungeConfigs.createConfigsBySecretパラメーターをTrueに設定すると、このリソースは自動的に作成されます。 このリソースには、次のコンテンツが含まれます。"munge.key" ={{ .Values.mungeConfigs.content }} 。 とき。Values.mungeConfigs.createConfigsBySecretパラメータがTrueに設定され、Values.mungeConfigs.createConfigsBySecretパラメーターは、としてレンダリングされます。Spec.MungeConfPathパラメーターを指定し、ポッド内のリソースのマウントパスとしてレンダリングします。 ポッドの起動コマンドは、マウントパスに基づいて /etc/munge/munge.keyを初期化します。

SlurmCluster

カスタマイズ可能

レンダリングされたSlurmクラスター。

次の表に、関連するパラメーターを示します。

パラメーター

説明

clusterName

非該当

クラスター名です。 クラスター名は、シークレットとロールの生成に使用されます。 値は、他のSlurm設定ファイルで指定されたクラスター名と同じである必要があります。

headNodeConfig

非該当

This parameter is required. このパラメータは、slurmctldポッドの設定を指定します。

workerNodesConfig

非該当

このパラメーターには、slurmdポッドの設定を指定します。

workerNodesConfig.de leteSelfBeforeSuspend

true

値をtrueに設定すると、preStopフックがワーカーポッドに自動的に追加されます。 preStopフックは、ノードが削除される前に自動ノードのドレインをトリガーし、ノードをスケジュール不可としてマークします。

slurmdbdConfigs

非該当

このパラメーターには、slurmdbdポッドの設定を指定します。 このパラメーターを空のままにすると、slurmdbdを実行するポッドは作成されません。

slurmrestdConfigs

非該当

このパラメーターには、slurmrestdポッドの設定を指定します。 このパラメーターを空のままにすると、slurmrestdを実行するポッドは作成されません。

headNodeConfig.hostNetwork

slurmdbdConfigs.hostNetwork

slurmrestdConfigs.hostNetwork

workerNodesConfig.workerGroups[].hostNetwork

false

slurmctldポッドのhostNetworkパラメーターとしてレンダリングされます。

headNodeConfig.setHostnameAsFQDN

slurmdbdConfigs.setHostnameAsFQDN

slurmrestdConfigs.setHostnameAsFQDN

workerNodesConfig.workerGroups[].setHostnameAsFQDN

false

slurmctldポッドのsetHostnameAsFQDNパラメーターとしてレンダリングされます。

headNodeConfig.nodeSelector

slurmdbdConfigs.nodeSelector

slurmrestdConfigs.nodeSelector

workerNodesConfig.workerGroups[].nodeSelector

nodeSelector:
  example: example

slurmctldポッドのnodeSelectorパラメーターとしてレンダリングされます。

headNodeConfig.tolerations

slurmdbdConfigs.tolerations

slurmrestdConfigs.tolerations

workerNodesConfig.workerGroups[].tolerations

tolerations:
- key:
  value:
  operator:

slurmctldポッドの寛容としてレンダリングされます。

headNodeConfig.affinity

slurmdbdConfigs.affinity

slurmrestdConfigs.affinity

workerNodesConfig.workerGroups[].affinity

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.kubernetes.io/zone
          operator: In
          values:
          - zone-a
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 1
      preference:
        matchExpressions:
        - key: another-node-label-key
          operator: In
          values:
          - another-node-label-value

slurmctldポッドのアフィニティルールとしてレンダリングされます。

headNodeConfig.resources

slurmdbdConfigs. リソース

slurmrestdConfigs.resources

workerNodesConfig.workerGroups[].resources

resources:
  requests:
    cpu: 1
  limits:
    cpu: 1

slurmctldポッドのメインコンテナのリソースとしてレンダリングされます。 ワーカーポッドのプライマリコンテナのリソース制限は、Slurmノードのリソース制限として表示されます。

headNodeConfig.image

slurmdbdConfigs.image

slurmrestdConfigs.image

workerNodesConfig.workerGroups[].image

「registry-cn-hangzhou.ack.aliyuncs.com/acs/slurm:23.06-1.6-aliyun-49259f59」

slurmctldイメージとしてレンダリングされます。 ai-models-on-ack/framework/slurm/building-slurm-image at main・AliyunContainerService/ai-models-on-ack (github.com) からカスタムイメージをダウンロードすることもできます。

headNodeConfig.imagePullSecrets

slurmdbdConfigs.imagePullSecrets

slurmrestdConfigs.imagePullSecrets

workerNodesConfig.workerGroups[].imagePullSecrets

imagePullSecrets:
- name: example

slurmctldイメージをプルするために使用されるシークレットとしてレンダリングされます。

headNodeConfig.podSecurityContext

slurmdbdConfigs.podSecurityContext

slurmrestdConfigs.podSecurityContext

workerNodesConfig.workerGroups[].podSecurityContext

podSecurityContext:
  runAsUser: 1000
  runAsGroup: 3000
  fsGroup: 2000
  supplementalGroups: [4000]

slurmctldのセキュリティコンテキストとしてレンダリングされます。

headNodeConfig.securityContext

slurmdbdConfigs.securityContext

slurmrestdConfigs.securityContext

workerNodesConfig.workerGroups[].securityContext

securityContext:
  allowPrivilegeEscalation: false

slurmctldポッドのプライマリコンテナーのセキュリティコンテキストとしてレンダリングされます。

headNodeConfig.volumeMounts

slurmdbdConfigs.volumeMounts

slurmrestdConfigs.volumeMounts

workerNodesConfig.workerGroups[].volumeMounts

非該当

slurmctldポッドのプライマリコンテナのボリュームマウント構成としてレンダリングされます。

headNodeConfig.volumes

slurmdbdConfigs.volumes

slurmrestdConfigs.volumes

workerNodesConfig.workerGroups[].volumes

非該当

slurmctldポッドにマウントされたボリュームとしてレンダリング

slurmConfigs.slurmConfigPathInPod

非該当

ポッド内のSlurm構成ファイルのマウントパス。 Slurm構成ファイルがボリュームとしてポッドにマウントされている場合は、slurm.confファイルがマウントされているパスに値を設定する必要があります。 ポッドの起動コマンドは、マウントパス内のファイルを /etc/slurm /パスにコピーし、ファイルへのアクセスを制限します。

slurmConfigs.createConfigsByConfigMap

true

Slurm設定を保存するConfigMapを自動的に作成するかどうかを指定します。

slurmConfigs.configMapName

非該当

Slurm設定を格納するConfigMapの名前。

slurmConfigs.filesInConfigMap

非該当

Slurm設定を格納するために自動的に作成されるConfigMapのコンテンツ。

mungeConfigs.mungeConfigPathInPod

非該当

ポッド内のMUNGE構成ファイルのマウントパス。 MUNGE構成ファイルがボリュームとしてポッドにマウントされている場合は、munge.keyファイルがマウントされているパスに値を設定する必要があります。 ポッドの起動コマンドは、マウントパス内のファイルを /etc/munge /パスにコピーし、ファイルへのアクセスを制限します。

mungeConfigs.createConfigsBySecret

非該当

MUNGE構成を格納するシークレットを自動的に作成するかどうかを指定します。

mungeConfigs.secretName

非該当

MUNGE設定を格納するシークレットの名前。

mungeConfigs.content

非該当

MUNGE設定を格納するために自動的に作成されるシークレットのコンテンツ。

slurmConfigs.filesInConfigMapパラメーターの詳細については、「Slurmシステム構成ツール (schedmd.com) 」をご参照ください。

重要

ポッドの作成後にslurmConfigs.filesInConfigMapパラメーターを変更する場合は、変更を有効にするためにポッドを再作成する必要があります。 この場合、ポッドを再作成する前に、パラメーターが必要に応じて変更されているかどうかを確認することをお勧めします。

次の操作を実行します。

  1. 次のコマンドを実行して、Alibaba Cloudが提供するチャートリポジトリをHelmクライアントに追加します。リポジトリの追加後、Alibaba Cloudが提供するHelmチャート (ack-slurm-clusterコンポーネントのチャートなど) にアクセスできます。

    helm repo add aliyun https://aliacs-app-catalog.oss-cn-hangzhou.aliyuncs.com/charts-incubator/
  2. 次のコマンドを実行して、ack-slurm-clusterチャートをプルして解凍します。 この操作により、現在のディレクトリにack-slurm-clusterという名前のサブディレクトリが作成されます。 ack-slurm-clusterディレクトリには、チャートに含まれるすべてのファイルとテンプレートが含まれます。

    helm pull aliyun/ack-slurm-cluster --untar=true
  3. 次のコマンドを実行して、values.yamlファイルのグラフパラメーターを変更します。

    values.yamlファイルには、グラフのデフォルト設定が含まれています。 ビジネス要件に基づいて、ファイル内のパラメーター設定を変更できます。 設定には、Slurm設定、リソース要求と制限、およびストレージ設定が含まれます。

    cd ack-slurm-cluster
    vi values.yaml

    JSON Webトークン (JWT) を生成し、JWTをクラスターに送信する手順を示します

    JWT認証プラグインのキーを生成し、コマンドを実行してクラスターにキーをインポートします。 詳細については、「JWT認証プラグイン」をご参照ください。

    1. JWTに署名して認証するためのJSON Webキー (JWK) を取得します。

      JWT認証プラグインは、JWK (RFC7517) を使用して、JWTに署名し、認証する。 JWT認証プラグインを設定するには、まず有効なJWKを生成する必要があります。 手動でJWKを生成するか、mkjwk.orgなどのオンラインのJWKジェネレータを使用してJWKを生成できます。 次のサンプルコードは、JWKの内容を示しています。 秘密鍵は、JWTに署名するために使用される。 JWT認証プラグインの公開鍵は、JWTの認証に使用されます。 サンプルJWKコンテンツ:

      {
        "kty": "RSA",
        "e": "AQAB",
        "kid": "O9fpdhrViq2zaaaBEWZITz",
        "use": "sig",
        "alg": "RS256",
        "n": "qSVxcknOm0uCq5vGsOmaorPDzHUubBmZZ4UXj-9do7w9X1uKFXAnqfto4TepSNuYU2bA_-tzSLAGBsR-BqvT6w9SjxakeiyQpVmexxnDw5WZwpWenUAcYrfSPEoNU-0hAQwFYgqZwJQMN8ptxkd0170PFauwACOx4Hfr-9FPGy8NCoIO4MfLXzJ3mJ7xqgIZp3NIOGXz-GIAbCf13ii7kSStpYqN3L_zzpvXUAos1FJ9IPXRV84tIZpFVh2lmRh0h8ImK-vI42dwlD_hOIzayL1Xno2R0T-d5AwTSdnep7g-Fwu8-sj4cCRWq3bd61Zs2QOJ8iustH0vSRMYdP5oYQ"
      }        

      上記のJWKはJSON形式です。 JWT認証プラグインをYAML形式で設定する場合は、JWKをYAML形式で使用する必要があります。*

      • JWT認証プラグインの場合、公開鍵を設定するだけで済みます。 秘密鍵の資格情報を保持します。 次の表に、JWT認証プラグインでサポートされている署名署名アルゴリズムを示します。

      署名アルゴリズム

      サポートされているalg設定

      SHA-2とRSASSA-PKCS1-V1_5

      RS256、RS384、RS512

      SHA-2付き楕円曲線 (ECDSA)

      ES256、ES384、ES512

      SHA-2を使用したHMAC

      HS256、HS384、HS512

      重要

      HS256、HS384、またはHS512タイプのキーを設定すると、キー値がBase64URL-encodedになります。 署名が無効な場合は、キーがトークンの生成に使用されたキーと同じ形式であるかどうかを確認します。

    2. JWKをクラスターにインポートします。

      kubectl create configmap jwt --from-literal=jwt_hs256.key={{ .jwtkey }}

    データベースアドレスを指定して汎用リソース (GRE) を設定する手順を表示

    slurmrestdとslurmdbdを有効にします。 変更します。Modify the. Values.slurmConfigs.filesInConfigMapvalues.yamlファイルのパラメーターを使用して、データベースアドレスを指定し、GREを設定します。

    slurmConfigs:
      ...
      filesInConfigMap:
        gres.conf: |
          # Configure Copilot to update the information about the resources allocated from Kubernetes to Slurm.
          Name=k8scpu Flags=CountOnly
          Name=k8smemory Flags=CountOnly
        slurmdbd.conf: |
          # The path of the logs. The path must be the same as the path specified in the following authentication configurations.
          LogFile=/var/log/slurmdbd.log
          # When you use slurmrestd, you must specify JWT authentication.
          AuthAltTypes=auth/jwt
          # slurmdbd needs to use the key in the following path to authenticate the token. Use the following configurations to mount the key to the pod.
          AuthAltParameters=jwt_key=/var/jwt/jwt_hs256.key
          AuthType=auth/munge
          SlurmUser=slurm
          # Specify a MySQL database account.
          StoragePass=
          StorageHost=
          StorageType=accounting_storage/mysql
          StorageUser=root
          StoragePort=3306
        slurm.conf: |
          # Specify the following extended resource attributes for nodes in the Slurm cluster: k8scpu and k8smemory. This prevents the nodes from entering the DOWN state.
          NodeFeaturesPlugins=node_features/k8s_resources
          # Enable Slurm to automatically add k8scpu and k8smemory when you use Slurm to submit jobs.
          JobSubmitPlugins=k8s_resource_completion
          AccountingStorageHost=slurm-test-slurmdbd
          # When you use slurmrestd, you must specify JWT authentication.
          AuthAltTypes=auth/jwt
          # slurmctld needs to use the key in the following path to authenticate the token. Use the following configurations to mount the key to the pod.
          AuthAltParameters=jwt_key=/var/jwt/jwt_hs256.key
          # Configure Copilot to update the information about the resources allocated from Kubernetes to Slurm.
          GresTypes=k8scpu,k8smemory
          # Specify ${slurmClusterName}-slurmdbd. slurmOperator automatically deploys slurmdbd.
          AccuntingStorageHost=
          AccountingStoragePort=6819
          AccountingStorageType=accounting_storage/slurmdbd
          # Information used by the JobComp plug-in to access the MySQL database.
          JobCompHost=
          JobCompLoc=/var/log/slurm/slurm_jobcomp.log
          JobCompPass=
          JobCompPort=3306
          JobCompType=jobcomp/mysql
          JobCompUser=root
          # Configurations that ensure high availability.
          SlurmctldHost=

    slurmrestdポッドとslurmdbdポッドを設定する手順を示します

    slurmrestdポッドとslurmdbdポッドを設定します。

    ...
    headNodeConfig:
      image: "registry-cn-hangzhou.ack.aliyuncs.com/acs/slurm:23.06-1.6-aliyun-49259f59"
      # Mount the generated JWT key to Slurm. The mount path must be the same as the path specified in the preceding section.
      volumes: 
      - configMap:
          defaultMode: 444
          name: jwt
        name: config-jwt
      volumeMounts: 
      - mountPath: /var/jwt
        name: config-jwt
    slurmdbdConfigs:
      nodeSelector: {}
      tolerations: []
      affinity: {}
      resources: {}
      image: "registry-cn-hangzhou.ack.aliyuncs.com/acs/slurm:23.06-1.6-aliyun-49259f59"
      imagePullSecrets: []
      # if .slurmConfigs.createConfigsByConfigMap is true, slurmConfPath and volume and volumeMounts will be auto set as:
      #  volumeMounts:
      #    - name: config-{{ .Values.slurmConfigs.configMapName }}
      #      mountPath: {{ .Values.slurmConfigs.slurmConfigPathInPod }}
      # volumes:
      #   - name: config-{{ .Values.slurmConfigs.configMapName }}
      #     configMap:
      #       name: {{ .Values.slurmConfigs.configMapName }}
      # also for mungeConfigs.createConfigsBySecret
      # Mount the generated JWT key to Slurm. The mount path must be the same as the path specified in the preceding section.
    
      volumes: 
      - configMap:
          defaultMode: 444
          name: jwt
        name: config-jwt
      volumeMounts: 
      - mountPath: /var/jwt
        name: config-jwt
    
    slurmrestdConfigs:
      nodeSelector: {}
      tolerations: []
      affinity: {}
      resources: {}
      image: "registry-cn-hangzhou.ack.aliyuncs.com/acs/slurm:23.06-1.6-aliyun-49259f59"
      imagePullSecrets: []
      # if .slurmConfigs.createConfigsByConfigMap is true, slurmConfPath and volume and volumeMounts will be auto set as:
      #  volumeMounts:
      #    - name: config-{{ .Values.slurmConfigs.configMapName }}
      #      mountPath: {{ .Values.slurmConfigs.slurmConfigPathInPod }}
      # volumes:
      #   - name: config-{{ .Values.slurmConfigs.configMapName }}
      #     configMap:
      #       name: {{ .Values.slurmConfigs.configMapName }}
      # also for mungeConfigs.createConfigsBySecret
      # Mount the generated JWT key to Slurm. The mount path must be the same as the path specified in the preceding section.
      volumes: 
      - configMap:
          defaultMode: 444
          name: jwt
        name: config-jwt
      volumeMounts: 
      - mountPath: /var/jwt
        name: config-jwt
  4. 次のコマンドを実行して、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.
  5. チャートをインストールした後、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.0      
  6. slurmrestdとslurmdbdが期待どおりに実行されるかどうかを確認します。

    1. 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
    2. 次のコマンドを実行してログを照会します。 ログを表示して、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に依存関係をインストールする方法を表示します。

Slurmイメージを作成する手順を表示する

Slurmイメージを準備します。 イメージ (registry-cn-beijing.ack.aliyuncs.com/acs/slurm:23.06-1.6-aliyun-49259f59) は、このトピックで使用されるすべてのソフトウェアとともにプリインストールされています。 次のDockerfileを使用してSlurmイメージを作成できます。 カスタム依存関係を追加することもできます。 次のプラグインがイメージにインストールされているかどうかを確認します。 Alibaba Cloudのオープンソースコードリポジトリから、以下のプラグインのパッケージと以下のDockerfileのソースコードを取得できます。

  • kubectl、node_features、およびk8s_resourcesが必要です。

  • job_submitまたはk8s_resource_completionをインストールする必要があります。 job_submitまたはk8s_resource_completionはGREの自動完了を有効にするために使用されます。

    デフォルトでは、slurmdが _slurm_rpc_node_registrationリクエストを送信すると、slurmctldはノードでのGREの使用状況をチェックします。 GREの使用が変更された場合、ノードは無効と見なされ、INVALとしてマークされます。 INVAL状態のノードにジョブをスケジュールすることはできません。 その結果、クラスターが期待どおりに実行されない場合があります。 この問題を解決するには、クラスターからノードを削除し、ノードをクラスターに再度追加する必要があります。 ノードのActivateFeature属性が更新されると、k8s_resourcesプラグインはk8scpuおよびk8smmemory属性を0に設定し、k8scpuおよびk8smmemoryのnode_featureフラグをtrueに設定します。 これにより、ノードでのGREチェックがスキップされ、クラスター内のリソースが期待どおりに使用できるようになります。

サンプルDockerfileのコンテンツを表示

FROM nvidia/cuda:11.4.3-cudnn8-devel-ubuntu20.04 as exporterBuilder
ENV TZ=Asia/Shanghai
ENV DEBIAN_FRONTEND=noninteractive
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update && apt install -y golang git munge libhttp-parser-dev libjson-c-dev libyaml-dev libjwt-dev libgtk2.0-dev libreadline-dev libpmix-dev libmysqlclient-dev libhwloc-dev openmpi-bin openmpi-common libopenmpi-dev rpm libmunge-dev libmunge2 libpam-dev perl python3 systemd lua5.3 libnvidia-ml-dev libhdf5-dev
# Download the source code before building the image
COPY ./slurm-23.02.7.tar.bz2 ./slurm-23.02.7.tar.bz2
RUN tar -xaf slurm-23.02.7.tar.bz2
COPY ../node_features/k8s_resources ./slurm-23.02.7/src/plugins/node_features/k8s_resources
RUN sed -i '/"src\/plugins\/node_features\/Makefile") CONFIG_FILES="\$CONFIG_FILES src\/plugins\/node_features\/Makefile" ;;/ a "    src/plugins/node_features/k8s_resources/Makefile") CONFIG_FILES="\$CONFIG_FILES src/plugins/node_features/k8s_resources/Makefile" ;;' ./slurm-23.02.7/configure
RUN awk '/^ac_config_files="\$ac_config_files/ && !found { print; print "ac_config_files=\"$ac_config_files src/plugins/node_features/k8s_resources/Makefile\""; found=1; next } { print }' ./slurm-23.02.7/configure > ./slurm-23.02.7/configure.new && mv ./slurm-23.02.7/configure.new ./slurm-23.02.7/configure && chmod +x ./slurm-23.02.7/configure
RUN cat ./slurm-23.02.7/configure
RUN sed -i '/^SUBDIRS =/ s/$/ k8s_resources/' ./slurm-23.02.7/src/plugins/node_features/Makefile & \
sed -i '/^SUBDIRS =/ s/$/ k8s_resources/' ./slurm-23.02.7/src/plugins/node_features/Makefile.in & \
sed -i '/^SUBDIRS =/ s/$/ k8s_resources/' ./slurm-23.02.7/src/plugins/node_features/Makefile.am
RUN cd slurm-23.02.7 && ./configure --prefix=/usr/ --sysconfdir=/etc/slurm && make 

FROM nvidia/cuda:11.4.3-cudnn8-runtime-ubuntu20.04
ENV TZ=Asia/Shanghai
ENV DEBIAN_FRONTEND=noninteractive
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN apt update
RUN apt install -y munge libhttp-parser-dev libjson-c-dev libyaml-dev libjwt-dev libgtk2.0-dev libreadline-dev libpmix-dev libmysqlclient-dev libhwloc-dev openmpi-bin openmpi-common libopenmpi-dev rpm libmunge-dev libmunge2 libpam-dev perl python3 systemd lua5.3 inotify-tools openssh-server pip libnvidia-ml-dev libhdf5-dev
COPY --from=0 /slurm-23.02.7 /slurm-23.02.7
RUN cd slurm-23.02.7 && make install && cd ../ && rm -rf /slurm-23.02.7
RUN apt remove libnvidia-ml-dev libnvidia-compute-545 -y; apt autoremove -y ; ln -s /usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1 /usr/lib/x86_64-linux-gnu/libnvidia-ml.so
COPY ./sh ./
RUN mkdir /etc/slurm
RUN chmod +x create-users.sh munge-inisitalization.sh slurm-initialization.sh slurm-suspend.sh slurm-resume.sh slurmd slurmctld slurmdbd slurmrestd
RUN touch /var/log/slurm-resume.log /var/log/slurm-suspend.log ; chmod 777 /var/log/slurm-resume.log /var/log/slurm-suspend.log
RUN mv slurmd /etc/init.d/slurmd && mv slurmdbd /etc/init.d/slurmdbd && mv slurmctld /etc/init.d/slurmctld
RUN ./create-users.sh && ./munge-inisitalization.sh && ./slurm-initialization.sh
RUN rm ./create-users.sh ./munge-inisitalization.sh ./slurm-initialization.sh
ENV NVIDIA_VISIBLE_DEVICES=
RUN apt-get update && apt-get upgrade -y && rm -rf /var/cache/apt/

2. 共同配置されたスケジューリングのテスト

2.1 共同配置されたスケジューリングのテスト

  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"}]
  2. 次のコマンドを実行して、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"}]
  3. この場合、別のジョブを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ジョブスクリプトでパラメーターを指定する方法を表示します。

Slurmジョブスクリプトの説明を表示する

Slurmクラスターでジョブを送信するときは、GREの量を計算する必要があります。 次のセクションでは、srunとsbatchを使用してジョブを送信するときに使用できるパラメーターについて説明し、ジョブのGREの量を計算する方法の例を示します。

パラメーター

説明

-- tres-per-task

ジョブの各タスクに必要なTrackable Resources (TREs) 。

-- gres

仕事に必要なGRE。

Slurmジョブのリソースを計算する手順を表示

ジョブに必要なGREの量を計算する場合、次の方法を使用して、ジョブが各ノードから必要とするvCPUの数とメモリの量を計算する必要があります。

  1. 必要なvCPUの総数を計算します。

    Slurmを使用してジョブをスケジュールする場合、効率的なリソース割り当てとジョブスケジューリングを確保するための鍵は、各タスクが各ノードから必要とするvCPUの総数を適切に計算することです。

    計算は次のパラメータに基づいています。

    • ノード: ジョブに必要なノードの数。

    • Tasks per Node: 各ノードで実行されるタスクの数。

    • タスクあたりのCPU数: タスクに必要なvCPUの数。

    上記のパラメーターは、Slurmスクリプトまたはコマンドのオプションで指定できます。

    計算式

    ノードから必要なvCPUの総数=ノードあたりのタスク数 × 各タスクで必要なvCPU数

    以下のパラメータが使用されます。

    • ノード: 2

    • ノードごとのタスク: 4

    • タスクあたりのCPU数: 2

    各ノードから必要なvCPUの総数は8 (4 × 2) です。 この場合、2つのノードが使用されます。 したがって、ジョブが必要とするvCPUの総数は16 (8 × 2) である。

  2. 必要なメモリの総量を計算します。

    Slurmを使用してジョブをスケジュールする場合、適切なメモリ割り当てを確保し、メモリの無駄や不足を防ぐための鍵は、各タスクが各ノードから必要とするメモリの合計量を計算することです。 必要なメモリの総量は、各ノードで実行されるタスクの数と、各タスクで必要なメモリの量によって異なります。

    ノードから必要なメモリの合計量=ノードあたりのタスク数 × 各タスクで必要なvCPU数 × vCPUあたりのメモリ量

  3. ジョブを送信するときにGREの自動完了を有効にします。

    ジョブの送信時に -- gres設定を手動で追加する場合は、各ノードからジョブに必要なvCPU (CPU) の数とメモリ (MEM) の量を手動で計算する必要があります。 ただし、-- gres設定がなくてもジョブを送信できます。

    この場合、job_submitプラグインをインストールして -- gres設定の自動完了を有効にすることができます。 サンプルコードが提供される。 サンプルコードを使用してジョブを送信する場合は、-nまたは -- tasks設定を追加してタスク数を指定する必要があります。 それ以外の場合、ジョブの送信は失敗します。 -- gpusまたは -- gpus-per-socket構成を使用して、ジョブに必要なGPUの数を要求すると、ジョブの送信は失敗します。 GPUを要求するには、-- GPUs-per-task設定を使用する必要があります。

サンプルSlurmジョブスクリプト

#!/bin/bash
#SBATCH --job-name=test_job                   # The job name.
#SBATCH --nodes=2                             # The number of nodes required by the job.
#SBATCH --ntasks-per-node=4                   # The number of tasks to run on each node.
#SBATCH --cpus-per-task=2                     # The number of vCPUs required by each task.
#SBATCH --time=01:00:00                       # The maximum duration of the job.
#SBATCH --output=job_output_%j.txt            # The name of the stdout file.
#SBATCH --error=job_error_%j.txt              # The name of the stderr file.

# User-defined job commands.
srun my_program

コマンドで上記のパラメーターを指定することもできます。

sbatch --nodes=2 --ntasks-per-node=4 --cpus-per-task=2 --time=01:00:00 --job-name=test_job my_job_script.sh

パラメーターの説明:

  • -- nodes (-N ): ジョブに必要なノード数。

  • -- ntasks-per-node (-- tasks-per-node ): 各ノードで実行するタスクの数。

  • -- cpus-per-task: 各タスクに必要なvCPUの数。

  • -- time (-t ): ジョブの最大期間。

  • -- job-name (-J ): ジョブ名。

オプション: 2.2コンテナ化されていないSlurmクラスターで同一場所に配置されたスケジューリングを実装する

SlurmCopilotはSlurm APIを使用してSlurmと対話します。 この相互作用方法は、非コンテナ化Slurmクラスターシナリオにも適用されます。

コンテナ化されていないSlurmクラスターシナリオでは、特定のKubernetesリソースを手動でのみ作成できます。 次のセクションでは、手動で作成する必要があるKubernetesリソースについて説明します。

  1. 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
  2. 各SlurmクラスターのDNSレコードを設定します。

    slurmrestdプロセスへのアクセスを有効にするには、SlurmCopilot設定で、${.metadata.name}.${.metadata.name空間}.svc.cluster.local :${.spec.ports[0].port} をslurmrestdプロセスのIPアドレスにポイントするようにDNSレコードを設定する必要があります。

  3. 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コンテナ化ワークロードを同じクラスターにデプロイして、ハードウェアリソースを最大限に活用できます。