Slurm を利用して自動スケーリング HPC クラスタをデプロイする

1. 概要

Google Cloud Platform で Slurm クラスタを実行するための Google Codelab へようこそ。この Codelab を修了すると、自動スケーリング Slurm クラスタのプロビジョニングとオペレーションのしやすさについて理解を深めることができます。

c16fa310c142ac6f.png

Google Cloud は SchedMD と提携し、Compute Engine で Slurm ワークロード マネージャーを簡単に起動し、追加のリソースが必要なときに既存のクラスタを動的に拡張できる一連のツールをリリースしました。この統合は、Slurm のベスト プラクティスに従って SchedMD の専門家によって構築されました。

Slurm on Google Cloud Platform の統合を使用する予定がある場合や、ご不明な点がある場合は、Google Cloud & Slurm Community Discussion Group への参加をご検討ください。

Slurm について

a739730a41acff0a.png

Google Cloud Platform のスタンドアロン Slurm クラスタの基本的なアーキテクチャ図。

Slurm は、世界中の HPC クラスタで使用されている主要なワークロード マネージャーの 1 つです。Slurm は、小規模および大規模な Linux クラスタ向けのオープンソースのフォールト トレラントでスケーラビリティの高いワークロード管理およびジョブ スケジューリング システムです。Slurm は、オペレーションにカーネルの変更を必要とせず、比較的自己完結型です。クラスタ ワークロード マネージャーとして、Slurm には次の 3 つの主な機能があります。

  1. リソース(コンピューティング ノード)への排他アクセスまたは非排他アクセスをユーザーに一定期間割り当て、ユーザーが作業を実行できるようにします。
  2. 割り当てられたノードのセットで作業(通常は並列ジョブ)を開始、実行、モニタリングするためのフレームワークを提供します。
  3. 保留中の作業のキューを管理することで、リソースの競合を仲裁します。

学習内容

  • Terraform を使用して Slurm クラスタを設定する方法
  • SLURM を使用してジョブを実行する方法
  • クラスタ情報をクエリし、SLURM で実行中のジョブをモニタリングする方法
  • 特定のジョブ パラメータと要件に対応するためにノードを自動スケーリングする方法
  • Slurm のヘルプの入手先

前提条件

  • Google Cloud Platform アカウントと、課金が有効になっているプロジェクト
  • 基本的な Linux の経験

2. セットアップ

セルフペース型の環境設定

プロジェクトを作成

Google アカウント(Gmail または G Suite)をお持ちでない場合は、アカウントを作成する必要があります。Google Cloud Platform コンソール(console.cloud.google.com)にログインし、[リソースの管理] ページを開きます。

359c06e07e6d699f.png

[プロジェクトを作成] をクリックします。

25c23d651abb837b.png

プロジェクト名を入力します。プロジェクト ID(上のスクリーンショットで赤でハイライト表示されている部分)をメモしておきます。プロジェクト ID は、すべての Google Cloud プロジェクトで一意の名前である必要があります。プロジェクト名が一意でない場合、Google Cloud はプロジェクト名に基づいてランダムなプロジェクト ID を生成します。

次に、Google Cloud リソースを使用するために、Developers Console で課金を有効にする必要があります。

この Codelab の操作をすべて行っても、費用は数ドル程度です。ただし、その他のリソースを使いたい場合や、実行したままにしておきたいステップがある場合は、追加コストがかかる可能性があります(このドキュメントの最後にある「まとめ」セクションを参照)。Google Cloud Platform 料金計算ツールはこちらでご利用いただけます。

Google Cloud Platform の新規ユーザーは、$300 の無料トライアルをご利用いただけます。

Google Cloud Shell

Google Cloud はノートパソコンからリモートで操作できますが、この Codelab では、Google Cloud Shell(Cloud 上で動作するコマンドライン環境)を使用します。

Google Cloud Shell を起動する

GCP Console で右上のツールバーにある Cloud Shell アイコンをクリックします。

dbad104cef962719.png

[Cloud Shell の起動] をクリックします。

4e50db320508ac88.png

プロビジョニングと環境への接続にはそれほど時間はかかりません。

20b0aa80492144d.png

この仮想マシンには、必要な開発ツールがすべて用意されています。永続的なホーム ディレクトリが 5 GB 用意されており、Google Cloud で稼働します。そのため、ネットワークのパフォーマンスが大幅に向上し、認証が簡素化されています。このラボでの作業のほとんどは、ウェブブラウザまたは Google Chromebook から実行できます。

