はじめに
Azure 上で High-Performance Computing (HPC) を実装するにあたり、Azure CycleCloud というサービスが存在しています。 これに触れる機会がありましたがなかなかに手こずったため、備忘もかねてまとめておきます。
注意点として、HPC 関連技術に深い理解があるわけではないため、デプロイしてサンプルを動かす、というところまでです。
クラスターテンプレートについてここでは詳しく触れていませんが、別途軽く書きたいとは思っています。
目次
Azure CycleCloud 概要
Azure CycleCloud は、Azure 上で HPC 環境をオーケストレーション・管理するためのツールです。 一般的なスケジューラー (Slurm, PBS Pro など) をデプロイして利用しつつ、Azure におけるクラウドのリソースやオートスケールなどの柔軟性を活用できるようにするためのものです。
CycleCloud が Azure に対する権限を持つことによって、VM や VMSS、ディスク、NIC 等リソースのデプロイや削除を管理してくれます。 また、CycleCloud からクラスターを作成する際に、SSH キーを展開してすべての VM に同じユーザーでログインできるように、などもしてくれます。
勘違いしやすい点として、CycleCloud 自体がスケジューラーとしてジョブを実行するものではありません。CycleCloud はスケジューラーと Azure の橋渡しに相当するイメージです。
ここでは PBS Pro を使ってクラスターを構築してみます。
構成
構成は次の図のとおりです。

VNet に操作用の VM とプライベート エンドポイント付きのストレージ アカウント、Bastionはデプロイした状態です。 環境の都合で、NAT GW も使用しています。
それぞれの役割はこんな感じです。
| ノード | 概要 |
|---|---|
| 操作用 VM | Windows Server 2025。VNet 内への接続用。 |
| CycleCloud | Azure CycleCloud のソフトウェアがインストールされた、根幹となる VM。Marketplace からデプロイ (Ver 8.9) |
| スケジューラー ノード | Slurm や PBS などスケジューラーのヘッド ノード。CycleCloud 経由でデプロイする、スタンドアロン VM。 |
| ログイン ノード | HPC のジョブを実行するために、ユーザーがログインするノード。CycleCloud 経由でデプロイする、VMSS。 |
| 実行ノード | 実際にジョブを処理するノード。CycleCloud 経由でデプロイする、VMSS。 |
| ストレージ アカウント | Blob に "プロジェクト" というファイル群を格納するためのもので、"ロッカー" と呼ばれる。ただし今回は使っていない。 |
ちなみに、CycleCloud の中やドキュメントではノードと言うと単体の VM を指し、ノード アレイ (ノード配列) と言うと VMSS による VM 群を指すところがあります。
Azure ポータルからの操作はほとんどありませんが、こんな感じでデプロイします。
CycleCloud VM のデプロイと初期設定
SSH キーの準備
CycleCloud へのアクセスでは、SSH キーが重要です。 登録した SSH キーを、展開するクラスターの各ノードに登録して、ログインできるようにセットアップしてくれます。
CycleCloud VM 自体へは ID/パスワードでログインすることも可能ですが、初めから SSH キーでアクセスしてしまった方が楽なので、作っておきましょう
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N "" cat ~/.ssh/id_ed25519.pub
公開キーをこの後何度か使います。
CycleCloud VM のデプロイ
Marketplace から CycleCloud を検索し、Azure CycleCloud のデプロイ画面に進みます。

認証は SSH キーにして、先ほどのキーを使います。

加えて、マネージド ID が必要なため、システム割り当てマネージド ID を有効にしておきます。 これも含めて、CycleCloud が稼働するために必要なマネージド ID が二つあり、デプロイ後に設定します。

その他設定してデプロイします。
マネージド ID の設定
CycleCloud では、正常に動作するために次の 2 つのマネージド ID が必要です。
CycleCloud 自身が Azure 環境を操作するためのシステム割り当てマネージド ID
このマネージド ID は、2 つの役割があります。1 つは、CycleCloud で使用するノードやその関連リソースのデプロイ (VM, NIC, ディスク) や、スケール変更のためなどへの利用、もう 1 つは、ロッカー (ストレージ アカウントの Blob) に対する CycleCloud 用のアセットの読み書きへの利用です。CycleCloud 自身が使うのみであるため、システム割り当てで十分です。クラスター ノード用のユーザー割り当てマネージド ID
これは、スケジューラーや実行ノードなど、クラスター内のノードがロッカー内のアセットを入手するためのものです。 クラスター内の不特定多数のノードが利用するため、ユーザー割り当てマネージド ID の方が適しています。
それぞれの役割に応じて、RBAC による権限付与が必要です。 最小権限の方が望ましく、カスタムロールのサンプルも提供されています。
が、ここではシンプルに組み込みロールで次のように設定してしまいます。
| マネージド ID | ロール | スコープ |
|---|---|---|
| CycleCloud VM のシステム割り当てマネージド ID | 共同作成者 | サブスクリプション |
| ストレージ Blob データ共同作成者 | ロッカー用ストレージアカウント | |
| クラスター ノード用のユーザー割り当てマネージド ID | ストレージ Blob データ閲覧者 | ロッカー用ストレージアカウント |
初期設定の中でこれらが必要なため、先に構成しておきます。
CycleCloud VM のマネージド ID

