さくらのVPSではじめるOpen OnDemand

## Open OnDemandとは
複数の計算機で構成されたクラスタを使う場合、PuTTYなどのターミナルからSSHを使ってそのクラスタにログインし、Slurmなどのジョブスケジューラを介してジョブを投入することが一般的です。しかし、ターミナルのインストール、SSHの鍵管理、ジョブスケジューラの使い方などを勉強する手間は大きいです。

その問題を解決するため、オープンソースソフトウェアである[Open OnDemand](https://openondemand.org)というWebポータルがクラスタで利用されつつあります。ユーザはクラスタ上に構築されたOpen OnDemandのWebサイトにログインすると、GUI操作でクラスタを利用することができます。具体的には、ファイルのアップロード/ダウンロード/編集、リモートデスクトップやJupyterなどの対話型アプリケーションや通常のバッチジョブの投入などを行うことができます。

Open OnDemandの開発は、オハイオ州立大学のスーパーコンピューターセンターで2016年から開始されました[^1]。現在（2023年9月）、250以上の機関でOpen OnDemandが利用されており[^2]、日本では理化学研究所の「富岳」で利用されています[^3][^4]。また、国立情報学研究所の[学認クラウドオンデマンド構築サービス](https://cloud.gakunin.jp/ocs/)を使って東京大学の[データ活用社会創成プラットフォームmdx](https://mdx.jp)上でOpen OnDemandを構築することも可能です[^5]。

## 本記事の目的
Open OnDemandのインストールを行い、リモートデスクトップが動作する設定について説明します。

## 計算機環境
説明を簡単にするため、1台の計算機のみを使います。つまり、Open OnDemandをインストールするサーバと、リモートデスクトップが動作するサーバは同じです。複数の計算機を使いたい場合は、ユーザ認証やNFSの設定が必要になるでしょう。本記事では、さくらインターネットのさくらVPS（Rocky Linux 9.2）を使いますが、それ以外の環境であっても手順は同じはずです。

まず、ポート「22」と「443」を開けてください。さくらインターネットの場合は、VPSコントロールパネルの「パケットフィルター設定」で下記にように設定ください。
![スクリーンショット 2023-09-09 17.11.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43789/dfe1d32c-dfa2-ed78-fcf8-933222ef0e25.png)
## Open OnDemandのインストール
[公式サイト](https://osc.github.io/ood-documentation/latest/installation/install-software.html)の通りにRocky Linux 9用のソフトウェアのインストールを行います。今回、インストールしたOpen OnDemandのバージョンは3.0.1でした。
```
sudo dnf -y config-manager --set-enabled crb
sudo dnf -y install epel-release
sudo dnf -y install https://yum.osc.edu/ondemand/3.0/ondemand-release-web-3.0-1.noarch.rpm
sudo dnf -y install ondemand
sudo systemctl start httpd
sudo systemctl enable httpd
```

## Open OnDemandの認証の設定
Open OnDemandではApache2.4でサポートしている認証を利用できます。詳細は[こちら](https://osc.github.io/ood-documentation/latest/authentication.html)を参照ください。今回は簡単なため[PAM認証](https://osc.github.io/ood-documentation/release-1.8/authentication/pam.html)の設定を行いますが、この認証は推奨されていないことに注意ください。
```
sudo dnf -y install mod_authnz_pam
echo "LoadModule authnz_pam_module modules/mod_authnz_pam.so" | sudo tee /etc/httpd/conf.modules.d/55-authnz_pam.conf
sudo cp /etc/pam.d/sshd /etc/pam.d/ood
sudo chmod 640 /etc/shadow
sudo chgrp apache /etc/shadow
```
`/etc/ood/config/ood_portal.yml`に下記を追記します。
```
auth:
  - 'AuthType Basic'
  - 'AuthName "Open OnDemand"'
  - 'AuthBasicProvider PAM'
  - 'AuthPAMService ood'
  - 'Require valid-user'
# Capture system user name from authenticated user name
user_map_cmd: "/opt/ood/ood_auth_map/bin/ood_auth_map.regex"
node_uri: '/node'
rnode_uri: '/rnode'
```
`/opt/ood/ood_auth_map/bin/ood_auth_map.regex`を下記のように作成します。
```
#!/bin/bash

REX="([^@]+)"
INPUT_USER="$1"

if [[ $INPUT_USER =~ $REX ]]; then
  MATCH="${BASH_REMATCH[1]}"
  echo "$MATCH" | tr '[:upper:]' '[:lower:]'
else
  # can't write to standard out or error, so let's use syslog
  logger -t 'ood-mapping' "cannot map $INPUT_USER"

  # and exit 1
  exit 1
fi
```
実行権限をつけます。
```
sudo chmod +x /opt/ood/ood_auth_map/bin/ood_auth_map.regex
```
Apacheの設定ファイルを自動生成します。
```
sudo /opt/ood/ood-portal-generator/sbin/update_ood_portal
```

## SSL/TLSサーバー証明書
Let's Encryptを使ってSSL/TLSサーバー証明書を生成します。ホスト名を「hoge.sakura.ne.jp」とします。以下、実際のホスト名と置き換えてください。
```
sudo dnf -y install certbot python3-certbot-apache
sudo certbot --apache -d hoge.sakura.ne.jp
(emailアドレスを入力)
Y <-- 入力
Y <-- 入力
```
上で作成した証明書などのPATHを`/etc/ood/config/ood_portal.yml`に記述します。
```
servername: hoge.sakura.ne.jp
ssl:
  - 'SSLCertificateKeyFile "/etc/letsencrypt/live/hoge.sakura.ne.jp/privkey.pem"'
  - 'SSLCertificateFile "/etc/letsencrypt/live/hoge.sakura.ne.jp/fullchain.pem"'
```
もう一度、Apacheの設定ファイルを自動生成します[^6]。
```
sudo /opt/ood/ood-portal-generator/sbin/update_ood_portal
```

この時点で、Webブラウザでhoge.sakura.ne.jpにアクセスすると、ユーザ認証後に、下記のような画面が表示されます。
![スクリーンショット 2023-09-09 14.02.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43789/c3d80bcc-3640-9dc0-6ab5-48d7cdb03785.png)

## クラスタの設定
Open OnDemandで用いるクラスタの設定を行います。クラスタの名前を「tenpozan」とします。
```
sudo mkdir -p /etc/ood/config/clusters.d
```
`/etc/ood/config/clusters.d/tenpozan.yml`を下記のように作成します。
```
---
v2:
  metadata:
    title: "Tenpozan"
  login:
    host: "hoge.sakura.ne.jp"
  job:
    adapter: "slurm"
  batch_connect:
    vnc:
      script_wrapper: |
        export PATH="/opt/TurboVNC/bin:$PATH"
        export WEBSOCKIFY_CMD="/usr/bin/websockify"
        %s
```
## Slurmの設定
ジョブスケジューラであるSlurmの設定を行います。
```
sudo dnf -y install munge 
```

mungeの鍵の作成を行います。下記の一行目の「hoge」は適当な文字列に置き換えてください。

```
echo -n "hoge" | sha1sum | cut -d' ' -f1 | sudo tee /etc/munge/munge.key
sudo chown munge:munge /etc/munge/munge.key
sudo chmod 400 /etc/munge/munge.key
sudo systemctl start munge
sudo systemctl enable munge
```

次にSlurmの設定です。今回は1ノードの設定なので、Slurmサーバとクライアントの両方をインストールします。
```
sudo dnf -y install slurm slurm-slurmctld slurm-slurmd
sudo systemctl start slurmctld
sudo systemctl enable slurmctld
sudo systemctl start slurmd
sudo systemctl enable slurmd
```

ここで`sinfo`コマンドを実行すると、下記のような出力が行われます。
```
sinfo
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
debug*       up   infinite      1   idle localhost
```

## リモートデスクトップの設定
必要なソフトウェアのインストールを行います。
```
sudo dnf -y install https://yum.osc.edu/ondemand/latest/compute/el9Server/x86_64/python3-websockify-0.10.0-1.el9.noarch.rpm
sudo dnf -y install https://yum.osc.edu/ondemand/latest/compute/el9Server/x86_64/turbovnc-2.2.5-1.el9.x86_64.rpm
sudo dnf -y group install Xfce
sudo dnf -y install dbus-x11 python3-numpy
```

Webフォームの設定ファイルである`/var/www/ood/apps/sys/bc_desktop/form.yml`を下記のように編集します。
```
---
attributes:
  bc_vnc_idle: 0
  bc_vnc_resolution:
    required: true
  bc_num_slots: 1
  desktop: "xfce"
  cluster: "tenpozan"

form:
  - bc_num_hours
  - bc_vnc_idle
  - bc_vnc_resolution
  - bc_num_slots
  - desktop
  - cluster
```

以上で設定は完了です。もう一度、Webブラウザでhoge.sakura.ne.jpにアクセスください。Webフォームの変更を反映させるため、ナビゲーションバーから`Restart Web Server`をクリックください。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43789/6dabdbb0-b3a2-c359-b9ab-69ec5ab35581.png" width="350">

## リモートデスクトップの起動
ナビゲーションバーの`Interactive Apps`の`Desktop`をクリックします。
![スクリーンショット 2023-09-09 14.09.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43789/9ae2f528-2504-6535-215f-73059ab1b58b.png)

下記のような画面が表示されるので、そのまま`Launch`をクリックすると、Xfceが起動します。

![スクリーンショット 2023-09-14 21.02.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43789/94e52f89-a3a5-8d63-947d-cedcb0546561.png)
お疲れ様でした。
![スクリーンショット 2023-09-09 17.49.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43789/d6a6d6ed-b82c-cec0-80a9-a32f344c0957.png)

## 補足
以下の設定は必須ではありませんが、メモとして残しておきます。

### SSHホストベース認証
ナビゲーションバーの`Clusters`の`Tenpozan Shell Access`をクリックすると、Webブラウザからターミナルが立ち上がりますが、その際にパスワードの入力が求められます。そのパスワード入力を省略するには、SSHホストベース認証を行う必要があります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43789/0e56d794-4d69-3b2f-5388-62cde1f0ee6f.png" width="350">

`/etc/ssh/ssh_config`に下記を追加します。
```
EnableSSHKeysign yes
HostbasedAuthentication yes
```
`/etc/ssh/sshd_config`に下記を追加します。
```
HostbasedAuthentication yes
UseDNS yes
```

ホスト鍵の登録を行い、最後にsshサーバを再起動させます。
```
ssh-keyscan hoge.sakura.ne.jp | sudo tee /etc/ssh/ssh_known_hosts
echo "hoge.sakura.ne.jp" | sudo tee /etc/hosts.equiv
sudo systemctl restart sshd
```

### SlurmのOverSubscribe
OverSubscribeとは1台の計算機に複数個のジョブを同時に実行する設定のことです。`/etc/slurm/slurm.conf`に下記の設定を行います。
```
#SelectType=select/linear
SelectType=select/cons_tres
SelectTypeParameters=CR_CORE
 :
PartitionName=debug Nodes=ALL Default=YES MaxTime=INFINITE State=UP OverSubscribe=FORCE:8
```
FORCEのコロンの後の数字は、最大同時実行数です。

最後に設定変更を反映させます。
```
sudo systemctl restart slurmctld.service
sudo systemctl restart slurmd.service
```

[^1]:[Dave Hudak et al. ``Open OnDemand: A web-based client portal for HPC centers'', May 2018](https://joss.theoj.org/papers/10.21105/joss.00622)
[^2]: https://openondemand.org/read-our-story
[^3]:[中尾昌広 他．``スーパーコンピュータ「富岳」における HPCクラスタ用WebポータルOpen OnDemandの運用'', 第191回HPC研究会，2023年9月](https://mnakao.net/data/2023/HPC191.pdf)
[^4]:[中尾昌広 他．``スーパーコンピュータ「富岳」における HPCクラスタ用WebポータルOpen OnDemandの導入'', 第186回HPC研究会，2022年9月](https://mnakao.net/data/2022/HPC186.pdf)
[^5]:大江 和一 他．``クラウド環境構築システムVCPによるmdxでのスケーラブルなHPCクラスタの構築'', 第190回HPC研究会，2022年8月
[^6]:`update_ood_portal`は2回実行されている。その理由は、Let's Encryptを使ったSSL/TLS証明書の発行前に`update_ood_portal`を実行しないと、`certbot`コマンドがOpen OnDemand用の設定ファイルを自動生成してしまい、`update_ood_portal`を実行して生成される設定ファイルとの整合性がつかなくなってしまうから。