Cloud Shell に接続すると、すでに認証は完了しており、プロジェクトに各自の PROJECT_ID が設定されていることがわかります。

$ gcloud auth list

コマンド出力:

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
$ gcloud config list project

コマンド出力:

[core]
project = <PROJECT_ID>

プロジェクト ID が正しく設定されていない場合は、次のコマンドを使用して設定できます。

$ gcloud config set project <PROJECT_ID>

コマンド出力:

Updated property [core/project].

3. Slurm Terraform 構成を準備して確認する

Slurm Terraform 構成をダウンロードする

Cloud Shell セッションで次のコマンドを実行して、Slurm for Google Cloud Platform Terraform ファイルを含む Git リポジトリのクローンを作成(ダウンロード)します。

git clone https://github.com/SchedMD/slurm-gcp.git

次のコマンドを実行して、Slurm デプロイ構成ディレクトリに切り替えます。

cd slurm-gcp

Slurm Terraform tfvars を構成する

basic.tfvars.example ファイルには、デプロイするネットワーク、インスタンス、ストレージなど、デプロイの構成が詳しく記載されています。新しいファイル(tfvars ファイル)にコピーし、必要に応じて編集します。

cd tf/example/basic
cp basic.tfvars.example basic.tfvars

Cloud Shell セッションで、tfvars ファイル basic.tfvars開きます。ファイルの内容を表示するには、お好みのコマンドライン エディタ(vi、nano、emacs など)を使用するか、Cloud Console コードエディタを使用します。

214f43bba6c917aa.png

tfvars ファイルの内容を確認します。

cluster_name = "g1"
project      = "<project>"
zone         = "us-west1-b"

# network_name            = "<existing network name>"
# subnetwork_name         = "<existing subnetwork name>"
# shared_vpc_host_project = "<vpc host project>"

# disable_controller_public_ips = true
# disable_login_public_ips      = true
# disable_compute_public_ips    = true

# suspend_time  = 300

controller_machine_type = "n1-standard-2"
controller_image        = "projects/schedmd-slurm-public/global/images/family/schedmd-slurm-20-11-4-hpc-centos-7"
controller_disk_type    = "pd-standard"
controller_disk_size_gb = 50
# controller_labels = {
#   key1 = "val1"
#   key2 = "val2"
# }
# controller_service_account = "default"
# controller_scopes          = ["https://www.googleapis.com/auth/cloud-platform"]
# cloudsql = {
#   server_ip = "<cloudsql ip>"
#   user      = "slurm"
#   password  = "verysecure"
#   db_name   = "slurm_accounting"
# }
# controller_secondary_disk      = false
# controller_secondary_disk_size = 100
# controller_secondary_disk_type = "pd-ssd"
#
# When specifying an instance template, specified controller fields will
# override the template properites.
# controller_instance_template = null

login_machine_type = "n1-standard-2"
login_image        = "projects/schedmd-slurm-public/global/images/family/schedmd-slurm-20-11-4-hpc-centos-7"
login_disk_type    = "pd-standard"
login_disk_size_gb = 20
# login_labels = {
#   key1 = "val1"
#   key2 = "val2"
# }
# login_node_count = 1
# login_node_service_account = "default"
# login_node_scopes          = [
#   "https://www.googleapis.com/auth/monitoring.write",
#   "https://www.googleapis.com/auth/logging.write"
# ]
#
# When specifying an instance template, specified login fields will
# override the template properties.
# login_instance_template = null

# Optional network storage fields
# network_storage is mounted on all instances
# login_network_storage is mounted on controller and login instances
# network_storage = [{
#   server_ip     = "<storage host>"
#   remote_mount  = "/home"
#   local_mount   = "/home"
#   fs_type       = "nfs"
#   mount_options = null
# }]
#
# login_network_storage = [{
#   server_ip     = "<storage host>"
#   remote_mount  = "/net_storage"
#   local_mount   = "/shared"
#   fs_type       = "nfs"
#   mount_options = null
# }]

# compute_node_service_account = "default"
# compute_node_scopes          = [
#   "https://www.googleapis.com/auth/monitoring.write",
#   "https://www.googleapis.com/auth/logging.write"
# ]