クラスターノード用のマネージド ID

CycleCloud 初期設定
デプロイ後は、CycleCloud のアプリケーションにブラウザ経由で接続し、初期設定を行います。 パブリック IP アドレス経由でもいいですが、ここではプライベート構成にしているので操作用の VM から接続します。
ブラウザから、次の URL に接続します。
https://<CycleCloud VM の IP>
自己署名証明書が使用されているため警告が出ますが、無視して接続します。
CycleCloud の Web UI が開き、初期セットアップ画面が表示されます。
サイト名というのは CycleCloud VM の環境名 (識別子) をつけるようなイメージです。 この CycleCloud VM に関連付いたノードが判別できるようになるもので、任意に名前を付けます。

CycleCloud Web UI 内での管理者ユーザーを作成します。 ここで作成したユーザーは、クラスターノードへのログインユーザーとして自動で登録されます。 そのため、CycleCloud VM に設定した管理者と同じものを使用することでアクセスがシンプルになります。 ということで VM デプロイに使用したものと同じ ID とキーを指定します。

Done から進めると、サブスクリプションの追加画面が表示されるため、使用するサブスクリプションやマネージド ID を指定します。
| 項目 | 設定値 | 概要 |
|---|---|---|
| Subscription Name | 任意 | CycleCloud 内でのサブスクリプション判別名 |
| Set Default | チェックを入れる | このサブスクリプションをデフォルトにするかどうか |
| Marketplace Terms | チェックを入れる | marketplace terms への同意 |
Orchestrator Configuration は、CycleCloud VM 自身に関する設定です。
Managed Identity を指定した状態で Validate Credentials を選択して、"Test succeeded" となれば OK です。
| 項目 | 設定値 | 概要 |
|---|---|---|
| Authentication | Managed Identity | CycleCloud VM の認証方法 |
| Subscription ID | 使用するサブスクリプションの ID | 現在のサブスクリプション ID が自動入力されているので基本そのままで OK のはず |
| Default Location | 使用するリージョン | デフォルトのクラスターデプロイ先 Azure リージョン |
| Resource Group | 新規 or 既存 | クラスターをデプロイしたときに、格納されるリソースグループ名 (デフォルトだとクラスター毎にリソース グループを作成) |

Locker Configuration は、ロッカーとして使用するストレージ アカウントや、認証方法の指定です。
| 項目 | 設定値 | 概要 |
|---|---|---|
| Authentication | Use managed identity for storage access (recommended) | ノードからロッカーへの認証方法 |
| Locker Identity | 作成したユーザー割り当てマネージド ID | リストから使用するマネージド ID を選択 |
| Storage Account | ロッカー用ストレージ アカウント | ロッカーとなるストレージアカウントの選択 |
| Storage Container | 任意 | ロッカー用 Blob コンテナー名 (事前作成は不要) |

全部できたら save して、初期設定の完了です。

CycleCloud CLI の設定
CycleCloud には、コマンドで操作を行うための CycleCloud CLI というツールもあります。
Web UI からクラスターをデプロイするだけならこのまま実行できるので必須ではないのですが、後のテンプレートを編集してなんやかんやするのであればほしいので、設定しておくとよいかなと思います。 ただ、この記事の中の操作では使ってはいないです。
CycleCloud Web UI の右上の "?" マークからダウンロードして任意のマシンにインストールできますが、これも初期設定が必要です。 CycleCloud VM 自体には初めからインストールされているため、ここではそれを用いて初期設定します。
CycleCloud VM に、設定したユーザーで接続します。

