ここではPCクラスタ用ジョブスケジューラであるSlurm Workload Managerを複数台のUbuntuマシンにインストールして設定する方法を説明します。

マシン環境

命令を下すヘッドノードが1台、受けた命令に従って処理を行う計算ノードが複数台あり、/homeがNFSで全マシン間で共有されていると仮定します。また、全マシンに高速処理用SSD領域が/workとしてマウントされていますが、共有はされていません。

全マシンにおいて、全ユーザーのUIDとGID、グループのGIDは統一されています。通常は、ヘッドノードまたは/homeをNFSで提供するNASにLDAPかActive DirectoryかNISを設定してそうなるようにしますが、ジョブをサブミットするユーザーが固定の環境であれば、全マシンで共通のユーザーを作成するだけでも問題はありません。これらの説明はしません。

外部ネットワークには1Gで接続されていますが、マシン間は10Gで接続されており、ファイアーウォールは10Gネットワークでは無効化されています。

MPIを使用して複数の計算ノード間をまたがって使用する方法や、計算ノードに搭載されたGPUをリソースとして使用する設定方法もここでは扱いませんが、下記の内容を改変することで対応できるので、参考にはなると思います。

事前準備

タイムゾーンとNTPサーバ設定を全マシンで統一します。

sudo timedatectl set-timezone Asia/Tokyo
sudo systemctl status systemd-timesyncd
cat /etc/systemd/timesyncd.conf | perl -npe 's/^\#NTP=/NTP=[NTPサーバ]/;' > timesyncd.conf
sudo cp timesyncd.conf /etc/systemd/timesyncd.conf
sudo systemctl restart systemd-timesyncd
sudo systemctl status systemd-timesyncd
sudo timedatectl timesync-status

全マシンで10Gネットワークではファイアーウォールを無効化します。

sudo apt install ufw
cat /etc/default/ufw | perl -npe 's/^\#?IPV6=.+/IPV6=no/;' > ufw
sudo cp ufw /etc/default/ufw
sudo systemctl restart ufw
sudo ufw allow from [内部10Gサブネット]/24
sudo ufw enable

ヘッドノードでのSlurmインストールと設定

aptでSlurmをインストールします。

sudo apt install slurm-wlm slurmctld slurmd

設定ファイル生成用HTMLを取得します。

cp /usr/share/doc/slurmctld/slurm-wlm-configurator.html .

このslurm-wlm-configurator.htmlをGUIのあるWebブラウザで開き、適宜設定を行います。もしヘッドノードにXやGUIブラウザがない場合は、HTMLを別のPCにコピーしてそちらで開けば問題はありません。下記は私の環境のslurm.confです。

ClusterName=mypccluster
SlurmctldHost=headnode
ProctrackType=proctrack/cgroup
ReturnToService=1
SlurmctldPidFile=/run/slurmctld.pid
SlurmctldPort=6817
SlurmdPidFile=/run/slurmd.pid
SlurmdPort=6818
SlurmdSpoolDir=/var/lib/slurm/slurmd
SlurmUser=slurm
SlurmdUser=root
StateSaveLocation=/var/lib/slurm/slurmctld
TaskPlugin=task/affinity
InactiveLimit=0
KillWait=30
MinJobAge=300
SlurmctldTimeout=120
SlurmdTimeout=300
Waittime=0
SchedulerType=sched/backfill
SelectType=select/cons_tres
SelectTypeParameters=CR_CPU
JobCompType=jobcomp/none
JobAcctGatherFrequency=30
SlurmctldDebug=info
SlurmctldLogFile=/var/log/slurm/slurmctld.log
SlurmdDebug=info
SlurmdLogFile=/var/log/slurm/slurmd.log
NodeName=headnode Sockets=1 CoresPerSocket=16 ThreadsPerCore=2 State=UNKNOWN
NodeName=compnode1 Sockets=1 CoresPerSocket=64 ThreadsPerCore=2 State=UNKNOWN
NodeName=compnode2 Sockets=1 CoresPerSocket=64 ThreadsPerCore=2 State=UNKNOWN
PartitionName=head Nodes=headnode MaxTime=1440 State=UP OverSubscribe=YES
PartitionName=comp Nodes=compnode1,compnode2 Default=YES MaxTime=14400 State=UP OverSubscribe=EXCLUSIVE

SelectTypeParameters=CR_CPUは、論理CPU数(同時実行可能スレッド数)をジョブの消費する資源として扱い、論理CPU数の消費に応じてそのノードでのジョブの実行を制御する指定です。CR_Coreにすれば、物理CPUコア数を資源として扱うようにすることもできます。他にも様々なオプションがあるので、詳細は公式ドキュメントをご参照下さい。OverSubscribe=EXCLUSIVEは、そのパーティションでは資源が余っていても、1ノードで1ジョブしか実行されないようにするオプションです。OverSubscribe=YESであれば、そのパーティションでは資源が余っていれば1ノードで複数ジョブの同時実行を許可します。ただし、これらのオプションの意味はSelectTypeによって異なりますので注意して下さい。OverSubscribeのオプションも他にFORCENOなどがありますので、詳しくは公式ドキュメントを参照して下さい。

slurm.confProctrackType=proctrack/cgroupを選択したので、cgroup.confも必要です。私は下記のようにしました。

