はじめに
こんにちは、(株)日立製作所 研究開発グループ サービスコンピューティング研究部の露木です。
多人数で効率的に機械学習・AIの学習処理や,HPCライクな数値実験をしたければジョブスケジューラは必須といえます。表題の通り,本記事ではジョブスケジューラの一種であるPBSProをインストールして,GPUを利用した計算ジョブをnvidia-dockerで実行可能にする手順を前後編に分けて示します。
前編である今回は,CPUを利用したジョブを実行可能にするまでの手順を解説します。後編では,GPU利用に関する部分を解説します。
なお,同じアドベントカレンダーにSlurm HPCクラスタとKubernetesを同居させてみた(前編) - Qiita があり,こちらもHPC向けジョブスケジューラの話題になります。PBSは歴史のある枯れたジョブスケジューラですが,SlurmやKubernetesのような新しい技術に興味のある方はぜひ,そちらの記事もご覧ください。
本記事で目指す構成
本記事では図のようにPBSProの管理ノードと計算ノードのシンプルな2台構成を目指します。
+------------+ +------------+
| 管理ノード | --- | 計算ノード |
+------------+ +------------+
それぞれのノードの詳細は下記の通りです。
-
管理ノードの構成
- ホスト名: miso
- IPアドレス: 192.168.1.2
- GPU: 2本
- 計算ノードとしての役割も兼用させる
-
計算ノードの構成
- ホスト名: sio
- IPアドレス: 192.168.1.3
- GPU: 3本
前提環境
管理ノードと計算ノードには下記の環境が整っていることを前提とします。その上で,PBSProをインストールする手順を次節以後に説明していきます。
- OS (Ubuntu 18.04) はインストール済み
- Docker と nvidia-docker 2.0をインストール済み
- 管理ノードと計算ノードの
/home
ディレクトリはNFSで共有済み
PBSProパッケージのコンパイル
まず,PBSProのインストール用パッケージ (rpm, debファイル) をコンパイルします。コンパイル環境として,以下の内容でDockerfileを作成します。
FROM ubuntu:bionic
MAINTAINER tsuyuki
ARG DEBIAN_FRONTEND="noninteractive"
RUN apt update && apt upgrade -y \
&& apt install -y git make python tar wget
WORKDIR /root
RUN wget https://github.com/PBSPro/pbspro/releases/download/v19.1.2/pbspro-19.1.2.tar.gz
RUN tar xzf pbspro-19.1.2.tar.gz
WORKDIR /root/pbspro-19.1.2/
RUN apt install debhelper build-essential autotools-dev gcc automake autoconf comerr-dev libhwloc-dev libx11-dev x11proto-core-dev libxt-dev libedit-dev libical-dev libncurses-dev perl libpq-dev libpython2.7-minimal:amd64 libpython2.7-dev tcl-dev tk-dev swig dpkg-dev libexpat-dev libssl-dev zlib1g-dev:amd64 libxt-dev:amd64 libxext-dev libxft-dev dh-make debhelper devscripts fakeroot xutils lintian -y
RUN bash ./autogen.sh
RUN bash ./configure
RUN make dist
# build rpm
RUN apt install -y rpm alien
RUN mkdir -p /root/rpmbuild
WORKDIR /root/rpmbuild
RUN mkdir BUILD BUILDROOT RPMS SOURCES SPECS SRPMS
RUN cp /root/pbspro-19.1.2/pbspro*tar.gz /root/rpmbuild/SOURCES
RUN cp /root/pbspro-19.1.2/pbspro.spec /root/rpmbuild/SPECS
WORKDIR /root/rpmbuild/SPECS
RUN rpmbuild -ba --nodeps pbspro.spec
WORKDIR /root/rpmbuild/RPMS/x86_64
# convert rpm to deb
RUN alien --to-deb --scripts *.rpm
下記コマンドを実行し,Dockerコンテナの中でPBSProをコンパイルします。
docker build -t pbsbuild:19.1.2 .
UbuntuやDebianにインストールする場合
debファイルをカレントディレクトリにコピーするため,下記コマンドを実行します。
docker run --rm -it -v `pwd`:/host pbsbuild:19.1.2 bash -c "cp pbs*.deb /host"
正しくコピーできていれば,debファイルがコンテナホスト側に保存されています。
$ ls *.deb
pbspro-client_19.1.2-0_amd64.deb
pbspro-devel_19.1.2-0_amd64.deb
pbspro-execution_19.1.2-0_amd64.deb
pbspro-server_19.1.2-0_amd64.deb
pbspro_19.1.2-0_amd64.deb
[オプション] CentOSやRHLにインストールする場合
Ubuntuにインストールする場合は不要ですが,下記コマンドでrpmファイルを取得することもできます。もし,CentOSやRedHat Enterprise Linux などに PBSPro をインストールしたい場合は,このrpmファイルを利用したうえで以後のコマンドを適宜読み替えながら進めてください。
docker run --rm -it -v `pwd`:/host pbsbuild:19.1.2 bash -c "cp pbs*.rpm /host"
PBSProのインストールと設定
コンパイルしたパッケージを利用してPBSProをインストールし,設定していきます。なお, 開発元の PBS Works Documentation にはすべての情報がまとまっています。本稿でわからないことがあったら,開発元のドキュメントを参照するとスムーズに問題解決できるはずです。
管理ノードのインストールと設定
まず,管理ノードに必要な依存パッケージ (PostgreSQL) をインストールします。
sudo apt install postgresql libpq-dev
次に,コンパイルしておいたPBSProを下記コマンドでインストールします。なお,<pbsproのバージョン>
は適宜読み替えてください。もし,ここで依存関係のエラーがでた場合は sudo apt install -f
コマンドの実行で解決できます。
sudo dpkg -i pbspro-server_<pbsproのバージョン>_amd64.deb
ジョブ実行時の環境変数にタイムゾーンを追加します。
sudo bash -c 'echo TZ=\"Asia/Tokyo\" >> /var/spool/pbs/pbs_environment'
/etc/pbs.conf
を編集し,下記の2点を変更します。
-
PBS_SERVER=miso
に変更 (管理ノードのホスト名を記入する) -
PBS_START_MOM=1
に変更 (管理ノードへのジョブ投入を許可する設定)
変更後の /etc/pbs.conf
は以下のようになります。
PBS_EXEC=/opt/pbs
PBS_SERVER=miso
PBS_START_SERVER=1
PBS_START_SCHED=1
PBS_START_COMM=1
PBS_START_MOM=1
PBS_HOME=/var/spool/pbs
PBS_CORE_LIMIT=unlimited
PBS_SCP=/usr/bin/scp
/var/spool/pbs/mom_priv/config
に $usecp *:/home/ /home/
の記載を追加します。今回は/home
ディレクトリ以下をNFSで共有するため,scpではなくcpコマンドでジョブ実行結果をコピーするように$usecp
オプションを指定しています。設定変更後の/var/spool/pbs/mom_priv/config
の中身は以下のようになります。
$clienthost miso
$restrict_user_maxsysid 999
$usecp *:/home/ /home/
なお,計算ノードと管理ノードの/home
ディレクトリをNFSで共有していない場合は,$usecp
の設定は不要ですい。この場合,scpコマンドでジョブ実行結果をコピーすることになるので,計算ノードと管理ノードの間はパスワードなしでsshログインできるように設定しておく必要があります (具体的にはパスフレーズなしの証明書を設定するなど)。
次に,/etc/hosts
を変更し,管理ノード miso
と計算ノード sio
の名前解決を可能にします。ここでは,自ホストもNICに割り当てられたIPアドレス 192.168.1.2
に解決できるように指定する必要がります。デフォルトの 127.0.0.1
ではpbs_momは起動しません。
192.168.1.2 miso
192.168.1.3 sio
127.0.0.1 localhost
# 127.0.1.1 miso
ここまで設定ができたら,PBSProの各種daemonを起動します。
sudo /etc/init.d/pbs start
daemonの起動は,以下のコマンドで確認できます。
$ sudo /etc/init.d/pbs status
pbs_server is pid 18909
pbs_mom is pid 18721
pbs_sched is pid 18733
pbs_comm is 18689
もし,ここで4つのdaemonが起動していなければ障害対応が必要です。下記のディレクトリにある,PBSの動作ログを見ると,起動しない原因がわかると思います。
- /var/spool/pbs/server_logs/
- /var/spool/pbs/mom_logs/
- /var/spool/pbs/sched_logs/
- /var/spool/pbs/comm_logs/
正しく4つのdaemonが起動していたら,次は管理ノード自体を計算ノードとして登録します。
sudo /opt/pbs/bin/qmgr -c "create node miso"
ジョブを流すキューを作成するため,下記のコマンドを実行します。細かい設定は PBS Works Documentation を見ながらお好みに合わせて設定してください。
sudo /opt/pbs/bin/qmgr -c "create queue batch queue_type=execution"
sudo /opt/pbs/bin/qmgr -c "set queue batch enabled=True"
sudo /opt/pbs/bin/qmgr -c "set queue batch resources_default.nodes=1"
sudo /opt/pbs/bin/qmgr -c "set queue batch resources_default.walltime=360000"
sudo /opt/pbs/bin/qmgr -c "set queue batch started=True"
sudo /opt/pbs/bin/qmgr -c "set server acl_hosts = "`hostname`
sudo /opt/pbs/bin/qmgr -c "set server default_queue = batch"
sudo /opt/pbs/bin/qmgr -c "set server scheduling = True"
sudo /opt/pbs/bin/qmgr -c 'set server node_pack = True'
# 他ユーザのジョブもqstatで見えるようにする
sudo /opt/pbs/bin/qmgr -c "set server query_other_jobs = True"
# 管理ノード以外からもジョブ投入を許可する
sudo /opt/pbs/bin/qmgr -c "set server flatuid = True"
下記コマンドで登録済みの計算ノード一覧を確認します。ここまでの設定では管理ノード miso
が計算ノードとしても認識されていることがわかるはずです。
$ pbsnodes -a
miso
Mom = miso
ntype = PBS
state = free
pcpus = 8
resources_available.arch = linux
resources_available.host = miso
resources_available.mem = 32803912kb
resources_available.ncpus = 8
resources_available.vnode = miso
resources_assigned.accelerator_memory = 0kb
resources_assigned.hbmem = 0kb
resources_assigned.mem = 0kb
resources_assigned.naccelerators = 0
resources_assigned.ncpus = 0
resources_assigned.vmem = 0kb
resv_enable = True
sharing = default_shared
last_state_change_time = Tue Aug 6 18:57:38 2019
今後,管理ノードからジョブ投入や計算ノードの死活管理をします。PBSProのコマンド群をパスに追加しておくと便利です。
export PAHT=$PATH:/opt/pbs/bin/
動作確認のためにジョブを投入してみます。
echo "sleep 60; echo done" | qsub
qstatコマンドでジョブの状態を確認すると,正しくジョブが登録されていることがわかります。
$ qstat
Job id Name User Time Use S Queue
---------------- ---------------- ---------------- -------- - -----
1.miso STDIN tsuyuki 00:00:00 R batch
今回は sleep 60
を実行するジョブなので1分立つとジョブが終わります。
ジョブの実行結果としてカレントディレクトリにstdoutとstderrが保存されます。
$ qstat
$ ls
STDIN.e1
STDIN.o1
$ cat STDIN.o1
done
計算ノードのインストールと設定
次に,計算ノードsio
を追加します。計算ノードにSSHでログインしてから下記コマンドを実行し,計算ノード用のパッケージをインストールします。ただし,<pbsproのバージョン>
は適宜読み替えてください。
sudo dpkg -i pbspro-execution_<pbsproのバージョン>_amd64.deb
このとき,依存関係のエラーが出たら場合は下記コマンドの実行で解決できます。
sudo apt install -f
計算ノードの /etc/pbs.conf
を変更します。具体的な変更点は下記の1点のみです。
-
PBS_SERVER=miso
に変更 (管理ノードのホスト名を記入)
変更後の /etc/pbs.conf
は以下のようになります。
PBS_EXEC=/opt/pbs
PBS_SERVER=miso
PBS_START_SERVER=0
PBS_START_SCHED=0
PBS_START_COMM=0
PBS_START_MOM=1
PBS_HOME=/var/spool/pbs
PBS_CORE_LIMIT=unlimited
PBS_SCP=/usr/bin/scp
計算ノードの /var/spool/pbs/mom_priv/config
に下記の2点の変更を加えます。
-
$clienthost miso
の記載に変更 (管理ノードのホスト名を記入) -
$usecp *:/home/ /home/
の記載を追加- 今回は
/home
ディレクトリ以下をNFSで共有するため,scpではなくcpコマンドで実行結果をコピーする設定
- 今回は
設定変更後の/var/spool/pbs/mom_priv/config
の中身は以下のようになります。
$clienthost miso
$restrict_user_maxsysid 999
$usecp *:/home/ /home/
なお,計算ノードと管理ノードの/home
ディレクトリをNFSで共有しない場合は,$usecp
の設定は不要です。この場合,scpでジョブ実行結果をコピーすることになるので,計算ノードと管理ノードの間はパスワードなしでsshログインできるように設定しておく必要があります (具体的にはパスフレーズなしの証明書を設定するなど)。
次に,計算ノードでも管理ノードのホスト名 miso
と計算ノードのホスト名 sio
を名前解決できるように /etc/hosts
に書き込みます。
192.168.1.2 miso
192.168.1.3 sio
タイムゾーンをジョブ実行時の環境変数に追加します。
sudo bash -c 'echo TZ=\"Asia/Tokyo\" >> /var/spool/pbs/pbs_environment'
PBSProのdaemonを起動します。
sudo /etc/init.d/pbs start
PBSProのdaemon起動を確認します。計算ノードではpbs_momのみが動作していればOKです。
$ sudo /etc/init.d/pbs status
pbs_mom is pid 29095
計算ノードsio
を追加登録させるため,管理ノードにSSHでログインして下記コマンドを実行します。
sudo /opt/pbs/bin/qmgr -c "create node sio"
ここまで設定すると,下記のように計算ノードが増えていることがわかります。
$ pbsnodes -a
miso
Mom = miso
ntype = PBS
state = free
pcpus = 8
resources_available.arch = linux
resources_available.host = miso
resources_available.mem = 32803912kb
resources_available.ncpus = 8
resources_available.vnode = miso
resources_assigned.accelerator_memory = 0kb
resources_assigned.hbmem = 0kb
resources_assigned.mem = 0kb
resources_assigned.naccelerators = 0
resources_assigned.ncpus = 0
resources_assigned.vmem = 0kb
resv_enable = True
sharing = default_shared
last_state_change_time = Tue Aug 6 20:33:19 2019
last_used_time = Tue Aug 6 19:16:10 2019
sio
Mom = sio
ntype = PBS
state = free
pcpus = 48
resources_available.arch = linux
resources_available.host = sio
resources_available.mem = 198036808kb
resources_available.ncpus = 48
resources_available.vnode = sio
resources_assigned.accelerator_memory = 0kb
resources_assigned.hbmem = 0kb
resources_assigned.mem = 0kb
resources_assigned.naccelerators = 0
resources_assigned.ncpus = 0
resources_assigned.vmem = 0kb
resv_enable = True
sharing = default_shared
last_state_change_time = Tue Aug 6 20:33:19 2019
新しい計算ノードにジョブが流れるか,動作確認のためにノード名を指定してジョブを投入します。
echo "sleep 60; hostname; echo done" | qsub -l select=host=miso
echo "sleep 60; hostname; echo done" | qsub -l select=host=sio
ジョブ投入結果を確認します。misoとsioに1つずつのジョブが流れている事がわかります。
$ qstat -s
miso:
Req'd Req'd Elap
Job ID Username Queue Jobname SessID NDS TSK Memory Time S Time
--------------- -------- -------- ---------- ------ --- --- ------ ----- - -----
714.miso tsuyuki batch STDIN 27878 1 1 -- 100:0 R 00:00
Job run at Tue Aug 06 at 15:47 on (miso:ncpus=1)
715.miso tsuyuki batch STDIN 30988 1 1 -- 100:0 R 00:00
Job run at Tue Aug 06 at 15:47 on (sio:ncpus=1)
ここまでの設定で,CPUを利用した計算ジョブは問題なく実行できるようになりました。次回は,GPUを計算リソースとしてジョブスケジューリングするための設定をし,動作確認を行います。