次のコマンドで、初期設定を行います。
cyclecloud initialize
| 項目 | 設定値 | 概要 |
|---|---|---|
| CycleServer URL | https://xxxx | CLI の接続先となる CycleCloud VM (ここではローカルなので設定せずデフォルト、別マシンからの接続ならホスト名とか IP アドレスとか) |
| CycleServer username | Web UI 初期セットアップで作成したユーザー | CLI での接続に使用するユーザー |
| CycleServer password | 上記ユーザーのパスワード | CLI での接続に使用するユーザーのパスワード |
これで設定完了です。
試しに、ロッカーを表示してみましょう
cyclecloud locker list
一連の流れはこんな感じになっています。

クラスターのデプロイ
では、初期設定が済んだためクラスターを作成してみます。
ロッカーの設定などしましたが、実は以降の方法では特にロッカーに何も配置せずにクラスターをデプロイしています。 次回、クラスター テンプレートについて書くときに触れようと思います。
Web UI で "Back to clusters" や右上の "クラスター" ボタン、左上の "Azure CycleCloud" などをクリックするとクラスター画面が開きます。 ここで展開しているクラスターを管理します。
今回は OpenPBS でデプロイするので、"OpenPBS" を選択します。

クラスター名を付けます。

以降はクラスターに対する個別設定です。
Required Settings
展開するスケジューラー ノードとログイン ノード (Server VM Type)、実行ノード (Execute VM Type) の VM サイズやリージョン、オートスケールの有無、監視方法などを設定します。
Low Priority というのは Azure のスポット VM の設定です。
サブネットは、実行ノード展開用のサブネットを指定します。

Network Attached Storage
名前のとおり、NAS の設定です。
Scheduler Mount では、外部のスケジューラを使うかどうかの選択をします。 デフォルト (チェックを入れない) の場合、スケジューラー ノードが管理する共有ディレクトリ (ジョブスクリプトやスケジューラー設定ファイルを配置する場所) として /sched が用意され、 すべてのノードに対して /sched としてマウントされます。
Default NFS Share では、ユーザーのホームディレクトリを含む共有ストレージを指定します。 全ノードからアクセスできるため、ジョブの入出力データ配置などで利用します。 Builtin だとスケジューラー ノードが NFS サーバーとして使われますが、External NFS にすることで、Azure NetApp Files など別の NFS サーバー指定も可能です。
Additional NFS Mount は、上記以外の追加の NFS マウントが必要な場合に設定します。
ここでは何も変更していません。

Advanced Settings
資格情報や OS などの設定です。
Azure Settings では、Credentials として作成したサブスクリプション、Managed ID として作成したユーザー割り当てマネージド ID を指定します。
BootDiskSize は、イメージサイズのままの OS ディスクサイズでよければ 0 で OK です。
| 項目 | 設定値 | 概要 |
|---|---|---|
| Credentials | 登録済みサブスクリプション | CycleCloud に登録した Azure サブスクリプション |
| Managed Id | cc-locker-identity | クラスターノードに割り当てる User-Assigned MI (ロッカーアクセス用) |
| BootDiskSize | 0 (デフォルト) | OS ディスクサイズ (GB)。0 はイメージのデフォルトサイズを使用 |
Software では、Scheduler OS (スケジューラー ノード)、Compute OS (実行ノード) の OS の種類やカスタムイメージの利用有無、デプロイする PBS のバージョンなどを選択します。
ここではデフォルトの Alma Linux 8 で進めますが、実際の環境ではカスタムイメージを作成して使用することもあるでしょう。
その際は用途ごとに個別にカスタムしたイメージを使うのではなく、共通部分のカスタムにとどめたイメージを用意し、後述の Cluster-init で細かいところを構成するのがよいです。 ロッカー内の所定の場所にデプロイ後の構成用スクリプトを配置し、ノード起動後に実行することで設定を流し込むことができます。 CycleCloud を使う上で非常に重要な機能です。
ログイン ノードの台数は、クラスターの操作時にログインしてジョブ実行などを行う用のサーバーの台数です。 必須なわけではありませんが、ここでは 1 台デプロイしてみます。
| 項目 | 設定値 | 概要 |
|---|---|---|
| Scheduler OS | Alma Linux 8 | Scheduler ノードの OS イメージ (HPC 最適化済み) |
| Compute OS | Alma Linux 8 | Execute ノードの OS イメージ (HPC 最適化済み) |
| PBS Version | OpenPBS v20, el8-only | OpenPBS のバージョン |
| Server Cluster-Init | (なし) | Scheduler ノード起動時に実行するカスタムスクリプト (Locker から取得) |
| Execute Cluster-Init | (なし) | Execute ノード起動時に実行するカスタムスクリプト |
| Num Login Nodes | 1 | 別途ログインノードを作成する場合の台数 |
Node Health Checks は、正常性チェックの設定です。クラスターへの追加前に異常をチェックしてくれます。
| 項目 | 設定値 | 概要 |
|---|---|---|
| Enable NHC tests | 任意 | ノード起動時にヘルスチェック (GPU エラーやネットワーク不具合の検出) を実行するか |
Advanced Networking は、NW 関連の設定です。 CycleCloud VM とノードは通信が必要ですが、間に FW などがあり直接の通信ができない場合に SSH トンネルを利用して接続します。今回は不要です。
Public Head Node は、スケジューラー ノードにパブリック IP を持たせて外部から接続可能にするかどうかです。今回は不要です。
| 項目 | 設定値 | 概要 |
|---|---|---|
| Return Proxy | チェックを入れない | クラスターノードが CycleCloud サーバーと通信する際、Scheduler ノード経由の SSH トンネルを使用する。ノードから CycleCloud へ直接通信できない場合に必須 |
| Public Head Node | チェックを入れない | Scheduler ノードにパブリック IP を付与してインターネットからアクセス可能にするか |
このあたりは全体的に環境や設計構想によるところが大きいため、任意に設定します。

