openhpc x slurm x beeGFS環境の構築と検証:slurmマスターのインストール

# はじめに

openhpc版のslurmをインストールする前に、ソースからslurmをインストールして検証していきたいと思います。
これは色んなツールをパッケージ化しているopenhpcを使うとドコでつまずいたのかわかりづらくなるため、単体での検証環境を作っておく方が切り分けしやすいからです。

また私の検証環境では、基本セキュリティはオフにしています。
これも問題がセキュリティなのかそれ以外なのか切り分けるために行っています。

OSS系のツールは依存関係が多いのでドコで問題が発生しているのかは非常に追跡が困難な場合があります。なるべく単体で検証出来るような環境が望ましいです。

## バージョンアップを想定したインストール

slurmももれなくパッケージ化されており、リポジトリからインストール可能になっています。
パッケージからインストールするのは手軽ですが、本番運用に入った場合、依存関係のあるパッケージに不具合があった場合や、全体のアップデート掛けるときに意図せずバージョンが上がるなど問題も多いです。
私がよく陥った罠は、nvidiaドライバ関係が自動アップデートにより破損する事がありました。（ubuntuでよく発生します）

基幹サービスになるものはアップデートを考慮するとソースからコンパイルすることをお勧めします。（安定している場合や、アップデートが頻繁ではないものはパッケージ版でも問題無いです）

もちろんdockerやapptainerを使って基幹サービスをコンテナ化し、検証後入れ替えるやり方もあります。私も当初そのやり方を考えていましたが、docker hubを見る限りあまり流行ってなさげでした。今後今後qiitaでコンテナ化するかも知れませんが今回は以下のやり方で行っています。

```bash
/opt/<パッケージ名>/<バージョン名>
/opt/<パッケージ名>/release # 上記のシンボリックリンク
```

この利点は、新しいバージョンを入れて検証している最中でも本番への影響をなくし、
入れ替える場合もシンボリックリンクの入替のみで対応可能なことと、
新しいバージョンにすることで問題が発生しても、すぐ前の状態に戻せるので、
運用への影響が最小限に出来ます。

ただ本来は、VMware,KVMなどのゲストOSで検証環境を構築し、検証後にゲストOS毎入れ替えるのが一番安全です。その次がdocker/apptainerでしょうか。

##検証環境の前提構成

下記ホストは全て firwwalld,selinxu,guiを停止しています。
拡張リポジトリの```epel-release```も追加済です。

| ホスト名   |   マシンの種類      |  OSの種類        |  サービス   |
|:---------:|:---------------:|:----------------:|:------:|
| beegfs01  | 物理H/W           | rocky linux8.8  |  KVMホスト,NFS,NIS   |
| master01  | KVMゲストOS       | rocky linux8.8  |  slurmctld,slurmdbd |
| slurm02   | KVMゲストOS       | rocky linux8.8  |  slurmd |
| slurm02   | KVMゲストOS       | rocky linux8.8  |  slurmd |
| slurm03   | KVMゲストOS       | rocky linux8.8  |  slurmd |