partitions = [
  { name                 = "debug"
    machine_type         = "n1-standard-2"
    static_node_count    = 0
    max_node_count       = 10
    zone                 = "us-west1-b"
    image                ="projects/schedmd-slurm-public/global/images/family/schedmd-slurm-20-11-4-hpc-centos-7"
    image_hyperthreads   = false
    compute_disk_type    = "pd-standard"
    compute_disk_size_gb = 20
    compute_labels       = {}
    cpu_platform         = null
    gpu_count            = 0
    gpu_type             = null
    network_storage      = []
    preemptible_bursting = false
    vpc_subnet           = null
    exclusive            = false
    enable_placement     = false
    regional_capacity    = false
    regional_policy      = {}
    instance_template    = null
  },
  #  { name                 = "partition2"
  #    machine_type         = "n1-standard-16"
  #    static_node_count    = 0
  #    max_node_count       = 20
  #    zone                 = "us-west1-b"
  #    image                = "projects/schedmd-slurm-public/global/images/family/schedmd-slurm-20-11-4-hpc-centos-7"
  #    image_hyperthreads   = false
  #
  #    compute_disk_type    = "pd-ssd"
  #    compute_disk_size_gb = 20
  #    compute_labels       = {
  #      key1 = "val1"
  #      key2 = "val2"
  #    }
  #    cpu_platform         = "Intel Skylake"
  #    gpu_count            = 8
  #    gpu_type             = "nvidia-tesla-v100"
  #    network_storage      = [{
  #      server_ip     = "none"
  #      remote_mount  = "<gcs bucket name>"
  #      local_mount   = "/data"
  #      fs_type       = "gcsfuse"
  #      mount_options = "file_mode=664,dir_mode=775,allow_other"
  #    }]
  #    preemptible_bursting = true
  #    vpc_subnet           = null
  #    exclusive            = false
  #    enable_placement     = false
  #
  #    ### NOTE ####
  #    # regional_capacity is under development. You may see slowness in
  #    # deleting lots of instances.
  #    #
  #    # With regional_capacity : True, the region can be specified in the zone.
  #    # Otherwise the region will be inferred from the zone.
  #    zone = "us-west1"
  #    regional_capacity    = True
  #    # Optional
  #    regional_policy      = {
  #        locations = {
  #            "zones/us-west1-a" = {
  #                preference = "DENY"
  #            }
  #        }
  #    }
  #
  #    When specifying an instance template, specified compute fields will
  #    override the template properties.
  #    instance_template = "my-template"
]