Virtual Machines
ここでは、VMSS のアップグレード ポリシーを指定します。 役割別に指定することも、全種一括の指定もできます。

Security
ここでは Trusted Launch や Azure Disk Encryption、ホスト暗号化の設定ができます。
ADE はリタイアが決定しているため、暗号化するのであればホスト暗号化を利用しましょう。

Cloud-init
最後は Cloud-init です。
これは、クラスターを展開して VM の起動時に、記載された設定を実行するものです。 Cloud-init と Cluster-init の違いは、実行のタイミングによるものです。
Cloud-init は VM が起動してすぐ、CycleCloud による関連ソフトウェアインストールが行われる前に実行されます。 そのため、OS 自体の設定には利用できますが、スケジューラーなどのインストールが前提となる設定には利用できません。
Cluster-init は VM が起動して、CycleCloud によってスケジューラーなど必要なソフトウェアのインストールが完了した後に実行されます。 従って、スケジューラーに対する設定などは Cluster-init を用いる必要があります。

これで、デフォルトで見えている設定はすべてできました。 変な言い方をしているのは、クラスターテンプレートを利用すると、このクラスター設定画面がいろいろカスタマイズできるからです。 デフォルト値はもちろん、表示する設定項目やタイトル、入力欄かドロップダウンかなどこの設定画面全体をカスタマイズできますが、それは別の機会に。
右下の Save を押すことでクラスターの構成として保存されます。

クラスターの操作
クラスターに対して "Start" を選択すると、クラスターが起動して必要なノードがデプロイされます。
"Edit" からは先ほどの設定を変更することもできます。 "Access" からクラスター内のノードに展開するユーザーを追加することも可能ですが、追加する前には Web UI の歯車 - Users から、ユーザーとして登録しておく必要があります。


設定によりますが、Azure 上では新たなリソース グループが作成され、その中にクラスター内の各ロールの VM、VMSS がデプロイされています。

エラーが出た場合は、ノードアレイの選択 - ノードの選択 (ダブルクリック) とブレイクダウンしていくとログが確認できます。 展開時はタイミングの問題などもあり、エラーと表示されてもすぐに解決されることも多々あるので、焦らずリトライを見守って Refresh ボタンで更新しましょう。 次の 2 つとも、エラー表示にはなっていますが待っているだけで解消しました。



うまくいくとこのように緑の Status になります。これでクラスターが起動しました。 デフォルトでは、VM のホスト名は IP アドレスが 16 進数に変換された値になっています。 (ip-0A000105 = 10.0.1.5)

上部の "Actions" を選択するとノードアレイ全体に対して、下部の "Actions" を選択すると個別のノードに対して操作を実行できます。

| 操作 | 概要 |
|---|---|
| Add | クラスターへのノード追加。後から 1 台追加なども可能だが、クラスターの初期状態としては設定画面の指定台数が反映されているため、恒久的な変更であれば Edit から。 |
| Remove | クラスターからのノード削除 |
| Shut Down | ノードの停止。デフォルトでは、Terminate = VM 関連リソース丸ごと削除だが、Deallocate = 割り当て解除も可能。 |
| Reimage | ノードの OS ディスクを元のイメージから再作成する。 |
| Restart | ノードの再起動 |
Shut Down 選択後の画面はこんな感じです。