CgroupAutomount=yes
CgroupMountpoint="/sys/fs/cgroup"
ConstrainCores=yes
ConstrainDevices=yes
ConstrainRAMSpace=yes

下記のコマンドを実行して、各ファイルを必要な場所に配置して権限を適切に設定します。

sudo cp slurm.conf /etc/slurm/slurm.conf
sudo chown slurm:slurm /etc/slurm/slurm.conf
sudo chmod a+r /etc/slurm/slurm.conf
sudo cp cgroup.conf /etc/slurm/cgroup.conf
sudo chmod a+r /etc/slurm/cgroup.conf
sudo mkdir -p /var/lib/slurm/slurmctld
sudo mkdir -p /var/lib/slurm/slurmd
sudo chown -R slurm:slurm /var/lib/slurm
sudo mkdir -p /var/log/slurm
sudo chown slurm:slurm /var/log/slurm
sudo systemctl enable --now munge slurmctld slurmd

後で計算ノードにいくつかファイルをコピーする必要があるので、共有している/home内にコピーしておきます。

sudo cp /etc/munge/munge.key /home/USER/munge.key
sudo cp /etc/slurm/slurm.conf /home/USER/slurm.conf
sudo cp /etc/slurm/cgroup.conf /home/USER/cgroup.conf

なお、全マシンで互いに10GネットワークのIPアドレスが引けるように、/etc/hostsを編集しておきます。

計算ノードでのSlurmインストールと設定

計算ノードに必要なのはslurmdのみなので、これをインストールします。

sudo apt install slurmd

必要なファイルを必要な場所にコピーして、ファイルやフォルダの権限を適切に設定します。

sudo cp /home/USER/munge.key /etc/munge/munge.key
sudo chown munge:munge /etc/munge/munge.key
sudo chmod 400 /etc/munge/munge.key
sudo cp /home/USER/slurm.conf /etc/slurm/slurm.conf
sudo chown slurm:slurm /etc/slurm/slurm.conf
sudo chmod a+r /etc/slurm/slurm.conf
sudo cp /home/USER/cgroup.conf /etc/slurm/cgroup.conf
sudo chmod a+r /etc/slurm/cgroup.conf
sudo mkdir -p /var/lib/slurm/slurmd
sudo chown -R slurm:slurm /var/lib/slurm
sudo mkdir -p /var/log/slurm
sudo chown slurm:slurm /var/log/slurm
sudo systemctl enable --now munge slurmd

計算ノードでも、全マシンで互いに10GネットワークのIPアドレスが引けるように、/etc/hostsを編集しておきます。

Ubuntuの純正リポジトリのSlurmをインストールした場合、/var/log/slurmに出力されるログファイルはlogrotateされるように/etc/logrotate.dに設定ファイルが登録されていますので、改めて行う必要はありません。圧縮方法や保持数を変えたければ編集して下さい。

また、計算ジョブ内で使用するコマンドとそれらが要求するライブラリは計算ノード上に予めインストールしておく必要がありますので、適宜インストールしておきます。

動作確認

まずはヘッドノードに管理者としてログインして、計算ノードがちゃんと認識されているかチェックします。ついでにデーモンとログも確認します。

sinfo
sudo systemctl status munge
sudo systemctl status slurmctld
sudo systemctl status slurmd
sudo tail -n 20 /var/log/slurm/slurmctld.log
sudo tail -n 20 /var/log/slurm/slurmd.log

計算ノードでもデーモンやログを確認します。

sudo systemctl status munge
sudo systemctl status slurmd
sudo tail -n 20 /var/log/slurm/slurmd.log

ヘッドノードに、ジョブ投入を行うユーザーでログインして、ジョブ投入テスト用のフォルダやファイルを作成し、実際にジョブを投入して様子を見てみます。

mkdir slurmtest
cd slurmtest
echo '#!/bin/sh
#SBATCH --get-user-env
#SBATCH -p comp
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -c 32
#SBATCH -o runlog.txt
homedir=`pwd`
echo $HOSTNAME > runnode.txt
cd /work/$USER
touch tempfile
mkdir tempdir
sleep 60
rm tempfile
rmdir tempdir
cd $homedir
if test $? -eq 0; then
echo "The job finished correctly."
else
echo "The job crashed."
fi' > testjob.sh
for n in `seq 1 2`
do mkdir job$n
cp testjob.sh job$n/job$n.sh
done
for n in `seq 1 2`
do cd job$n
sbatch job$n.sh
cd ..
done
sinfo
squeue
ls -alR

なお、上記の例では、各計算ノードで/work/ユーザー名というフォルダ内で作業を行っているので、予め/work/ユーザー名というフォルダが必要です。所有権やパーミッションも適切に設定されている必要がありますのでご注意願います。/work/ユーザー名がない環境では、cd /work/$USERcd $homedirの行を削除して下さい。

slurmtest/job1およびslurmtest/job2内にrunnode.txtrunlog.txtが生成されていること、内容がおかしくないことを確認します。また、ジョブ実行中のsinfosqueueコマンドの出力も確認しておきます。ジョブ実行前に計算ノードにもログインしておき、ジョブ実行中に/work/ユーザー名tempfiletempdirが生成されているかどうか、ジョブ完了時に削除されているかどうかも見ておくと良いでしょう。