この tfvars ファイルには、構成するフィールドがいくつかあります。構成する必要があるフィールドは プロジェクトのみです。例の他の構成はそのまま使用できますが、状況に応じて必要に応じて変更してください。構成オプションの詳細については、こちらをご覧ください。

  • cluster_name: Slurm クラスタの名前
  • project: リソースがデプロイされる Google Cloud プロジェクト ID
  • zone: このクラスタのコントローラ インスタンスとログイン インスタンスを含む Google Cloud ゾーン - 詳細
  • network_name: Slurm クラスタのデプロイ先となる Virtual Private Cloud ネットワーク
  • subnetwork_name: Slurm クラスタのデプロイ先となる Virtual Private Cloud サブネットワーク
  • shared_vpc_host_project: Slurm クラスタのデプロイ先となる共有 VPC ネットワーク
  • disable_controller_public_ips: Slurm コントローラに外部 IP を割り当てるかどうか。
  • disable_login_public_ips: Slurm ログインノードに外部 IP を割り当てますか?
  • disable_compute_login_ips: Slurm ログインノードに外部 IP を割り当てるかどうか。
  • suspend_time: ノードがアイドル状態になってからノードを一時停止するまでの待機時間
  • controller_machine_type: コントローラ ノードのインスタンス タイプ
  • controller_image: Slurm コントローラ インスタンスの作成に使用される GCP イメージ
  • controller_disk_type: コントローラ インスタンスのブートディスクのタイプ
  • controller_disk_size_gb: コントローラ インスタンスのブートディスクのサイズ
  • controller_labels: コントローラ インスタンスに付加するラベル
  • controller_service_account: コントローラ インスタンスで使用するサービス アカウント
  • controller_scopes: コントローラ インスタンスのアクセス スコープ
  • cloudsql: Google CloudSQL サーバー。コントローラ インスタンスでデータベースをホストする代わりに、Slurm データベースとして使用します。
  • server_ip: CloudSQL サーバーの IP
  • user: CloudSQL ユーザー名
  • password: CloudSQL パスワード
  • db_name: CloudSQL データベース名
  • controller_secondary_disk: NFS サーバー ストレージ用のセカンダリ ディスクを追加しますか?
  • controller_secondary_disk_type: コントローラのセカンダリ ディスクのタイプ
  • controller_secondary_disk_size_gb: コントローラ セカンダリ ディスクのサイズ
  • controller_instance_template: コントローラ インスタンスに使用する GCP インスタンス テンプレート。指定された計算フィールドは、テンプレートのプロパティよりも優先されます。たとえば、controller_image が指定されている場合、インスタンス テンプレートのイメージが上書きされます。
  • login_machine_type: ログイン(SSH アクセス可能)ノードのインスタンス タイプ
  • login_image: Slurm ログイン インスタンスの作成に使用される GCP イメージ
  • login_disk_type: ログイン インスタンスのブートディスクのタイプ
  • login_disk_size_gb: ログイン インスタンスのブートディスクのサイズ
  • login_labels: ログイン インスタンスにアタッチするラベル
  • login_node_count: 作成するログインノードの数
  • login_node_service_account: ログイン インスタンスで使用するサービス アカウント
  • login_node_scopes: ログイン インスタンスのアクセス スコープ
  • login_instance_template: ログイン インスタンスに使用する GCP インスタンス テンプレート。指定された計算フィールドは、テンプレートのプロパティよりも優先されます。たとえば、login_image が指定されている場合、インスタンス テンプレートのイメージが上書きされます。
  • network_storage: すべてのノードにマウントするネットワーク ストレージ。フィールドは fstab に直接追加されます。追加のマウントに対して繰り返すことができます。
  • server_ip: ストレージ サーバーの IP
  • remote_mount: ストレージ マウント名(ファイルシステム名)
  • local_mount: ローカル マウント ディレクトリ
  • fs_type: ファイル システムのタイプ(NFS、CIFS、Lustre、GCSFuse は自動的にインストールされます)
  • mount_options: マウント オプション(defaults、_netdev など)
  • login_network_storage: ログインノードとコントローラ ノードにマウントするネットワーク ストレージ。NFS、CIFS、Lustre、GCSFuse は自動的にインストールされます。追加のマウントに対して繰り返すことができます。
  • server_ip: ストレージ サーバーの IP
  • remote_mount: ストレージ マウント名(ファイルシステム名)
  • local_mount: ローカル マウント ディレクトリ
  • fs_type: ファイル システムのタイプ(NFS、CIFS、Lustre、GCSFuse は自動的にインストールされます)
  • mount_options: マウント オプション(defaults、_netdev など)
  • compute_node_service_account: コンピューティング インスタンスで使用されるサービス アカウント
  • compute_node_scopes: コンピューティング インスタンスのアクセス スコープ
  • partitions: Slurm パーティション構成。追加のパーティションに対して繰り返すことができます。
  • name: パーティション名
  • machine_type: コンピューティング ノードのインスタンス タイプ
  • static_node_count: 常時稼働コンピューティング ノードの数
  • max_node_count: 許可されるコンピューティング ノードの合計数の最大値 - 最大 64K
  • zone: このパーティションのリソースを含む Google Cloud ゾーン - 詳細
  • image: コンピューティング イメージ ノードのマシンタイプ
  • image_hyperthreads: インスタンスのハイパースレッディングをオンまたはオフにします。
  • compute_disk_type: コンピューティング インスタンスのブートディスクのタイプ(pd-standard、pd-ssd)
  • compute_disk_size_gb: コンピューティング インスタンスのブートディスクのサイズ
  • compute_labels: コンピューティング インスタンスにアタッチするラベル
  • cpu_platform: すべてのコンピューティング ノードに必要な最小 CPU プラットフォーム
  • gpu_count: パーティション内の各インスタンスにアタッチする GPU の数
  • gpu_type: パーティションのインスタンスにアタッチする GPU のタイプ
  • network_storage: パーティション内のすべてのコンピューティング ノードにマウントするネットワーク ストレージ。フィールドは fstab に直接追加されます。追加のマウントに対して繰り返すことができます。
  • server_ip: ストレージ サーバーの IP
  • remote_mount: ストレージ マウント名(ファイルシステム名)
  • local_mount: ローカル マウント ディレクトリ
  • fs_type: ファイル システムのタイプ(NFS、CIFS、Lustre、GCSFuse は自動的にインストールされます)
  • mount_options: マウント オプション
  • preemptible_bursting: インスタンスはプリエンプティブル インスタンスですか?
  • vpc_subnet: Slurm パーティションのデプロイ先となる Virtual Private Cloud サブネットワーク
  • exclusive: Slurm がノード全体をジョブに割り当てられるようにします。
  • enable_placement: インスタンス間のネットワーク レイテンシを低くするため、インスタンスを相互に近い場所に配置するプレースメント ポリシーを有効にします。
  • regional_capacity: 可用性に基づいて、インスタンスをリージョン内の任意のゾーンに配置できるようにします。
  • regional_policy: regional_capacity が true の場合、このポリシーは使用するリージョンと、そのリージョンで使用しないゾーンを決定します。
  • Instance_template: コンピューティング インスタンスに使用する GCP インスタンス テンプレート。指定された計算フィールドは、テンプレートのプロパティよりも優先されます。たとえば、イメージが指定されている場合、インスタンス テンプレートのイメージが上書きされます。

