Azure CycleCloud 8 と Slurm、Azure NetApp Files(ANF)を組み合わせ、バッチ処理・対話型 JupyterLab・複数ユーザー QoS・ストレージ容量クォータ・オートスケール/常時起動の切り替えをプライベート VNet 内で統合制御する共用クラスタ構成。
なぜこの検証を実施したのか
大学の研究室や企業の R&D 部門で HPC / GPU クラスタをクラウド上に整備する際、「単発の VM を立てて SSH する」だけでは運用が回りません。複数の研究者や学生が同じ環境を共用しようとすると、次のような 7 つの運用上の疑問が挙がります。
- バッチ処理(Slurm 等)でジョブ投入・キューイング・順次実行ができるか(Q1)
- JupyterLab 等の対話型(インタラクティブ)操作を同じ Slurm 管理下で両立できるか(Q2)
- 複数の教員・学生で同一クラスタとホーム領域を安全に共用できるか(Q3)
- 特定のユーザーが計算資源を長時間独占しないよう、利用時間の上限やジョブ優先順位(QoS)を制御できるか(Q4)
- 共有ホームディレクトリの容量を特定のユーザーが使い切らないよう、利用者単位でストレージ容量を制限できるか(Q5)
- ジョブ実行時だけ計算ノードを自動起動・停止(オートスケール)してコンピュート課金を抑えつつ、必要な期間は常時起動(占有)に切り替えられるか(Q6)
- 将来 H100 や A100 など別世代の GPU VM へ置き換える際、どのように設定変更・パーティション分割を行うか(Q7)
これら 7 つの問いに対して、Azure CycleCloud 8 + Slurm + Azure NetApp Files(ANF) の組み合わせでどこまで標準機能として答えられるかを実機構成で検証しました。
重要: 本記事の情報は 2026年10月時点の Microsoft Learn 公開情報および Azure CycleCloud 8(Slurm 26.05.4 /
cyclecloud-slurmテンプレート)に基づきます。今回の実機検証(TC-01〜TC-07)ではサブスクリプションの GPU クォータ制約を回避してオートスケール・QoS・JupyterLab・ANF クォータの一連の制御を実証するため、計算ノード(hpcパーティション)にStandard_D4s_v6を割り当てて実測し、GPU VM SKU(Standard_NC24ads_A100_v4等)の割り当ては CycleCloud GUI の設定画面(TC-08)で確認しています。
TL;DR(先に結論)
-
バッチと対話型(JupyterLab)の両立: Slurm の
sbatchでバッチジョブを順次実行できるだけでなく、srun --pty bashで確保した計算ノード上で JupyterLab を起動することで、対話型セッションも同じ Slurm のキュー・時間制限管理下に統合できる。 -
0 台からの自動起動・自動停止と常時起動の切り替え: 通常時は計算ノードを 0 台(計算ノードの VM コンピュート課金停止) にしておき、ジョブ投入をトリガーに自動起動、アイドル時間経過後に自動削除できる。一方で、年間予約や集中利用期間などノードを落としたくない場面では
azslurm keep_aliveコマンド 1 つで 特定ノードを常時起動(自動停止除外) に切り替えられる。 -
利用時間と優先度は Slurm、容量制限は ANF で役割分担: ジョブの最大実行時間(
MaxWall)や優先度(Priority)は Slurm アカウンティング(sacctmgrの QoS)で制御し、/shared/home/$USERのディスク容量上限は Azure NetApp Files の個人ユーザークォータ で制御するのがシンプルで堅牢な設計になる。 -
GPU SKU の置き換え: 計算ノードの VM サイズ(SKU)は CycleCloud のパーティション設定で管理されており、OS イメージに NVIDIA GPU ドライバー同梱の AlmaLinux 8.10 HPC(
almalinux:almalinux-hpc:8_10-hpc-gen2:latest) 等を採用することで、クラスタ設定の VM サイズ変更またはパーティション追加によって GPU SKU を切り替えられる(ただし GPU 世代を変更する際は CUDA バージョンやコンテナイメージの互換性確認を推奨)。
1. 検証の背景・要件マッピング
共用クラスタに求められる 7 つの要件と、本検証における Azure / Slurm 側の実現方式・検証区分を以下の表に整理します。
| # | 共用環境の要件 | 実現コンポーネント | 制御・設定のポイント | 対応する検証項目・確認方法 |
|---|---|---|---|---|
| Q1 | バッチ処理(ジョブ投入・キューイング・順次実行) | Slurm (sbatch / squeue) |
sbatch で計算リソースを要求し、空き枠に応じて順次スケジューリング(GPU 利用時は --gres=gpu:N を指定) |
4-1 (TC-01: 実機検証) |
| Q2 | JupyterLab 等の対話型(インタラクティブ)操作 | Slurm (srun) + Windows VDI |
srun --pty bash で計算ノードを確保して JupyterLab を起動、Bastion 経由の VDI ブラウザから接続 |
4-4 (TC-04: 実機検証) |
| Q3 | 複数の教員・学生・メンバーでのクラスタ共用 | Slurm + ANF (/shared/home) |
複数 OS ユーザー(全ノード共通 UID)でホーム領域を NFS 共有し、ジョブをユーザー別に識別 | 4-5 (TC-05: 実機検証) |
| Q4 | 利用時間の上限・ジョブ優先順位の制御 | Slurm Accounting (sacctmgr) |
normal(学生想定:上限 1 時間)と high(優先研究想定:上限 24 時間・高優先度)の 2 段階 QoS |
4-6 (TC-06: 実機検証) |
| Q5 | 利用者ごとのストレージ容量制限 | Azure NetApp Files (User Quota) | ANF ボリュームの個人ユーザークォータ(UID 単位)で容量上限を設定し quota -s で監視 |
4-7 (TC-07: 実機検証) |
| Q6 | 従量課金の自動起動/停止と、占有(常時起動)の併用 | CycleCloud Autoscale (azslurm) |
ジョブ連動の 0 台↔N 台オートスケールと、azslurm keep_alive による常時起動ノードの固定 |
4-2, 4-3 (TC-02, TC-03: 実機検証) |
| Q7 | H100 / A100 等、別 GPU SKU への置き換え・混在 | CycleCloud クラスタテンプレート | Node Array の VM サイズ変更、または hpc / gpu パーティションの分割 |
4-8 (TC-08: GUI 設定画面確認) |
2. アーキテクチャと設計のポイント
2-1. 全体アーキテクチャ図
本検証で構築する環境の全体アーキテクチャを下図に示します。すべてのクラスタ VM からパブリック IP を排除し、Azure Bastion を唯一の入り口とする閉域ネットワーク構成としています。
構成図内の主要コンポーネント、起動形態(常時起動かオートスケールか)、および役割は以下のとおりです。
| レイヤー / 境界 | コンポーネント | 構成・サイズ例 | 起動形態 | 役割と設計上の意図 |
|---|---|---|---|---|
アクセス経路 (AzureBastionSubnet) |
Azure Bastion (bastion-hpc01) |
Standard SKU | 常時稼働(PaaS) | クラスタ VM にパブリック IP を持たせず、ポータルや CLI 経由で安全に RDP / SSH 接続を提供する踏み台サービス。 |
クラスタサブネット (subnet-cluster01 10.0.1.0/24) |
Azure NAT Gateway (natgw-hpc01) |
Standard SKU | 常時稼働(PaaS) | 2026年3月末以降のプライベートサブネット既定化(defaultOutboundAccess: false)に対応し、閉域 VM から Azure Resource Manager(management.azure.com)やパッケージリポジトリへの送信通信を提供する。 |
クラスタサブネット (subnet-cluster01 10.0.1.0/24) |
Windows VDI Node (vdi-win01) |
Standard_D4s_v6 (Windows Server) |
利用時のみ起動(手動停止可) | 閉域 VNet 内の CycleCloud Web UI(HTTPS)および計算ノード上の JupyterLab(HTTP 8888)へブラウザアクセスするための作業用端末。 |
クラスタサブネット (subnet-cluster01 10.0.1.0/24) |
CycleCloud Server (cc-server01) |
Standard_D4s_v6 (AlmaLinux / RHEL) |
クラスタ稼働中は常時起動(1台) | クラスタのテンプレート管理・VM プロビジョニング・オートスケールを司るオーケストレーター(インフラ管理サーバー)。Slurm のジョブスケジューラそのものではなく、裏方で Azure VM/VMSS を作成・削除する。 |
クラスタサブネット (subnet-cluster01 10.0.1.0/24) |
Slurm Head Node (scheduler) |
Standard_D4s_v6 (AlmaLinux 8.10 HPC) |
クラスタ稼働中は常時起動(1台) |
Slurm のスケジューラーノード兼ログインノード。slurmctld(ジョブスケジューラ)および slurmdbd(アカウンティング)を実行し、学生・研究者が SSH ログインして sbatch / srun を投入する窓口となる。ジョブが入ると azslurm 経由で CycleCloud Server の API を呼び出して計算ノードの起動を要求する。 |
クラスタサブネット (subnet-cluster01 10.0.1.0/24) |
Compute Nodes (hpc / gpu / htc) |
GPU / 汎用 VM SKU(初期 0 台、ジョブ連動) |
オートスケール(0台↔N台) ※ keep_alive で常時起動化も可 |
AlmaLinux 8.10 HPC イメージで起動する計算ノード群。ジョブがない時は 0 台(VM コンピュート課金ゼロ) で待機し、ジョブ投入時に自動起動、アイドル時に自動削除される。 |
ANF 委任サブネット (subnet-anf01 10.0.253.0/28) |
Azure NetApp Files (anf-stg / vol01) |
Standard サービスレベル / 4 TiB プール | 常時稼働(PaaS) |
/shared/home/$USER 等の共有 NFS ボリュームを提供し、UID 単位のユーザークォータで容量上限を強制する。 |
認証・保管 (Identity & Storage) |
User Assigned Managed Identity (mngdid-rg-hpc01) |
RG Contributor + Storage Blob Data Contributor + Sub Reader
|
— | CycleCloud サーバーおよびクラスタに割り当て、シークレット管理なしに VM 作成・Locker 読み書き・SKU カタログ取得を行う。 |
認証・保管 (Identity & Storage) |
CycleCloud Locker (stgacctcc01) + Private Endpoint |
StorageV2 + privatelink.blob.core.windows.net
|
常時稼働(PaaS) | CycleCloud が cluster-init スクリプトや Slurm パッケージを配置する Blob ストレージ。Private Endpoint 経由で閉域アクセスする。 |
補足(CycleCloud Server と Slurm Head Node の違い・常時起動の範囲):
- CycleCloud Server はスケジューラーノードではありません。CycleCloud Server(
cc-server01)は Azure リソースを管理するオーケストレーターであり、Slurm のスケジューラー(兼ユーザーのログインノード)は CycleCloud が起動する Slurm Head Node(scheduler) です。- ジョブをいつでも受け付けられるようにするため、クラスタ稼働中は
CycleCloud ServerとSlurm Head Node (scheduler)の 2 台(安価な汎用 VM)は常時起動させておき、高価なCompute Nodes(GPU 計算ノード)だけを 0 台↔N 台でオートスケールさせるのが基本運用です(長期休暇等でクラスタ自体を使わない期間は、CycleCloud 上でクラスタをTerminateしてschedulerも削除し、cc-server01自体も VM 停止できます)。
2-2. なぜこの構成なのか(3 つの設計判断)
-
すべての計算・管理 VM からパブリック IP を排除(Bastion + Windows VDI + NAT Gateway 方式)
大学・研究機関のセキュリティポリシーでは、計算ノードや管理サーバーへインターネットから直接インバウンド接続させない構成が強く求められます。各 VM にはパブリック IP を付与せず、インバウンドは Azure Bastion 経由のみとし、アウトバウンド通信(ARM API やパッケージ取得)はサブネットに紐付けた Azure NAT Gateway で明示的に制御します。CycleCloud の Web UI や計算ノード上で起動する JupyterLab(ポート 8888)へは、同一 VNet 内に配置した Windows VDI ノードのブラウザからプライベート IP でアクセスすることで、SSH ポートフォワーディングなしに直感的な GUI 操作を実現できます。 -
HPC / GPU ドライバー導入済みの AlmaLinux 8.10 HPC イメージ
オートスケールで計算ノードが動的に起動・破棄される環境では、起動のたびにドライバーやライブラリをビルドしているとジョブ開始までの待ち時間が増加します。Azure Marketplace で提供されているalmalinux:almalinux-hpc:8_10-hpc-gen2:latest(またはmicrosoft-dsvm:ubuntu-hpc:2404:latest)は、NVIDIA GPU ドライバー・Mellanox OFED(InfiniBand ドライバー)・主要な HPC ライブラリがあらかじめ組み込まれているため、GPU SKU を選択した際もプロビジョニング完了後すぐにジョブを実行できます。 -
「計算リソース制御(Slurm)」と「ストレージ容量制御(ANF)」の分離
Slurm は CPU / メモリ / GPU(GRES)の割り当て時間や優先度を制御するのには優れていますが、NFS 上のホームディレクトリ容量の制限はファイルシステム側の責務です。Azure NetApp Files(ANF)のユーザークォータ機能を組み合わせることで、Linux 標準の UID に基づいてストレージ側で確実な容量上限をかけられます。
出典: Azure HPC/AI VM イメージ / Azure NetApp Files の既定および個別のユーザーとグループのクォータについて
2-3. 利用者(学生・研究者)と管理者のアカウント設計・アクセス導線
「学生が使う場合、どこにアカウントを作り、どのように環境へ入っていくのか(CycleCloud に入るのか? VDI 経由なのか?)」という運用イメージを整理します。
結論として、学生は「CycleCloud の管理画面」には一切入りません。学生が使うのは 「Slurm ヘッドノード(scheduler)への SSH」 と、JupyterLab を使う場合の 「VDI のブラウザ」 だけです。
| 誰が(ロール) | 何をするか | どこに入るか(接続経路) | どこにアカウントを作るか |
|---|---|---|---|
|
管理者 (教職員・インフラ担当) |
クラスタ起動/停止・GPU SKU 変更・クォータ設定 | Bastion → VDI(RDP)→ ブラウザで CycleCloud 管理画面(cc-server01)
|
CycleCloud 管理画面 + Azure RBAC |
|
学生・研究者 (バッチジョブ実行) |
sbatch でジョブ投入・結果確認 |
Bastion(または学内 VPN)→ Slurm ヘッドノード(scheduler)へ直接 SSH※VDI や CycleCloud は使わない |
Linux OS ユーザー(共通 UID)+ Slurm DB(sacctmgr) |
|
学生・研究者 (JupyterLab 対話利用) |
ブラウザで Notebook を対話実行 | Bastion → VDI(RDP) → scheduler へ SSH して srun で Jupyter 起動 → VDI 内ブラウザで接続 |
Linux OS ユーザー + Slurm DB + VDI ログイン用アカウント |
ポイント(Linux アカウントの一元管理):
オートスケールで動的に起動する計算ノードでも同じ UID / ホーム(/shared/home/$USER)でジョブが動くよう、実運用では CycleCloud 8 の組み込みユーザー管理や Active Directory / Microsoft Entra Domain Services / LDAP 連携で全ノード共通の UID を一元管理します。
学生が Bastion 経由で入る場合、Azure の RBAC 付与は必要か?
Azure Bastion を入り口にする場合、接続方式によって学生への Azure RBAC 付与が「必要なケース」と「不要にできるケース」に分かれます。
| 接続方式 | 学生への Azure RBAC | 必要な権限・運用の特徴 |
|---|---|---|
|
A. Azure Portal / Azure CLI から Bastion 接続 (標準の Bastion SSH / RDP / az network bastion tunnel) |
必要 | 学生の Entra ID に対し、①対象 VM(scheduler / vdi-win01)、②対象 VM の NIC、③Azure Bastion リソースの 3 点に対する Reader(閲覧者)ロールが必要。 |
|
B. Bastion の「共有可能リンク(Shareable Link)」を利用 (Bastion Standard SKU 以上の機能) |
不要 | 管理者が発行した専用 URL を学生に配布する方式。学生は Azure Portal 権限(RBAC)や Entra ID なしで、ブラウザから URL を開いて Linux の SSH 秘密鍵(または RDP 資格情報)だけでログイン可能。 |
|
C. 学内 VPN / ExpressRoute 経由で直接接続 (大学キャンパス網と Azure VNet を接続する場合) |
不要 | Bastion を介さず手元 PC からプライベート IP(10.0.1.7)へ直接 SSH できるため、Azure RBAC は一切不要(Linux アカウントと SSH 鍵のみで完結)。 |
出典: Azure Bastion FAQ - 仮想マシンにアクセスするために必要なロールはありますか? / Bastion の共有可能リンクを作成する
3. 環境構築手順(ハンズオン準拠)
ここからは、実際に Azure CLI で基盤リソースを展開し、CycleCloud 上で Slurm クラスタを構築する手順を示します。
注意: CycleCloud クラスタを展開する際、VNet・ANF・CycleCloud サーバー・計算ノードは同一リージョンに配置します(本検証では変数
$LOCATION="southeastasia"で統一しています)。
3-1. 事前準備(RG・マネージド ID・VNet・NAT Gateway・閉域 Storage・Bastion)
まず、リソースグループ、CycleCloud サーバーに付与するユーザー割り当てマネージド ID、仮想ネットワーク(3 つのサブネット+NAT Gateway)、および Private Endpoint 付きの CycleCloud Locker 用ストレージアカウントを作成します。
重要(2026年3月31日以降の仕様変更): Azure では 2026年3月31日以降の API バージョンで新規作成されるサブネットが既定で**プライベート サブネット(
defaultOutboundAccess: false)**になりました。パブリック IP を持たないcc-server01やschedulerから Azure Resource Manager(management.azure.com)や GitHub へアクセスするため、subnet-cluster01には Azure NAT Gateway を必ず関連付けます。
01-infra-prereq.sh: RG・マネージドID・VNet・NAT Gateway・閉域Storage・Bastionの作成(クリックで展開)
# 01-infra-prereq.sh
# リージョンとリソース名の定義(全リソースを同一リージョンに統一する)
RG="rg-hpc01-sea"
LOCATION="southeastasia"
VNET="vnet-hpc01"
MNGD_ID="mngdid-rg-hpc01"
STG_ACCT="stgacctcc01$(openssl rand -hex 2)"
# 1. リソースグループの作成
az group create -n "$RG" -l "$LOCATION"
# 2. CycleCloud 用ユーザー割り当てマネージド ID の作成と RBAC ロール付与
az identity create -n "$MNGD_ID" -g "$RG" -l "$LOCATION"
PRINCIPAL_ID=$(az identity show -n "$MNGD_ID" -g "$RG" --query principalId -o tsv)
RG_ID=$(az group show -n "$RG" --query id -o tsv)
SUB_ID=$(az account show --query id -o tsv)
az role assignment create --assignee-object-id "$PRINCIPAL_ID" --assignee-principal-type ServicePrincipal --role "Contributor" --scope "$RG_ID"
az role assignment create --assignee-object-id "$PRINCIPAL_ID" --assignee-principal-type ServicePrincipal --role "Storage Blob Data Contributor" --scope "$RG_ID"
az role assignment create --assignee-object-id "$PRINCIPAL_ID" --assignee-principal-type ServicePrincipal --role "Reader" --scope "/subscriptions/$SUB_ID"
# 3. 仮想ネットワークと 3 つのサブネット(cluster + NAT Gateway / anf委任 / Bastion)の作成
az network nsg create -g "$RG" -n "nsg-cluster01" -l "$LOCATION"
az network public-ip create -g "$RG" -n "pip-natgw-hpc01" -l "$LOCATION" --sku Standard
az network nat gateway create -g "$RG" -n "natgw-hpc01" -l "$LOCATION" --public-ip-addresses "pip-natgw-hpc01" --idle-timeout 10
az network vnet create -g "$RG" -n "$VNET" -l "$LOCATION" \
--address-prefixes 10.0.0.0/16 \
--subnet-name "subnet-cluster01" --subnet-prefixes 10.0.1.0/24 \
--network-security-group "nsg-cluster01" --nat-gateway "natgw-hpc01"
# ANF 用サブネット(Microsoft.NetApp/volumes へ委任)
az network vnet subnet create -g "$RG" --vnet-name "$VNET" -n "subnet-anf01" \
--address-prefixes 10.0.253.0/28 --delegations "Microsoft.NetApp/volumes"
# Azure Bastion 用サブネット
az network vnet subnet create -g "$RG" --vnet-name "$VNET" -n "AzureBastionSubnet" \
--address-prefixes 10.0.254.0/26
# 4. CycleCloud Locker 用ストレージアカウントと Private Endpoint の作成
az storage account create -n "$STG_ACCT" -g "$RG" -l "$LOCATION" --sku Standard_LRS --kind StorageV2 --allow-blob-public-access false
STG_ID=$(az storage account show -n "$STG_ACCT" -g "$RG" --query id -o tsv)
az network private-dns zone create -g "$RG" -n "privatelink.blob.core.windows.net"
az network private-dns link vnet create -g "$RG" -z "privatelink.blob.core.windows.net" -n "link-$VNET" -v "$VNET" -e false
az network private-endpoint create -g "$RG" -n "pe-$STG_ACCT-blob" -l "$LOCATION" \
--vnet-name "$VNET" --subnet "subnet-cluster01" \
--private-connection-resource-id "$STG_ID" --group-id "blob" --connection-name "conn-blob"
az network private-endpoint dns-zone-group create -g "$RG" --endpoint-name "pe-$STG_ACCT-blob" \
-n "default" --private-dns-zone "privatelink.blob.core.windows.net" --zone-name "blob"
# 5. Azure Bastion の展開
az network public-ip create -g "$RG" -n "pip-bastion-hpc01" -l "$LOCATION" --sku Standard
az network bastion create -g "$RG" -n "bastion-hpc01" -l "$LOCATION" \
--public-ip-address "pip-bastion-hpc01" --vnet-name "$VNET" --sku Standard --enable-tunneling true
作成後の検証コマンド:
az network private-endpoint show -g "$RG" -n "pe-$STG_ACCT-blob" --query "provisioningState" -o tsv
# Succeeded が返ることを確認
3-2. Azure NetApp Files(ANF)の展開と共有ボリューム作成
続いて、/shared/home/$USER としてマウントする Azure NetApp Files のアカウント、容量プール(4 TiB / Standard)、および NFSv3 ボリューム(vol01)を作成します。
02-create-anf.sh: ANFアカウント・容量プール・NFSボリュームの作成(クリックで展開)
# 02-create-anf.sh
ANF_ACCT="anf-stg"
ANF_POOL="anf-stg-pool01"
ANF_VOL="vol01"
# 1. NetApp アカウントと容量プール(4 TiB, Standard)の作成
az netappfiles account create -g "$RG" -n "$ANF_ACCT" -l "$LOCATION"
az netappfiles pool create -g "$RG" --account-name "$ANF_ACCT" -n "$ANF_POOL" -l "$LOCATION" \
--size 4 --service-level Standard
# 2. NFSv3 ボリューム(100 GiB、subnet-anf01 に配置)の作成
az netappfiles volume create -g "$RG" --account-name "$ANF_ACCT" --pool-name "$ANF_POOL" -n "$ANF_VOL" -l "$LOCATION" \
--service-level Standard --usage-threshold 100 --file-path "vol01" \
--vnet "$VNET" --subnet "subnet-anf01" --protocol-types NFSv3 \
--rule-index 1 --allowed-clients "10.0.0.0/16" --unix-read-write true --has-root-access true
作成後、Slurm テンプレートに設定する ANF のマウント先 IP アドレスを確認します。
az netappfiles volume show -g "$RG" --account-name "$ANF_ACCT" --pool-name "$ANF_POOL" -n "$ANF_VOL" --query "mountTargets[0].ipAddress" -o tsv
# 例: 10.0.253.4 が返ることを確認
3-3. CycleCloud サーバーと Windows VDI ノードの展開
CycleCloud サーバー VM(パブリック IP なし・ユーザー割り当てマネージド ID アタッチ)と、ブラウザ操作用の Windows VDI ノードを subnet-cluster01 に作成します。
03-create-cyclecloud-and-vdi.sh: CycleCloudサーバーとWindows VDIの展開(クリックで展開)
# 03-create-cyclecloud-and-vdi.sh
ID_RES_ID=$(az identity show -n "$MNGD_ID" -g "$RG" --query id -o tsv)
# Marketplace の CycleCloud イメージ規約に同意
az vm image terms accept --urn "azurecyclecloud:azure-cyclecloud:cyclecloud8-gen2:latest"
# 1. CycleCloud サーバー VM の作成(パブリック IP なし、マネージド ID 付与)
az vm create -g "$RG" -n "cc-server01" -l "$LOCATION" \
--image "azurecyclecloud:azure-cyclecloud:cyclecloud8-gen2:latest" \
--size "Standard_D4s_v6" \
--vnet-name "$VNET" --subnet "subnet-cluster01" --public-ip-address "" \
--private-ip-address "10.0.1.6" --nsg "" \
--assign-identity "$ID_RES_ID" \
--admin-username "azureuser" --ssh-key-values "@ssh_keys/id_rsa.pub"
# 2. Windows VDI ノードの作成(CycleCloud Web UI / JupyterLab アクセス用)
az vm create -g "$RG" -n "vdi-win01" -l "$LOCATION" \
--image "MicrosoftWindowsServer:WindowsServer:2022-datacenter-g2:latest" \
--size "Standard_D4s_v6" \
--vnet-name "$VNET" --subnet "subnet-cluster01" --public-ip-address "" --nsg "" \
--admin-username "azureuser" --admin-password "<StrongPassword123!>"
3-4. Slurm クラスタテンプレート(cyclecloud-slurm)の導入と GPU 設定
Azure Bastion 経由で vdi-win01 に RDP 接続し、ブラウザから CycleCloud Web UI へアクセスして初期セットアップ(Site Name、Managed Identity 認証、Storage Locker stgacctcc01 の選択、管理者 SSH 公開鍵の登録)を完了します。
CycleCloud の Subscriptions 設定画面。Orchestrator Configuration と Locker Configuration の双方でユーザー割り当てマネージド ID(mngdid-rg-hpc01)を指定し、閉域 Storage Account(stgacctcc011402)を Locker として紐付けます。
その後、CycleCloud サーバーへ SSH ログインし、GitHub から cyclecloud-slurm テンプレートを取得してインポートします(CycleCloud 8 標準搭載の Slurm テンプレートをそのまま利用することも可能です)。
04-import-slurm-template.sh: cyclecloud-slurm 3.0.10 の取得とインポート(クリックで展開)
# 04-import-slurm-template.sh(cc-server01 上で実行)
mkdir -p ~/cyclecloud_projects && cd ~/cyclecloud_projects
wget https://github.com/Azure/cyclecloud-slurm/archive/refs/tags/3.0.10.zip
unzip 3.0.10.zip
ln -s cyclecloud-slurm-3.0.10 cyclecloud-slurm
cd cyclecloud-slurm/templates
# テンプレート名を Slurm-poc01 としてインポート
cp -p slurm.txt slurm.txt.org
sed -i 's/\[cluster Slurm\]/[cluster Slurm-poc01]/' slurm.txt
cyclecloud import_template -f slurm.txt
CycleCloud GUI で新規 Slurm クラスタ(Slurm-poc01)を作成する際、以下の 4 点を設定します。
| 設定タブ | パラメータ | 設定値 | 理由 |
|---|---|---|---|
| Required Settings | Scheduler VM Type / HPC VM Type / GPU VM Type | Scheduler: Standard_D4s_v6 / HPC: Standard_D4s_v6 / GPU: Standard_NC24ads_A100_v4 等 |
計算ノード(hpc / gpu パーティション)に用途別の VM サイズを割り当てるため |
| Required Settings | Autoscale / Max Nodes |
Start and stop execute instances automatically を ON(初期起動台数は 0) |
ジョブがない時は 0 台に保ち、投入時のみスケールアウトさせるため |
| Network Attached Storage | File-system Mount for /shared
|
Use Builtin NFS を OFF → External NFS / IP 10.0.253.4 / Export Path /vol01
|
ANF ボリュームを全ノード共通の /shared(/shared/home/$USER)としてマウントするため |
| Advanced Settings | Managed Id / OS (Alma Linux 8) |
Managed Id: mngdid-rg-hpc01 / OS: Alma Linux 8 (almalinux:almalinux-hpc:8_10-hpc-gen2:latest) |
Locker アクセス用マネージド ID と NVIDIA GPU ドライバー同梱の HPC イメージを指定し、完全閉域(Return Proxy・Public Head Node オフ)で起動するため |
Required Settings タブの設定画面。Scheduler VM Type・HPC VM Type・GPU VM Type をそれぞれ指定し、Autoscale を有効化します。
Network Attached Storage タブの設定画面。/shared の Use Builtin NFS のチェックを外して External NFS を選択し、ANF ボリュームのマウント IP(10.0.253.4)と Export Path(/vol01)を指定します(下部の Additional Filesystem Mount で二重に /shared を指定しないよう注意します)。
Advanced Settings タブの設定画面。Managed Id に rg-hpc01-sea/mngdid-rg-hpc01 を選択し、OS に Alma Linux 8(almalinux:almalinux-hpc:8_10-hpc-gen2:latest)を指定します。
4. 7つの運用シナリオ実機検証(TC-01〜TC-08)
クラスタを開始(Start)すると、約 6 分で Slurm ヘッドノード(scheduler)が Ready(緑色)となり、計算ノードは 0 台 の状態で待機します。ここから冒頭の 7 つの質問(Q1〜Q7)に対応する 8 つのテストケースを順に検証します。
クラスタ起動完了直後の状態。scheduler ノード(1 台・4 コア)のみが稼働(緑色)しており、計算ノードは 0 台で課金が発生していないことが確認できます。
4-1. バッチ処理とジョブの順次実行(TC-01 / Q1)
Slurm ヘッドノード(10.0.1.7)へ SSH ログインし、バッチジョブスクリプトを作成して sbatch で 3 本連続投入します。
gpu-job01.sh: Slurmバッチジョブスクリプト(クリックで展開)
#!/bin/bash
#SBATCH --partition=hpc
#SBATCH --job-name=gpu-job01
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=4
#SBATCH --time=00:10:00
#SBATCH --output=slurm-%x-%j.out
# 1. ジョブ開始時刻と、割り当てられた計算ノードのホスト名(例: slurm-poc01-hpc-1)を出力
echo "=== Job Start: $(date) on $(hostname) ==="
# 2. GPU 搭載ノードなら nvidia-smi を出力し、GPU 非搭載の汎用 VM なら代わりに lscpu で CPU 情報を出力
nvidia-smi 2>/dev/null || lscpu | grep -E "Model name|Socket|Thread|NUMA|CPU\(s\):"
# 3. squeue で実行中(R)状態や複数ジョブの挙動を観察できるよう、模擬処理として 120 秒間維持
sleep 120
# 4. ジョブ終了時刻を出力
echo "=== Job End: $(date) ==="
スクリプト後半の 4 行は以下の意味を持っています。
-
echo "=== Job Start: $(date) on $(hostname) ===": ジョブの開始日時と、実際に処理が走っているホスト名(ヘッドノードではなく計算ノードslurm-poc01-hpc-1等であることの証跡)を出力します。 -
nvidia-smi 2>/dev/null || lscpu | grep -E ...: まずnvidia-smiで GPU の認識状態を表示し、もし GPU 非搭載の汎用 VM(今回のStandard_D4s_v6代替検証環境など)でnvidia-smiが失敗した場合(||)は、代わりにlscpuで CPU のモデル名・コア数・NUMA 構成を抜粋して出力します。GPU ノード・CPU ノードのどちらでも同じスクリプトのまま動作確認できる書き方です。 -
sleep 120: 本来の機械学習や数値計算の代わりに 120 秒間待機します。処理が一瞬で終わるとsqueue上のR(Running)状態や複数ジョブのキューイングを確認できないために入れています。 -
echo "=== Job End: $(date) ===": 120 秒経過後のジョブ終了日時を記録します。
ジョブの3本連続投入とキュー確認コマンド(クリックで展開)
sbatch ~/gpu-job01.sh
sbatch ~/gpu-job01.sh
sbatch ~/gpu-job01.sh
squeue
これにより、計算資源の空き枠に応じてジョブが割り当てられ、完了後に結果ログ(slurm-gpu-job01-<JOBID>.out)が /shared/home/$USER 上に出力されることを確認できます。
4-2. 計算ノードの自動起動・自動停止(TC-02 / Q6)
CycleCloud + Slurm の大きなメリットが、「ジョブがない時は計算ノード 0 台、ジョブが入ると自動起動、終われば自動削除」 というオートスケール動作です。
-
ジョブ投入前: CycleCloud GUI 上で計算ノードが
0台(sinfoの STATE がidle~:未起動待機)であることを確認します。 -
ジョブ投入時:
sbatch ~/gpu-job01.shを 3 本実行すると、sinfoの STATE がalloc#(プロビジョニング中)、squeueの STATE がCF(Configuring)になり、CycleCloud 側で計算ノード VMSS(Slurm-poc01-hpc-[1-3])の作成が自動的に開始されます。
ジョブ投入直後の画面(左:CycleCloud Web UI、右:ヘッドノード SSH ターミナル)。sbatch をトリガーに hpc ノード 3 台のプロビジョニングが自動開始され、squeue 上で CF(Configuring)として表示されています。
-
ノード起動完了とジョブ実行: 約 7〜8 分で VM が起動して Slurm クラスタに参加すると、STATE が
R(Running)へ遷移してジョブが実行され、slurm-gpu-job01-1.outに計算ノード(slurm-poc01-hpc-1)の実行結果が出力されます。
計算ノード起動完了後の実行結果。sacct でジョブが COMPLETED となり、slurm-gpu-job01-1.out に計算ノード slurm-poc01-hpc-1 上での出力が記録されています。
-
ジョブ終了後の自動停止: ジョブ完了後、Slurm の
SuspendTime(既定 300 秒)が経過すると、計算ノード VM は自動的に Deallocate(削除)され、再び 0 台(課金ゼロ) に戻ります。
ポイント: GPU VM の GPU 枚数が Slurm の GRES に正しく認識されない場合(
Requested node configuration is not availableとなる場合)は、ヘッドノードの/opt/azurehpc/slurm/autoscale.jsonにslurm_gpusを明示定義してazslurm scaleとazslurm bucketsを実行することで即時反映できます(詳細は「5. ハマったポイント」参照)。
4-3. azslurm keep_alive による計算ノードの常時起動(TC-03 / Q6)
「通常はオートスケールで節約したいが、特定の研究期間や年間予約枠のノードは毎回数分の起動待ちをせずに常時起動(占有)させておきたい」という要件(Q6)に対しては、クラスタを作り直すことなく azslurm keep_alive コマンドでノード単位に制御できます。
05-keep-alive.sh: 特定ノードを自動停止対象から除外して常時起動化する手順(クリックで展開)
# 1. 対象の計算ノードが起動している状態で、ヘッドノードにて keep_alive を設定
sudo azslurm keep_alive --set --node-list Slurm-poc01-hpc-1
# 2. slurmctld を再起動し、azslurm scale で反映
sudo systemctl restart slurmctld
sudo azslurm scale
cat /etc/slurm/keep_alive.conf
# (常時起動を解除して再びオートスケールに戻す場合)
sudo azslurm keep_alive --remove --node-list Slurm-poc01-hpc-1
sudo systemctl restart slurmctld
sudo azslurm scale
azslurm keep_alive --set の実行画面。CycleCloud GUI 側の Status Message が KeepAlive に変わり、/etc/slurm/keep_alive.conf の SuspendExcNodes=Slurm-poc01-hpc-1 によってアイドル時も自動停止されなくなります。
これにより、同じ 1 つの Slurm クラスタの中で「必要なときだけ起動する従量ノード」と「常時起動しておく固定ノード」を柔軟に使い分けられることが確認できます。
出典: Azure CycleCloud Slurm - パーティションやノードをオートスケールから除外する (keep_alive)
4-4. Slurm 管理下での対話型利用(JupyterLab)(TC-04 / Q2)
「バッチだけでなく JupyterLab で対話的に試行錯誤したい」という要件(Q2)に対し、計算ノードへ直接勝手に入るのではなく、Slurm のインタラクティブジョブ(srun)として計算リソースと利用時間を確保した上で JupyterLab を起動します。
srunによる対話ジョブ取得とJupyterLab起動コマンド(クリックで展開)
# 1. ヘッドノードから最大 1 時間を指定して計算ノードの対話シェルを取得
srun --partition=hpc --time=01:00:00 --pty bash
# 2. 割り当てられた計算ノード(slurm-poc01-hpc-1)上で IP を確認し、JupyterLab を起動
hostname -I
~/.local/bin/jupyter lab --no-browser --ip=0.0.0.0 --port=8888
起動時に出力される URL(http://10.0.1.8:8888/lab)を、Azure Bastion 経由で接続している Windows VDI ノード(vdi-win01)のブラウザ で開きます。
Windows VDI 内のブラウザから計算ノード(10.0.1.8:8888)の JupyterLab に接続し、Notebook セル上で !hostname(slurm-poc01-hpc-1)と !lscpu を対話実行している様子。右側のターミナルでは srun によってセッションが Slurm ジョブとして管理されています。
この方式のメリットは以下の 2 点です。
- Notebook セルから対話的にコードを実行でき、ファイルは
/shared/home/$USER(ANF)に直接保存される。 -
対話型で利用中のノードも
squeue上に 1 ジョブとして可視化され、指定した--time(または QoS の上限時間)が来れば自動的に解放されるため、「誰かが Jupyter を開いたまま放置して計算ノードがずっと空かない」という共用クラスタ特有の課題を防げる。
4-5. 複数ユーザーでのクラスタ共用(TC-05 / Q3)
共用環境(Q3)の検証として、全ノード共通の UID を持つ 2 名のユーザー(user01:学生想定、user02:教員想定)を作成し、ホームディレクトリを ANF 上の /shared/home/$USER に配置します。
# 共通 UID で user01 / user02 を作成し、ホームを /shared/home 配下に配置
sudo useradd -u 20003 -d /shared/home/user01 -m user01
sudo useradd -u 20002 -d /shared/home/user02 -m user02
両ユーザーから同時にジョブを投入すると、squeue 上で USER 列によって誰のジョブかが明確に識別され、計算ノード側でも同じ UID で /shared/home/user01・/shared/home/user02 にアクセスできることを確認できます。
user01(JOBID 4)と user02(JOBID 5)の双方からジョブを投入した状態。squeue の USER 列でユーザーごとにジョブが識別され、CycleCloud 側で 2 台の計算ノードが並行して自動起動しています。
4-6. Slurm QoS による利用時間・優先順位の制御(TC-06 / Q4)
「学生と教員で最大実行時間やキューの優先順位を分けたい」という要件(Q4)は、Slurm アカウンティング(slurmdbd / sacctmgr)の QoS(Quality of Service) で制御します。本検証では以下の 2 つの QoS を定義します。
| QoS 名 | 想定ロール | 最大実行時間 (MaxWall) |
ジョブ優先度 (Priority) |
リソース上限 (MaxTRESPerUser) |
|---|---|---|---|---|
normal |
一般・学生 (user01) |
01:00:00(1 時間) |
10 |
cpu=4(または gres/gpu=1) |
high |
教員・優先研究 (user02) |
24:00:00(24 時間) |
1000 |
cpu=16(または gres/gpu=4) |
06-configure-slurm-qos.sh: slurmdbd(MariaDB)の有効化と sacctmgr による QoS 作成(クリックで展開)
# 06-configure-slurm-qos.sh(ヘッドノードの root で実行)
# 0. MariaDB と slurmdbd の構成・起動(Job Accounting 未有効時)
dnf install -y mariadb-server && systemctl enable --now mariadb
mysql -e "CREATE DATABASE IF NOT EXISTS slurm_acct_db; CREATE USER IF NOT EXISTS 'slurm'@'localhost' IDENTIFIED BY 'slurm123'; GRANT ALL ON slurm_acct_db.* TO 'slurm'@'localhost'; FLUSH PRIVILEGES;"
cat << 'EOF' > /sched/slurm-poc01/slurmdbd.conf
AuthType=auth/munge
DbdHost=localhost
StorageType=accounting_storage/mysql
StorageHost=localhost
StorageUser=slurm
StoragePass=slurm123
StorageLoc=slurm_acct_db
LogFile=/var/log/slurm/slurmdbd.log
PidFile=/var/run/slurmdbd.pid
SlurmUser=slurm
EOF
chown slurm:slurm /sched/slurm-poc01/slurmdbd.conf && chmod 600 /sched/slurm-poc01/slurmdbd.conf
systemctl enable --now slurmdbd
cat << 'EOF' > /sched/slurm-poc01/accounting.conf
AccountingStorageType=accounting_storage/slurmdbd
AccountingStorageHost=localhost
AccountingStorageEnforce=associations,limits,qos
EOF
systemctl restart slurmctld
# 1. normal と high の 2 つの QoS を作成
sacctmgr -i add qos normal set MaxWall=01:00:00 Priority=10 MaxTRESPerUser=cpu=4
sacctmgr -i add qos high set MaxWall=24:00:00 Priority=1000 MaxTRESPerUser=cpu=16
# 2. クラスターアカウントにユーザーを登録し、既定 QoS を割り当て
sacctmgr -i add user user01 Account=root DefaultQOS=normal QOS=normal
sacctmgr -i add user user02 Account=root DefaultQOS=high QOS=high
# 3. PriorityWeightQOS を有効化して設定反映
echo -e "\nPriorityType=priority/multifactor\nPriorityWeightQOS=10000" >> /sched/slurm-poc01/site_specific.conf
scontrol reconfigure
sacctmgr show qos format=Name,Priority,MaxWall,MaxTRESPerUser
QoS の検証結果。normal QoS(上限 1 時間)が割り当てられた user01 が --time=02:00:00(2 時間)のジョブ(JOBID 6)を投入すると、REASON が (QOSMaxWallDurationPerJobLimit) となって実行前にブロックされます。
設定後の検証動作:
-
上限時間を超えるジョブのブロック(保留)と対処法:
user01(normalQoS:上限 1 時間)がsbatch --time=02:00:00 gpu-job01.shを投入すると、REASON が(QOSMaxWallDurationPerJobLimit)となって実行前にブロックされます。-
ブロックされたジョブはどうなるか: 自動的には削除(キャンセル)されず、キュー内で
PD(Pending:保留)状態のままホールドされます。この状態では計算ノードの自動起動(オートスケール)も一切トリガーされないため、無駄な VM 課金が発生することはありません。 -
解除・対処する方法:
- 利用者本人が
scancel <JOBID>で一度取り消し、--time=01:00:00以下に修正して再投入する(またはscontrol update JobId=<JOBID> TimeLimit=01:00:00で要求時間を短縮するとそのまま実行待ちに進む)。 - 管理者が特例として長時間実行を許可する場合は、
sudo scontrol update JobId=<JOBID> QOS=highでジョブの QoS を変更するとブロックが解除される。 - ※もしキューに
PDで残すのではなく、sbatchを叩いた瞬間にエラーで弾きたい(投入自体を拒否したい)場合は、パーティション設定やslurm.confのEnforcePartLimits=ALLを組み合わせる運用も可能です。
- 利用者本人が
-
ブロックされたジョブはどうなるか: 自動的には削除(キャンセル)されず、キュー内で
-
待機ジョブの優先順位制御:
PriorityWeightQOS=10000により、sprioでnormalQoS とhighQoS の優先度スコアに明確な差がつき、空きノードがhighQoS のジョブへ優先割り当てされます。 -
ユーザー別の利用実績集計:
sudo sacct -a -X --format=JobID,User,Partition,QOS,Elapsed,Stateを実行することで、誰がどの QoS で何時間クラスタを使用したかを後から正確に集計できます。
4-7. Azure NetApp Files のユーザークォータによる容量制限(TC-07 / Q5)
「特定のユーザーが巨大なデータセットやチェックポイントを置いて共有ストレージをパンクさせるのを防ぎたい」という要件(Q5)は、Azure NetApp Files(ANF)の個人ユーザークォータ(Individual User Quota) で制御します。
07-set-anf-user-quota.sh: ANF ボリュームに対する UID 単位の容量クォータ設定(クリックで展開)
# 07-set-anf-user-quota.sh
# user01 (UID: 20003) に対して 1 GiB (1048576 KiB) のユーザークォータを設定
az netappfiles volume quota-rule create \
-g "$RG" --account-name "$ANF_ACCT" --pool-name "$ANF_POOL" --volume-name "$ANF_VOL" \
-n "quota-user01" -l "$LOCATION" \
--quota-type IndividualUserQuota --quota-target "20003" --quota-size 1048576
Azure Portal 上の vol01 > [クォータ ルール] 画面。UID 20003(user01)に対して 1 GiB (1,048,576 KiB) の個別ユーザークォータ(IndividualUserQuota)が適用されています。
クォータ反映後、Linux クライアント(scheduler)上で quota -s コマンドを実行すると、ANF ボリューム(10.0.253.4:/vol01)側の rquotad から user01 の上限(1024M)と現在の消費量がリアルタイムに取得できることを確認できます。
quota -s によるユーザークォータ上限と消費量追跡の確認コマンド(クリックで展開)
# user01 (UID: 20003) のクォータ上限(1024M)と 800MB ファイル作成時の消費量追跡を確認
sudo -u user01 quota -s
sudo -u user01 dd if=/dev/zero of=/shared/home/user01/test_800m.bin bs=1M count=800
sudo -u user01 quota -s
sudo -u user01 quota -s の実行画面。10.0.253.4:/vol01 の quota / limit が 1024M(1 GiB)として認識されており、800 MB ファイル書き込み(dd)後の再実行では space が 16K から 801M へ増加して ANF 側で UID 単位の消費量が追跡されます。
このように、「計算リソース・ジョブ実行時間のガバナンスは Slurm の QoS」「ホーム領域の容量ガバナンスは ANF のユーザークォータ」 と役割分担することで、OS 側の複雑なクォータ設定を自前で管理することなく安全に共用環境を運用できます。
4-8. GPU SKU の置き換え・複数世代 GPU の混在運用(TC-08 / Q7)
「当初は入手しやすい GPU SKU で始め、後から H100(Standard_NC40ads_H100_v5 / Standard_ND96isr_H100_v5)や A100(Standard_NC24ads_A100_v4)に変更・追加したい」という要件(Q7)に対しては、CycleCloud のクラスタ設定で以下の 2 通りのアプローチが取れます。
CycleCloud の Select a machine type ダイアログで Compute Type: GPU を選択した画面。A100(Standard_NC24ads_A100_v4)や RTX PRO 6000、NVv4 などの各 GPU SKU について、コア数・メモリ・時間単価・クォータ状況・SR-IOV / RDMA 対応可否を一覧比較して選択できます。
-
既存パーティションの VM SKU 差し替え: CycleCloud GUI のクラスタ編集画面(
Required Settings→HPC VM TypeまたはGPU VM Type)で VM サイズを変更して Save し、ヘッドノードでsudo azslurm scaleを実行するだけで、次回起動する計算ノードから新しい GPU SKU に切り替わります。 -
GPU 種類ごとのパーティション分割(推奨): CycleCloud 8 の Slurm テンプレートには最初から
hpc・gpu・htc・dynamicの複数パーティションが用意されています。日常のコードデバッグ・前処理用には汎用 VM や低価格 GPU パーティションを割り当て、本番の大規模学習用には A100 / H100 パーティションを割り当てることで、ユーザーはsbatchの--partition指定を変えるだけで同じ/shared/home/$USER環境のまま複数の GPU 世代を使い分けられます。
5. ハマったポイント・運用上の注意点
今回の実機構築・検証を通じて実際に遭遇したハマりどころと解決策をまとめます。
| # | ハマりどころ・事象 | 原因 | 対処法 |
|---|---|---|---|
| 1 | CycleCloud GUI の Subscriptions > Create が Loading... のまま進まない |
2026年3月31日以降、新規サブネットが既定でプライベートサブネット(defaultOutboundAccess: false)になり、パブリック IP なしの cc-server01 から management.azure.com へ通信できなくなったため |
クラスタ用サブネット(subnet-cluster01)に Azure NAT Gateway をアタッチして ARM API 等へのアウトバウンド通信を明示的に許可する |
| 2 | サブスクリプション登録直後に VM サイズ選択(Choose)を開くと No rows in the current filter で空になる |
サブスクリプション追加直後の約 1〜2 分間は、CycleCloud がバックグラウンドで Azure の全 VM SKU(約 7 万件)と価格情報を DB に同期しているため |
cycle_server.log に Stored 71,431 records of type Azure.MachineType が出力されるまで 1〜2 分待ってからダイアログを開き直す(クォータ 0 の SKU も見たい場合は Hide Unavailable のチェックを外す) |
| 3 |
Network Attached Storage タブで /shared に ANF を設定する際、内蔵 NFS と競合する・またはマウントに失敗する |
① File-system Mount for /shared の Use Builtin NFS にチェックが残っていると内蔵ディスクと競合する② /shared 専用欄の 3 行目は Mount Point ではなく Export Path、4 行目は Mount Options になっている |
File-system Mount for /shared の Use Builtin NFS のチェックを外し、IP Address: 10.0.253.4、Export Path: /vol01、Mount Options: 空欄 に設定する(下部の Additional Filesystem Mount は使わない) |
| 4 |
useradd -u 20001 user01 を実行すると UID 20001 is not unique エラーになる |
CycleCloud が作成するクラスタ管理者ユーザー(azureuser)に最初から UID 20001 が割り当てられているため |
追加の一般ユーザーは 20002 以降の UID を割り当てる(ANF ユーザークォータの --quota-target も実際の UID に合わせる) |
| 5 |
sacctmgr で QoS を設定しても実行時間制限や sprio の優先度差が効かない |
既定では accounting.conf が accounting_storage/none になっており、また site_specific.conf に PriorityWeightQOS が設定されていないため |
slurmdbd(MariaDB)を構成して AccountingStorageEnforce=associations,limits,qos を有効化し、site_specific.conf(末尾改行に注意)へ PriorityType=priority/multifactor と PriorityWeightQOS=10000 を追記して scontrol reconfigure を実行する |
| 6 | NFSv3(hard マウント)上の ANF でバッファード dd によりクォータ上限を超過させるとプロセスが D 状態でハングする |
AlmaLinux 8.10 カーネルのページキャッシュ書き戻し(nfs_file_flush)で NFS3ERR_DQUOT が返った際、hard マウントのリトライ待ちに入り /shared/home 全体の I/O が詰まることがある |
クォータの動作確認には quota -s コマンドを使用する。書き込み上限テストを行う場合は oflag=direct や小さいブロックサイズを使い、万一 .nfs* ロックが残った場合は一時的にクォータ上限を広げて削除する |
| 7 | GPU ジョブ(--gres=gpu:1)投入時に Requested node configuration is not available となる |
CycleCloud の autoscale.json が対象 GPU VM SKU の GPU 枚数(slurm_gpus)を自動解決できていないケースがある |
ヘッドノードの /opt/azurehpc/slurm/autoscale.json の default_resources に対象 VM サイズと slurm_gpus 枚数を明記し、azslurm scale と azslurm buckets で反映を確認する |
| 8 | 検証終了後に課金が継続してしまう | 計算ノードが 0 台でも、CycleCloud サーバー・Slurm ヘッドノード・Windows VDI・Azure Bastion・NAT Gateway・ANF プール(4 TiB)は起動中課金が発生する | デモ・検証期間外は azslurm keep_alive --remove で常時起動を解除し、VM 停止(Deallocate)、および長期中断時は Bastion と ANF ボリューム/プールの削除を実施する |
参考: GPU枚数がSlurmに反映されない場合の autoscale.json 修正手順(クリックで展開)
# Slurm ヘッドノードで root になり autoscale.json をバックアップ・編集
sudo -i
cd /opt/azurehpc/slurm
cp -p autoscale.json autoscale.json.org
# default_resources セクションに使用する GPU VM SKU と GPU 枚数を追記した上でスケール設定を再生成
azslurm scale
azslurm buckets
出典: GitHub - Azure/cyclecloud-slurm: Incorrect number of GPUs
まとめ
- Azure CycleCloud 8 + Slurm + Azure NetApp Files を組み合わせることで、大学・研究機関で求められる「バッチ処理」「JupyterLab による対話操作」「複数ユーザー共用」「QoS による時間・優先度制限」「ANF ユーザークォータによる容量制限」「0 台からのオートスケールと常時起動の併用」を 1 つの閉域クラスタで実現できる。
- Azure Bastion + Windows VDI を組み合わせることで、クラスタ内の全 VM からパブリック IP を排除しつつ、CycleCloud 管理画面や計算ノード上の JupyterLab へ安全にブラウザアクセスできる。
- AlmaLinux 8.10 HPC イメージを採用することで GPU ドライバー導入のオーバーヘッドをなくし、将来の GPU SKU 変更や複数世代 GPU パーティションの混在にも柔軟に対応できる。
参考リンク
- Azure CycleCloud のドキュメント (CycleCloud 8)
- Azure CycleCloud での Slurm の使用
- クラスタの自動スケーリングを構成する (Azure CycleCloud)
- Azure HPC/AI VM イメージ
- Azure での既定のアウトバウンド アクセス (プライベート サブネット既定化)
- Azure NetApp Files の既定および個別のユーザーとグループのクォータについて
- Azure NetApp Files ボリュームの既定および個別のユーザーとグループのクォータを管理する
- GitHub - Azure/cyclecloud-slurm
本記事は GitHub Copilot および Microsoft Foundry を活用して作成されています。内容の正確性については各公式ドキュメントをご確認ください。