この記事はmaster01(slurmマスター）のインストールまで記述します。

以後のインストールはこのサイトを参考に行いました。
https://oracle-japan.github.io/ocitutorials/hpc/tech-knowhow/setup-slurm-cluster/


## mungeのインストール

slurmは、ワーカーノードにジョブを分散させる際のセキュリティ機構としてmungeを使っています。slurmをインストールする必要があります。

### mungeインストール前提

・slurm環境下では、uid,gidを統一して置くことが前提です。
・ldap/nisなどで事前にmunge:mungeで作成して置いてください。
　今回は記載していませんが既にNFS,NISが構築されている前提になります。

・mungeのパッケージ版では```munge:munge```でユーザ:グループ作成を強制してくるので
　事前にアカウントとグループはuid/gidを指定して作成して置くことをお勧めします。
・mungeはパッケージ版で入れても問題がありませんが、敢えてソースで今回は入れます。


mungeのソースはgithubにあります。事前にインストール手順やインストールするバージョンは下記サイトから確認した後インストールをお願いします。
https://github.com/dun/munge/wiki/Installation-Guide

インストールするために必要なツール群はを事前に入れます。
```bash
dnf -y install -y git make gcc autoconf automake libtool
dnf -y install bzip2 zlib pkgconf
```
### munge0.5.15のインストール

2024/9/1時点では最新は0.5.16でした。が敢えて一つ前にしています。（練習のため）

```bash

# 事前にgithubサイトで適切なバージョンを調べておいてください。
# 相性の問題もあるので最新が必ずしもベストではないです。
# 最新としては0.5.16が有りますが、今回は敢えて0.5.15にしています。
cd
git clone https://github.com/dun/munge.git
cd munge
# githubで確認したタグを指定してソースコードを入れ替えます
git checkout tags/munge-0.5.15
# 関連するモジュールは`git checkout`だけでは変わらないため、以下のコマンドも実行
git submodule update --init --recursive

./bootstrap
./configure \
     --prefix=/opt/munge/0.5.15 \
     --sysconfdir=/opt/munge/0.5.15/etc \
     --localstatedir=/var \
     --with-runstatedir=/run

# 完全に切り替えるためには、``` /var , /run ```も``` /opt/munge/```以下にした方が
# よいですが、ログ管理が統一化されていないと混乱するので、そのままにしました。

make 
make install
# /opt/munge/releaseにより、今後0.5.16をインストールしてもリンクの切替だけで済む
ln -s /opt/munge/0.5.15 /opt/munge/release

# パッケージ版と違って、munge.serviceはソースからコピーする必要がある。
# そのままコピーでもいいですが、折角なのでmunge.systemd.serviceの中を編集し
# /opt/munge/0.5.15になっている箇所を/opt/munge/releaseに置換してください。
cp /root/munge/src/munge.systemd.service /etc/systemd/system/munge.service
```

```bash:/etc/systemd/system/munge.service
[Unit]
Description=MUNGE authentication service
Documentation=man:munged(8)
Wants=network-online.target
After=network-online.target
After=time-sync.target

[Service]
Type=forking
EnvironmentFile=-/opt/munge/release/etc/sysconfig/munge
ExecStart=/opt/munge/release/sbin/munged $OPTIONS
PIDFile=/var/run/munge/munged.pid
RuntimeDirectory=munge
RuntimeDirectoryMode=0755
User=munge
Group=munge
Restart=on-abort

[Install]
WantedBy=multi-user.target
```

最後に、ログディレクトリの作成や所有者をmungeに変更します

```bash

mkdir /var/log/munge
chown -R munge:munge /var/log/munge
# munge.keyを発行します。slurm01 - 03にはこのキーを配布します。
sudo -u munge /opt/munge/release/sbin/mungekey --verbose
chown -R munge:munge /opt/munge/
systemctl enable --now munge
systemctl status munge

```
エラーがなければ終了です。
ソースからインストールした際のエラーは大概ライブラリリンクのパス、
フォルダ未作成、フォルダ・ファイルの所有権及び権限設定に起因します。

大概は```sysytemctl status munge```で確認出来ますがよく分からないときは
chatgptにそのままエラーを貼り付けると原因と解決方法を教えてくれます。


## そもそもslurmってなんで必要なんでしたっけ？

今更ながらですが、slurmが必要な理由を私なりにお伝えします。
元々昔からサーバーに関しては4 or 8 CPU(1CORE時代)が入っていましたが、
高額なので、民間・大学の研究室では手元にあるワークステーション(1CPU)を複数台数繋げて計算負荷の高い部分だけ分散することでパフォーマンス向上するために必要とされたのがMPIです。
私がMPIを触ったのは1998年前後だった記憶がありますが、当時設定がむちゃくちゃ大変でした。
ネットワークはどこを使うのか（当時からInifiniBandはありました）ホストのハードウェア構成やOS情報をどう確認するかとか、七面倒だった記憶があります。
現在は研究者が研究に専念出来るように、mpiを想定したツールが作られたり、mpi開発者が楽になるようにリソース管理用ライブラリ(mpix)が充実したり、運用管理が楽になるように、mpiプログラム(ジョブ）がどのマシンで動くのか最適なのか設定出来たり、実行を監視、制限するためのツールとしてslurmのようなジョブ管理ソフトが出てきました。

当初はopenmpiのような並列で動かすためにジョブ管理ソフトは使われてましたが、１CPUしか使わずとも、多人数が使用する場合、負荷分散の意味合いでもslurmが使われるようになっています。

## mpixのインストール
では前置きが長くなりましたが、slurmをインストールするときは基本MPIxとOpenMPIはセットだと思ってください（全く必要ないなら、そもそもslurmではなくkubernetesやL7で良いかも）

PMIxをインストールするときも色々関連ツールをインストールします。
```bash
#　一般的なツールはパッケージのままでインストールします。
dnf install -y ncurses-devel openssl-devel gcc-c++ gcc-gfortran

# libeventはgithubを確認し、適切なバージョンを選択してインストールします
git clone https://github.com/libevent/libevent.git
cd libevent/
git checkout tags/release-2.1.12-stable
# 関連するモジュールは`git checkout`だけでは変わらないため、以下のコマンドも実行
git submodule update --init --recursive

./autogen.sh 
./configure --prefix=/opt/libevent/2.1.12
make
make install
ln -s /opt/libevent/2.1.12 /opt/libevent/release

# 同じようにhwlocはなぜかgithub上で管理していなかったのでダウンロードします 

cd
wget https://download.open-mpi.org/release/hwloc/v2.10/hwloc-2.10.0.tar.gz
tar -xvf ./hwloc-2.10.0.tar.gz
cd hwloc-2.10.0/
./configure --prefix=/opt/hwloc/2.10.0
make
make install
ln -s /opt/hwloc/2.10.0 /opt/hwloc/release
```
これでようやくPMIxをインストールする準備が整いました。

```bash
# 最新版は５.台ですが、まだ新しいのでv4.2.9にしています。
# 一般論ですがバージョン番号のx.y.zのｘ(メジャーバージョン)が上がるときは
# 下位バージョンとの互換性が失われるケースがあるため運用に入っている場合は
# 慎重に採用する必要があります。 

git clone https://github.com/openpmix/openpmix.git
cd openpmix/
git checkout tags/v4.2.9
git submodule update --init --recursive
./autogen.pl 
# 先程ソースからインストールしたlibeventとhwlocの場所を指定します。
./configure --prefix=/opt/pmix/4.2.9 --with-libevent=/opt/libevent/release --with-hwloc=/opt/hwloc/release
make 
make install
ln -s /opt/pmix/4.2.9 /opt/pmix/release
```
ここら辺はconfigure,makeでエラーがなければサクサク進んでください。

## openmpiのインストール
```bas
git clone https://github.com/open-mpi/ompi.git
git checkout tags/v5.0.5
git submodule update --init --recursive
./autogen.pl 
./configure --prefix=/opt/openmpi/5.0.5 --with-libevent=/opt/libevent/release --with-hwloc=/opt/hwloc/release --with-pmix=/opt/pmix/release --with-slurm
make
make install
ln -s /opt/openmpi/5.0.5 /opt/openmpi/release
```
インストールが終わった後は、.bashrcにopenmpiのPATHを追加します。
```bash
export PATH=$PATH:/opt/openmpi/release/bin
```

これでようやくslurmのインストールに取りかかれます。

## mariadbのインストール
ですがまだslurmをインストールする前に準備が必要です。
slurmを利用するユーザー、ジョブの種類が様々あるため、どのような使われ方をしているのかを把握し適切な設定にするために分析する必要があります。そのためにDBに記録を残していきます。

mariadbを使っているとmysqlという用語が出てきてて混乱すると思いますがmariadb=mysqlと考えてください。様々な大人の事情で突然ツールの名前が変わるケースがあります。
ややこしいのが、azure,aws,gcp,フリーソフトのどれも同じ物を使っていても、
機能をトッピング、チューニングしたことで全然別製品のような名前にされるので、覚えるこっちのみにもなって欲しいと、たまに恨み節で見ていたりしますが、それは置いて本題に戻ります。


```bash
# DBに関しては枯れた技術なのでそのままパッケージ使ってインストールします。

dnf install -y mariadb-server mariadb-devel

```
```bash:/etc/my.cnf.d/mariadb-server.cnf
#下記を21行目辺りに追記してください
innodb_buffer_pool_size=4096M
innodb_lock_wait_timeout=900
```
一旦これでmariadbサービスを起動します。
```bash
systemctl enable --now mariadb
```
起動後は、slurm用にアカウントとDBを作成します。
パスワードは検証用なのでそのままでもよいですが本番時には変更してください。
またDB:slurm_acct_dbも変更可能です。slurmdbd.confの記述と合わせてください。

```bash
mysql
MariaDB [(none)]> create database slurm_acct_db;
Query OK, 1 row affected (0.000 sec)

MariaDB [(none)]> create user 'slurm'@'localhost' identified by 'slurm';
Query OK, 0 rows affected (0.000 sec)

MariaDB [(none)]> set password for slurm@localhost = password('slurm');
Query OK, 0 rows affected (0.000 sec)

MariaDB [(none)]> grant all on slurm_acct_db.* TO 'slurm'@'localhost';
Query OK, 0 rows affected (0.000 sec)

MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.000 sec)

MariaDB [(none)]> Ctrl-C -- exit!
```

```bash
mysql --user=slurm --password=slurm slurm_acct_db -e 'show databases;'
```

## ucxのインストール
ようやくslurmをインストールするために必要な最後のツールをインストールします。
```bash
git clone https://github.com/openucx/ucx.git
cd ucx/
git checkout tags/v1.17.0
git submodule update --init --recursive
./contrib/configure-release --prefix=/opt/ucx/1.17.0
make
make install
ln -s /opt/ucx/1.17.0 /opt/ucx/release
```

## slurmのインストール

```bash
dnf install -y rpm-build pam-devel perl readline-devel autoconf automake
cd
git clone https://github.com/SchedMD/slurm.git
cd slurm/
git checkout tags/slurm-23-11-10-1
git submodule update --init --recursive

#事前にインストールしていた。PMIxとUCXのパスを指定します。
./configure --prefix=/opt/slurm/23.11.10.1 --sysconfdir=/opt/slurm/23.11.10.1/etc --with-pmix=/opt/pmix/release --with-ucx=/opt/ucx/release --with-munge=/opt/munge/release
make 
make install
ln -s /opt/slurm/23.11.10.1 /opt/slurm/release

#　ソースから設定ファイルをコピーします。
# 設定変更は後ほど行います。
mkdir /opt/slurm/release/etc
cp etc/slurm.conf.example /opt/slurm/release/etc/slurm.conf
cp etc/cgroup.conf.example /opt/slurm/release/etc/cgroup.conf
cp etc/slurmdbd.conf.example /opt/slurm/release/etc/slurmdbd.conf

# 事前に/opt/slurm/23.11.10.1の部分をreleaseに書き換えてからコピーしてください
cp etc/slurmctld.service /etc/systemd/system/
cp etc/slurmdbd.service /etc/systemd/system/

chown -R slurm:slurm /opt/slurm
mkdir /var/spool/slurmctld
chown slurm:slurm /var/spool/slurmctld/
mkdir /var/log/slurm
chown slurm:slurm /var/log/slurm
```

slurmctldを立ち上げる前にslurmdbdを立ち上げる必要があります。
slurmdbdを立ち上げる前にslurmdbd.confの設定を環境に合わせて修正します。

```bash:/opt/slurm/release/etc/slurmdbd.conf
#　大体以下の箇所を修正してください。
# このブログと同じようにしていた場合は下記の設定で問題ありません。
SlurmUser=slurm
LogFile=/var/log/slurm/slurmdbd.log
PidFile=/var/run/slurm/slurmdbd.pid
StorageType=accounting_storage/mysql
StorageHost=localhost
StoragePort=3306
StoragePass=slurm
StorageUser=slurm
StorageLoc=slurm_acct_db
```
```bash
systemctl enable --now slurmdbd
systemctl status slurmdbd
```
これで特段エラーがなければslurmdbdは完了です。
もしこの段階でエラーが起きているとしたら、mariadbのポート番号、dbユーザー名とパスワード、ディレクトリが存在しないか所有者がslurmになっていないかです。

slurm.confはこの段階では細かい設定はしません。まずは機能確認をするための最小限のみ設定します。

```bash:/opt/slurm/release/slurm.conf
SlurmctldHost=master01
SlurmctldLogFile=/var/log/slurm/slurmctld.log
AccountingStorageHost=master01
AccountingStoragePort=7004
AccountingStorageType=accounting_storage/slurmdbd

```

ではslurmctldを起動しましょう。この段階ではワーカーノードがない事や、ジョブの履歴がないことでエラーが出ますが、この段階ではslurmctldが起動することが確認出来たらOKです。
```bash
systemctl start slurmctld
systemctl status slurmctld

#この段階でもsinfoが動くはずです。
sinfo
```
![スクリーンショット 2024-09-01 12.39.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3856269/e6af2b6e-a817-b163-2079-37069409738a.png)

### やり残し
以上でslurmのマスターのインストールは以上になります。
この段階でやり残した事は、
slurmのワーカーノードにまた同じ事をするのは面倒なので、ソースからコンパイルしたファイルをパッケージ化して配布出来るようにするか、ansibleを使って構成するかのどちらかになります。

次回ワーカーノードのインストール前に、上記の方法を掲載してから最後ワーカーノードを行います。

また現時点ではslurm x apptainer/docker x GPU(nvidia rtx4090)のための設定は一切していません。これは後で設定変更した場合のやっかいさ含めて後日記事にします。