詳細設定

必要に応じて、クラスタのデプロイ プロセスの一環として、追加のパッケージとソフトウェアをインストールすることもできます。Slurm クラスタにソフトウェアをインストールするには、「Compute Engine の Slurm クラスタにアプリをインストールする」で説明されている複数の方法を使用するか、Slurm によってデプロイされたイメージをカスタマイズします。現在、Slurm は Google Cloud HPC VM イメージをベースにした SchedMD 提供の VM イメージをデプロイし、その上に Slurm をインストールします。

独自のイメージを使用するには、tfvars ファイルに記載されている一般公開の SchedMD VM イメージに基づいて、独自の構成でイメージをビルドします。次に、tfvars ファイルで指定されたイメージ URI を独自のイメージに置き換え、変更をテストします。

トラブルシューティング

この Codelab では、Slurm-GCP リポジトリの ReadMe のトラブルシューティング セクションを参照してください。

最も一般的な問題は、tfvars ファイルの構成ミスと割り当て制限です。この Codelab は、新規ユーザーの標準割り当てと、新規ユーザーが受け取る $300 の無料クレジット内で実行できるように設計されています。VM の作成が失敗した場合は、コントローラ ノードの /var/log/slurm/resume.log ファイルで API エラーを確認します。

4. 構成のデプロイと確認

構成をデプロイする

Cloud Shell セッションで、slurm-gcp/tf/example フォルダから次のコマンドを実行します。

terraform init
terraform apply -var-file=basic.tfvars

設定された構成に基づいて、説明されているアクションを承認するよう求められます。「yes」と入力して、デプロイを開始します。「terraform plan」を実行して、デプロイする構成を表示することもできます。

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

このオペレーションには数分かかることがあります。しばらくお待ちください

デプロイが完了すると、次のような出力が表示されます。

Apply complete! Resources: 8 added, 0 changed, 0 destroyed.

Outputs:

controller_network_ips = [
  [
    "10.0.0.2",
  ],
]
login_network_ips = [
  [
    "10.0.0.3",
  ],
]

VM インスタンスの作成を確認する

ナビゲーション メニューを開き、[Compute Engine] > [VM インスタンス] を選択します。

d5832bdd527794ed.png

コントローラとログイン VM インスタンスが一覧表示されます。

7a1fc9603758d58d.png

[VM インスタンス] で、Terraform によって作成された 2 つの仮想マシン インスタンスを確認します。

cluster_name フィールドを変更した場合は、名前が異なります。

  • g1-controller
  • g1-login0

5. Slurm クラスタにログインする

Slurm クラスタにアクセスする

コードエディタ/Cloud Shell のタブに戻ります。次のコマンドを実行してインスタンスにログインします。このとき、g1-login0 ノードのゾーン(us-central1-b)を <ZONE> に置き換えます。

gcloud compute ssh g1-login0 --zone=<ZONE>

このコマンドを実行すると、g1-login0 仮想マシンにログインします。

ログインノードに簡単にアクセスするもう 1 つの方法は、[VM インスタンス] ページの g1-login0 VM の横にある [SSH] ボタンをクリックして、SSH 接続を含む新しいタブを開くことです。

8c373a87d13620f7.png

Cloud Shell を初めて使用する場合は、次のようなメッセージが表示され、SSH 認証鍵の作成を求められることがあります。

WARNING: The public SSH key file for gcloud does not exist.
WARNING: The private SSH key file for gcloud does not exist.
WARNING: You do not have an SSH key for gcloud.
WARNING: SSH keygen will be executed to generate a key.
This tool needs to create the directory [/home/user/.ssh] before being
 able to generate SSH keys.

Do you want to continue (Y/n)?

該当する場合は、「Y」と入力します。パスフレーズの選択を求められたら、Enter キーを 2 回押して空白のままにします。

ログイン時に次のメッセージが表示された場合:

*** Slurm is currently being configured in the background. ***
A terminal broadcast will announce when installation and configuration is
complete.

このメッセージが表示されるまで待って、ラボを進めないでください(約 5 分):

*** Slurm login setup complete ***

上記のメッセージが表示されたら、ログアウトして g1-login0 にログインし直して、ラボを続行する必要があります。これを行うには、Ctrl+C キーを押してタスクを終了します。