さて、ここで画面上にはログイン ノードとスケジューラー ノードの 2 つしか起動しておらず、実行ノードは起動していません。 これは、デフォルトではジョブを実行した際に必要に応じてデプロイ、起動するようになっているためです。
まずは、ジョブ投入を試してみましょう。
ジョブの実行テスト
Web UI でログイン ノードを選択し、"Connect" を選択することで接続用の情報が表示されます。 これでログイン ノードに接続します。 そのまま ccadmin で接続できるのは、CycleCloud が最初に作成したユーザーを管理者として各マシンに SSH キーを展開してくれているからですね。


ここではとても簡単なスクリプトでテストします。 ログイン ノード上で、以下の内容で demo.sh を作成します。
#!/bin/bash echo "CycleCloud + PBS Demo" sleep 300
実行に使うのは qsub コマンドで、使用するノードの数や実行ノードの種類、CPU などをオプションで指定できます。
例えば、-l select=2 で 2 ノード使用を指定したり、slot_type=execute でジョブを実行するノードアレイを指定したりできます。
1 つのクラスターの中で、用途に応じて VM サイズを変えて複数のノードアレイを展開することもできるため、その際に指定することが可能です。
次のコマンドを実行して、ジョブを開始します。
qsub -l select=2 demo.sh

ジョブのステータスは次のコマンドで確認できます。
watch qstat -ans
S がステータスで、Q はインキューの状態です。
間違えて同じジョブを 2 回実行したので 2 つ表示されています…

ここで Web UI を見てみると、実行ノードがデプロイされていることがわかります。 2 ノードしてのジョブが 2 つあるので、2 * 2 で 4 台デプロイされています。

Azure ポータルでは、VMSS 内で 4 台デプロイされています。

ノードが起動したため、ジョブが実行状態の R になりました。

ジョブが終了しました。

ジョブの終了後、実行ノードは待機状態に入ります。 この状態で 5 分経過すると、自動的に Terminate されます。

実行ノードが削除された状態に戻りました。

これで、ジョブの実行ができました。
このように、ジョブを実行すると必要な実行ノードがデプロイされ、実行が終わって不要になると削除されます。 都度デプロイして各種 init による設定をしてからのジョブ実行になるため準備時間はかかりますが、コスト的には抑えられます。
一方で、準備時間を抑えたい場合にはデフォルトの動作を Deallocate にして起動時間のみにすることもできます。 その辺りはクラスターテンプレートで設定するのがいいかなと。
クラスターの停止
最後に、クラスターの停止です。 もちろん起動し続けたままでも問題ありませんが、クラスター丸ごと停止することでログイン ノード、スケジューラー ノードも Terminate して料金を抑えることができます。
Web UI から Terminate を実行してみます。確認画面で OK を選択します。

数分で、完全に Terminate されました。


Azure ポータルでは、クラスター用のリソース グループの中に、スケジューラー ノード用の OS ディスクだけが残されている状態です。

これは、デフォルトでスケジューラー ノードの Persistent 設定が有効になっており、OS ディスクは保持されるようになっているからです。 これにより、スケジューラー ノードの設定やジョブの履歴は保持されています。
再度 "Start" すれば、またスケジューラー ノードとログイン ノードが起動してきますし、"Edit" から設定や台数を変えて起動することも可能です。
冒頭で記載したとおり、クラスター テンプレートとプロジェクトをアップロードして~ まで書きたいとは思っていますが、今回はここまでにします。
終わりに
今回は、Azure CycleCloud で PBS Pro のクラスター起動、テストまで実行しました。
HPC のために大規模なコンピューティング リソースやストレージが必要になる部分を、スケジューラーと Azure (API) の間に Azure CycleCloud が入ることで橋渡しし、 クラウドのオートスケーリングや柔軟性を活用しよう、というのが Azure CycleCloud のコンセプトという理解です。
監視や分析など自動的に実施してくれる部分もありますが、PaaS というよりは IaaS に近いものだと思うので、 Cloud-init や Cluster-init での構成は自身で用意する必要がありますし、そこがセットアップの肝になるかと思います。
ここでは組み込みの PBS Pro をデプロイしたのみですが、クラスター テンプレートを用いればより細かいカスタマイズが可能です。 これを編集することで、クラスター作成時の GUI 画面にどの項目を入れるか、デフォルト値を何にするかなどいろいろ変更できます。
ただ、宣言型相当のテンプレートを編集する必要があるので、その辺はちょっとしたハードルがあります。
期間が空いてしまうかもしれませんが、何かしら書きたいとは思っています。