昨日の記事の続きになりますが、実践編ということでSLURMクラスタを使ったジョブの分散実行環境を構築してみたいと思います。
SLURMはLinux環境で動作するオープンソースのジョブスケジューラで、スパコンなど大規模な計算ノードクラスタで広く利用されています。Galaxyはジョブ実行プラグイン(Job Runner) として SLURM をサポートしており、ツールの実行先としてSLURMクラスタの計算ノードを使うことができます。
Galaxy + SLURM のサーバ構成
Galaxy と SLURM によるクラスタを構築するためには、以下の各機能を単一または複数のサーバに割り当てる必要があります。
- Galaxy (Webサーバ, データベース)
- SLURMクラスタ・コントローラ
- SLURMクラスタ・計算ノード
- 共有ファイルシステム
今回の構築例では、SLURM計算ノード用に2台のサーバを用意し、他の1台にGalaxyとSLURMコントローラをインストールします。また、共有ファイルシステムにはNFSを採用し、Galaxy+SLURMコントローラ側のディスク領域を各計算ノードからNFSマウントして利用することにします。
共有ファイルシステムの準備
まず、Galaxy+SLURMコントローラをインストールするサーバ上で NFS サーバを起動しておきます。
NFSのインストールおよび設定の詳細はここでは省略しますが、NFSサーバ側の /export
ディレクトリをエクスポートして共有するには /etc/exports
ファイルに以下のように記述します。
/export a.b.c.d/z(rw,sync,no_subtree_check,fsid=0,no_root_squash)
注) a.b.c.d/z
にはエクスポートされるファイルシステムへのアクセスを許可するネットワークを適切に設定する必要があります。(e.g. 192.168.1.0/24
)
各SLURM計算ノードにおいて、共有ファイルシステムをローカルの /export
ディレクトリにマウントします。
以下のコマンドは、GalaxyサーバのIPアドレスが 192.168.1.100
の場合の例です。
mount -t nfs 192.168.1.100:/export /export
DockerによるGalaxyサーバ起動
Galaxy Projectの開発メンバーの一人である Björn Grüning 氏によりGalaxyのDockerコンテナイメージが公開されています。このイメージには SLURM コントローラ機能が含まれているため、今回はこれを利用します。
Galaxy + SLURMコントローラを稼働させるサーバ上で、以下のようにDockerコンテナを起動します。
docker run -d --net host --hostname galaxy --name galaxy \
-v /export:/export \
-e "NONUSE=nodejs,proftp,reports,slurmctld,slurmd,condor" \
bgruening/galaxy-stable:17.05
SLURMコントローラは、あとで(Galaxy起動後に)手動で設定を行うため、ここでは NONUSE
オプションで slurmctld, slurmd
を指定します。
その他の起動オプションについては、GitHub の bgruening/docker-galaxy-stable リポジトリに非常に丁寧なドキュメントがあります。
DockerによるSLURMノード起動
上記の Galaxy サーバ用 Docker コンテナとともに利用可能な SLURM 計算ノード用コンテナとして、bgruening/docker-galaxy-stable で提供されているDockerfile(コンテナビルド用スクリプト)があります。
これを docker build
したコンテナイメージ(galaxy-slurm
) を用意します。
SLURM計算ノードを稼働させる各サーバ上で、以下のようにDockerコンテナを起動します。
# SLURMノード #1
docker run -d --net host --hostname c1 --name slurm1 -v /export:/export galaxy-slurm
# SLURMノード #2
docker run -d --net host --hostname c2 --name slurm2 -v /export:/export galaxy-slurm
SLURMクラスタの設定
ホスト名解決
SLURMクラスタを運用する場合、各サーバはIPアドレスではなくホスト名でアクセスできなければなりません。内部向けDNS Serviceを起動する方法もありますが、クラスタを構成するノード数が少なければ /etc/hosts
に記述するやり方でも構いません。
上記で起動した各コンテナ内の /etc/hosts
に、galaxy
, c1
, c2
のホスト名に対応するIPアドレスを記述します。(実際のIPアドレスは構築環境により異なります。)
172.17.0.2 galaxy
172.17.0.3 c1
172.17.0.4 c2
SLURM設定ファイルの共有ファイルシステムへの配置
SLURMでは以下の2つの設定ファイルが必要です。
- slurm.conf
- munge.key
クラスタを構成する全サーバでこれらのファイルを共有するために、NFSでエクスポートされるパス /export
の直下に配置します。
Galaxyサーバには起動時に生成された /etc/munge/munge.key
と /etc/slurm-llnl/slurm.conf
があるはずですので、これらを共有ファイルシステムにコピーします。
cp /etc/munge/munge.key /etc/slurm-llnl/slurm.conf /export
次に、 slurm.conf
の内容を編集します。重要なのは、末尾の2行です。
- NodeName, Nodes : 計算ノードのホスト名のリスト
- CPU, RealMemory(単位:MB) : 計算ノードのマシンスペックに合わせた値
:
:
NodeName=c[1-2] CPUs=4 RealMemory=8192 State=UNKNOWN
PartitionName=debug Nodes=c[1-2] Default=YES MaxTime=INFINITE State=UP Shared=YES
SLURMコントローラ・デーモンの再起動
Galaxyサーバ上にあるSLURMコントローラ( slurmctld
)を再起動します。
このとき、共有ファイルシステムの設定ファイル /export/slurm.conf
読み込むように指示します。
# GalaxyサーバのDockerコンテナに接続
docker run -ti galaxy bash
# galaxy コンテナ内で実行
pkill slurmctld && pkill munged
munged --key-file=/export/munge.key -f
slurmctld -L /home/galaxy/logs/slurmctld.log -f /export/slurm.conf
SLURMノード・デーモンの再起動
SLURMノード側はデフォルトで /export/slurm.conf
を読み込むように設定されているため、関係するデーモンを再起動します。各SLURMノード上で以下のコマンドを実行します。
# SLURMノードのDockerコンテナに接続
docker run -ti slurm1 bash
# slurm1,2 コンテナ内で実行
supervisorctl restart munge
supervisorctl restart slurmd
SLURMクラスタを構成するサーバの Docker コンテナ内で sinfo
コマンドを実行した結果、STATE
=idle
のノードが2つ見えればOKです。
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
debug* up infinite 2 idle c[1-2]
Galaxyジョブ実行プラグイン設定
最後に、Galaxyがジョブ実行先としてSLURMクラスタを使うように設定します。
具体的には Galaxyがジョブ実行プラグイン(Job Runner)として SlurmJobRunner
を使うための設定です。
bgruening/galaxy-stable
のDockerコンテナを利用している場合、 /etc/galaxy/job_conf.xml
を以下のように書きます。(共有ファイルシステムのPATHではないので注意)
<?xml version="1.0"?>
<job_conf>
<plugins workers="2">
<plugin id="slurm" type="runner" load="galaxy.jobs.runners.slurm:SlurmJobRunner">
<param id="drmaa_library_path">/usr/lib/slurm-drmaa/lib/libdrmaa.so</param>
</plugin>
<plugin id="local" type="runner" load="galaxy.jobs.runners.local:LocalJobRunner" workers="2"/>
</plugins>
<handlers default="handlers">
<handler id="handler0" tags="handlers"/>
<handler id="handler1" tags="handlers"/>
</handlers>
<destinations default="slurm_cluster">
<destination id="slurm_cluster" runner="slurm">
<param id="nativeSpecification">-p work -n 4</param>
<param id="embed_metadata_in_job">False</param>
<env file="/export/galaxy-central/.venv/bin/activate" />
</destination>
<destination id="local" runner="local"/>
</destinations>
<tools>
<tool id="upload1" destination="local"/>
</tools>
<limits>
</limits>
</job_conf>
ファイルアップロードツール (upload1) に関しては、SLURMを使わずにローカルサーバ上で実行する(LocalJobRunnerを使う)ように記述している点にご注意ください。
以上でGalaxyジョブを分散実行するための環境が出来上がりました!
実際に解析等に活用するためのツールのインストールを行う際は、GalaxyサーバだけでなくSLURM計算ノードのほうにも同様にインストールすることをお忘れなく。