次のコマンドを実行して、インスタンスからログアウトします。

exit

ログイン VM に再接続します。次のコマンドを実行してインスタンスにログインします。このとき、g1-login0 ノードのゾーンを <ZONE> に置き換えます。

gcloud compute ssh g1-login0 --zone=<ZONE>

上記と同様に、接続して設定のすべての側面が完了するまでに 1 ~ 2 分かかることがあります。

Slurm CLI ツールのツアー

これで、クラスタの Slurm ログインノードにログインしました。これは、ユーザー/管理者の操作、Slurm ジョブのスケジューリング、管理アクティビティ専用のノードです。

Slurm コマンドラインについて説明するために、いくつかのコマンドを実行してみましょう。

sinfo コマンドを実行して、クラスタのリソースのステータスを表示します。

sinfo

sinfo の出力例を次に示します。sinfo は、クラスタで使用可能なノード、それらのノードの状態、パーティション、可用性、ノードに課せられた時間制限などの情報をレポートします。

PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
debug*       up   infinite     10  idle~ g1-compute-0-[0-9]

デバッグ パーティションの「max_node_count」が 10 であるため、10 個のノードが「idle~」とマークされています(ノードはアイドル状態の非割り当てモードで、スピンアップの準備ができています)。

次に、squeue コマンドを実行して、クラスタのキューのステータスを表示します。

squeue

squeue の出力例を次に示します。squeue は、クラスタのキューのステータスをレポートします。これには、クラスタでスケジュールされた各ジョブのジョブ ID、ジョブが割り当てられているパーティション、ジョブの名前、ジョブを起動したユーザー、ジョブの状態、ジョブの実行時間、ジョブが割り当てられているノードが含まれます。実行中のジョブがないため、このコマンドの内容は空です。

JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)

Slurm コマンドの「srun」と「sbatch」は、キューに入れられたジョブを実行するために使用されます。「srun」は並列ジョブを実行し、mpirun のラッパーとして使用できます。「sbatch」は、バッチジョブを slurm に送信するために使用され、異なる構成で srun を 1 回または複数回呼び出すことができます。「sbatch」はバッチ スクリプトを受け取るか、–wrap オプションで使用してコマンドラインからジョブ全体を実行できます。

ジョブを実行して、Slurm の動作を確認し、キューにジョブを追加しましょう。

6. Slurm ジョブを実行してクラスタをスケーリングする

Slurm ジョブを実行してクラスタをスケーリングする

Slurm クラスタが稼働したので、ジョブを実行してクラスタをスケールアップしましょう。

「sbatch」コマンドは、Slurm バッチ コマンドとスクリプトを実行するために使用されます。自動スケーリングされた VM で「hostname」を実行する簡単な sbatch スクリプトを実行してみましょう。

g1-login0 にログインした状態で、次のコマンドを実行します。

sbatch -N2 --wrap="srun hostname"

このコマンドは、Slurm バッチ コマンドを実行します。これは、sbatch が「-N」オプションを使用して 2 つのノードを実行することを指定します。また、これらの各ノードが「–wrap」オプションで「srun hostname」コマンドを実行することも指定します。

デフォルトでは、sbatch はコマンドが実行された作業ディレクトリの「slurm-%j.out」に出力を書き込みます。ここで、%j は Slurm ファイル名パターンに従ってジョブ ID に置き換えられます。この例では、ユーザーの /home フォルダから sbatch が実行されています。これは、デフォルトでコントローラでホストされている NFS ベースの共有ファイル システムです。これにより、必要に応じてコンピューティング ノードで入力データと出力データを共有できます。本番環境では、クラスタ オペレーションのパフォーマンスへの影響を避けるため、作業用ストレージを /home ストレージから分離する必要があります。個別のストレージ マウントは、tfvars ファイルの network_storage オプションで指定できます。

sbatch コマンドラインを使用して sbatch スクリプトを実行すると、スケジュールされたジョブのジョブ ID が返されます。次に例を示します。

Submitted batch job 2

sbatch コマンドから返されたジョブ ID を使用して、ジョブの実行とリソースを追跡および管理できます。次のコマンドを実行して、Slurm ジョブキューを表示します。

squeue

実行したジョブが次のように表示されます。

JOBID PARTITION               NAME     USER ST       TIME  NODES   NODELIST(REASON)
    2     debug g1-compute-0-[0-1] username  R       0:10      2 g1-compute-0-[0-1]

コンピューティング ノードがプロビジョニングされていないため、Slurm はジョブの要件に従ってコンピューティング インスタンスを自動的に作成します。このプロセスが自動で行われることには、次の 2 つのメリットがあります。まず、HPC クラスタで通常必要となる、ノードの手動プロビジョニング、ソフトウェアの構成、ノードのクラスタへの統合、ジョブのデプロイといった作業が不要になります。第 2 に、アイドル状態の未使用ノードは最小ノード数が実行されるまでスケールダウンされるため、費用を節約できます。

sinfo コマンドを実行して、Slurm クラスタの起動を確認できます。

sinfo

これにより、squeue にリストされているノードが「alloc#」状態(ノードが割り当てられている状態)で表示されます。

PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
debug*       up   infinite      8  idle~ g1-compute-0-[2-9]
debug*       up   infinite      2 alloc#  g1-compute-0-[0-1]

Google Cloud コンソールの [VM インスタンス] セクションで、新しくプロビジョニングされたノードを確認することもできます。ジョブが新しく割り当てられたノードに割り当てられるまで、ノードのスピンアップと Slurm の実行に数分かかります。VM インスタンスのリストは次のようになります。

9997efff595f1e.png

ノードがジョブを実行すると、インスタンスは「alloc」状態に移行します。これは、ジョブがジョブに割り当てられたことを意味します。

PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
debug*       up   infinite      8  idle~ g1-compute-0-[2-9]
debug*       up   infinite      2  alloc g1-compute-0-[0-1]

ジョブが完了すると、squeue に表示されなくなり、sinfo の「alloc」ノードが「アイドル状態」に戻ります。ジョブが完了するまで(1 ~ 2 分後)、定期的に「squeue」を実行します。

出力ファイル slurm-%j.out が NFS 共有の /home フォルダに書き込まれ、ホスト名が含まれます。出力ファイル(通常は slurm-2.out)を開くか、cat します。出力ファイルの内容は次のようになります。

g1-compute-0-0
g1-compute-0-1

お疲れ様でした。ジョブを実行し、Slurm クラスタをスケールアップしました。

7. MPI ジョブを実行する

次に、ノード間で MPI ジョブを実行します。g1-login0 にログインした状態で、wget を使用して C プログラミング言語で記述された MPI プログラムをダウンロードします。

wget https://raw.githubusercontent.com/mpitutorial/mpitutorial/gh-pages/tutorials/mpi-hello-world/code/mpi_hello_world.c

OpenMPI ツールを使用するには、次のコマンドを実行して OpenMPI モジュールを読み込む必要があります。

module load openmpi

「mpicc」ツールを使用して MPI C コードをコンパイルします。次のコマンドを実行します。

mpicc mpi_hello_world.c -o mpi_hello_world

これにより、C コードがマシンコードにコンパイルされ、Slurm を介してクラスタ全体でコードを実行できるようになります。

次に、任意のテキスト エディタを使用して、「helloworld_batch」という名前の sbatch スクリプトを作成します。

vi helloworld_batch

i」と入力して vi 挿入モードに入ります。

次のテキストをコピーしてファイルに貼り付け、簡単な sbatch スクリプトを作成します。

#!/bin/bash
#
#SBATCH --job-name=hello_world
#SBATCH --output=hello_world-%j.out
#
#SBATCH --nodes=2

srun mpi_hello_world

コードエディタを保存して終了するには、Esc キーを押してから、引用符なしで「:wq」と入力します。

このスクリプトは、Slurm バッチ実行環境とタスクを定義します。まず、実行環境が bash として定義されます。次に、スクリプトは「#SBATCH」行で Slurm オプションを定義します。ジョブ名は「hello_world」と定義されています。

出力ファイルは「hello_world_%j.out」に設定されます。ここで、%j は Slurm ファイル名パターンに従ってジョブ ID に置き換えられます。この出力ファイルは、sbatch スクリプトが実行されたディレクトリに書き込まれます。この例では、これはユーザーの /home フォルダです。これは NFS ベースの共有ファイル システムです。これにより、必要に応じてコンピューティング ノードで入力データと出力データを共有できます。本番環境では、クラスタ オペレーションのパフォーマンスへの影響を避けるため、作業用ストレージを /home ストレージから分離する必要があります。

最後に、このスクリプトを実行するノードの数が 2 として定義されています。

オプションが定義されたら、実行可能なコマンドが提供されます。このスクリプトは、mpirun コマンドの代替となる srun コマンドを使用して、mpi_hello_world コードを並列で実行します。

次に、sbatch コマンドラインを使用して sbatch スクリプトを実行します。

sbatch helloworld_batch

sbatch を実行すると、スケジュールされたジョブのジョブ ID が返されます。例:

Submitted batch job 3

これにより、ノードごとに 1 つのタスクを使用して、2 つのノードで hostname コマンドが実行され、出力が hello_world-3.out ファイルに出力されます。

このジョブは、すでに 2 つのノードがプロビジョニングされているため、すぐに実行されます。

ジョブが完了してリストに表示されなくなるまで、squeue をモニタリングします。

squeue

完了したら、hello_world-3.out ファイルを開くか、cat コマンドを実行して、g1-compute-0-[0-1] で実行されたことを確認します。

Hello world from processor g1-compute-0-0, rank 0 out of 2 processors
Hello world from processor g1-compute-0-1, rank 1 out of 2 processors

5 分間アイドル状態が続くと(YAML の suspend_time フィールドまたは slurm.conf の SuspendTime フィールドで構成可能)、動的にプロビジョニングされたコンピューティング ノードが割り当て解除され、リソースが解放されます。これを検証するには、sinfo を定期的に実行し、クラスタサイズが 0 に戻ることを確認します。

PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
debug*       up   infinite     10  idle~ g1-compute-0-[0-9]

クラスタをデプロイしたリージョンで許可されている割り当てまで、より多くのインスタンスを起動して、さまざまな MPI アプリケーションを実行してみてください。

8. まとめ

おめでとうございます。Google Cloud Platform で Slurm クラスタを作成し、最新の機能を使用してクラスタを自動スケーリングし、ワークロードの需要を満たすことができました。このモデルを使用すると、さまざまなジョブを実行できます。また、Slurm でノードをリクエストするだけで、数分で数百のインスタンスにスケーリングできます。

GCP での Slurm の使用方法の学習を続ける場合は、必ず「Slurm を利用した連携 HPC クラスタの構築」の Codelab を続けてください。この Codelab では、クラウドに 2 つのフェデレーション Slurm クラスタを設定して、オンプレミスまたはクラウドでマルチクラスタ フェデレーションを実現する方法について説明します。

Slurm の新しい GCP ネイティブ機能を使用して、何かクールなものを構築していますか?ご不明な点がございましたら、機能に関するご提案がある場合は、Google Cloud のハイ パフォーマンス コンピューティング ソリューションのウェブサイトから Google Cloud チームにお問い合わせいただくか、Google Cloud と Slurm のヘルプグループでチャットしてください。

Terraform デプロイをクリーンアップする

slurm ノードからログアウトします。

exit

デプロイを削除する前に、自動スケーリングされたノードをスケールダウンします。これらのノードは、各インスタンスに対して「gcloud compute instances delete <インスタンス名>」を実行するか、コンソール GUI を使用して複数のノードを選択して [削除] をクリックすることで、手動で削除することもできます。

g1-login0 からログアウトした後、Google Cloud Shell から次のコマンドを実行すると、Terraform デプロイを簡単にクリーンアップできます。

cd ~/slurm-gcp/tf/examples/basic
terraform destroy -var-file=basic.tfvars

プロンプトが表示されたら、「yes」と入力して続行します。このオペレーションには数分かかることがあります。

プロジェクトを削除する

クリーンアップするには、プロジェクトを削除します。

  • ナビゲーション メニューで [IAM と管理] を選択します。
  • サブメニューの [設定] をクリックします。
  • [プロジェクトを削除] というテキストが表示されたゴミ箱アイコンをクリックします。
  • プロンプトの指示に沿って操作する

学習した内容

  • Terraform を使用して GCP に Slurm をデプロイする方法。
  • GCP で Slurm を使用してジョブを実行する方法。
  • クラスタ情報をクエリし、Slurm で実行中のジョブをモニタリングする方法。
  • GCP で Slurm を使用して特定のジョブ パラメータと要件に対応するためにノードを自動スケーリングする方法。
  • GCP の Slurm で MPI アプリケーションをコンパイルして実行する方法。

Slurm サポートを探す

テスト環境または本番環境でこれらの統合を使用する際にサポートが必要な場合は、SchedMD のお問い合わせページ(https://www.schedmd.com/contact.php)から直接お問い合わせください。

トラブルシューティング ガイドもご利用ください。

最後に、質問を Google Cloud と Slurm のディスカッション グループ(https://groups.google.com/g/google-cloud-slurm-discuss)に投稿することもできます。

詳細

フィードバック

この Codelab に関するフィードバックは、こちらのリンクからお送りください。フィードバックの所要時間は 5 分未満です。ありがとうございました。