Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
2
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@nigyta

遺伝研スパコンで Singularity を使う際のトラブルシュートあれこれ

はじめに

以前に書いた遺伝研スパコンにおける Singularity の使い方のより実践的なトラブルシュートの例として、BUSCO というツールを使えるようにするまでの過程を記録します。

BUSCO はゲノムや予測された遺伝子セットの完全性を評価するツールです。依存ツールが多く手動でインストールすると結構苦労するので Anaconda/Miniconda を使ってインストールすることをおすすめします。また、Docker が使える環境であれば公式のコンテナイメージも配布されています。
しかし、遺伝研スパコンでは Docker が使えないことと、個人的な事情から conda が使えない/使いたくなかったので遺伝研スパコンに用意されている Singularity 版 BUSCO を使用することにしました。

したがって、単に BUSCO を使いたいという人は、conda コマンドを使ってインストールしてしまえば幸せになれます。

$ conda install -c bioconda -c conda-forge busco

手っ取り早く Singularity 版 BUSCO を動かしたいという人は途中をすっ飛ばして、一番最後の最終的な実行スクリプトをご参照ください。
また、将来コンテナイメージが更新されたりスパコンの実行環境が変わった場合には、ここで書いている通りに動かなくなる可能性があることをご了承ください。

1. とりあえず起動してみる

遺伝研スパコンでは/usr/local/biotools/以下に各種生命科学用ツールの Singularity コンテナイメージが格納されている。これらは Biocontainers が提供している Docker イメージを Singularity イメージに変換したものである。
下記コマンドで BUSCO を起動し、ヘルプの表示を試みる。

$ singularity exec /usr/local/biotools/b/busco:4.0.2--pyr36_0 busco -h
WARNING: Skipping mount /opt/pkg/singularity/3.5.2/var/singularity/mnt/session/etc/resolv.conf [files]: /etc/resolv.conf doesn't exist in container
Segmentation fault

いきなり出鼻をくじかれてしまった。メモリ不足が疑われたので、qlogin 時に要求するメモリを増やしてみる。

$ qlogin -l mem_req=16G,s_vmem=16G

その後、再び実行。

$ singularity exec /usr/local/biotools/b/busco:4.0.2--pyr36_0 busco -h
WARNING: Skipping mount /opt/pkg/singularity/3.5.2/var/singularity/mnt/session/etc/resolv.conf [files]: /etc/resolv.conf doesn't exist in container
usage: busco -i [SEQUENCE_FILE] -l [LINEAGE] -o [OUTPUT_NAME] -m [MODE] [OTHER OPTIONS]
(以下省略)

無事にヘルプが表示されたので、まずは第一段階クリア。(警告が出ているが、今のところは無視。この警告は遺伝研スパコンで Singularity を使っていると良く出てくるが、ほとんどのケースでは問題なく動作する)

2. コンテナの中を探る

次に、--list-datasetsオプションを使って BUSCO が利用できる参照データの一覧を表示させてみる。

$ singularity exec /usr/local/biotools/b/busco:4.0.2--pyr36_0 busco --list-datasets 
WARNING: Skipping mount /opt/pkg/singularity/3.5.2/var/singularity/mnt/session/etc/resolv.conf [files]: /etc/resolv.conf doesn't exist in container
ERROR:  The config file is necessary here as it contains remote and local path locations for downloading dataset information
ERROR:  Please specify a BUSCO config file using either (i) an environment variable by entering 'export BUSCO_CONFIG_FILE=/path/to/config.ini' or (ii) using the command line flag --config /path/to/config.ini

エラー。どうやらコンフィグファイルのパスを実行時のオプションか環境変数で指定する必要があるようだ。そこで、コンフィグファイルがどこにあるのかコンテナ内に入って探すことにする。

$ singularity shell /usr/local/biotools/b/busco:4.0.2--pyr36_0
または、
$ singularity exec /usr/local/biotools/b/busco:4.0.2--pyr36_0 bash

でコンテナ内に入ることができるので、/usr/local以下などの怪しそうな場所を探索してみる。また、コンテナイメージは Bioconda のレシピをもとに生成されたものであるから、レシピファイルを参考にすると目的のファイルがどこにあるかを知る手がかりになる。レシピファイルは Bioconda の公式ページでツール名で検索すれば見つけることができる。

結果、/usr/local/config/config.ini にコンフィグファイルが存在することが分かった。

[TIPS]

  • singularity shell コンテナ名 でコンテナ内に入れる
  • Biocondaのレシピファイルを見ると問題解決の手助けになる

3. 環境変数の指定

コンフィグファイルが見つかったので、オプションで指定して実行してみる。

$ singularity exec /usr/local/biotools/b/busco:4.0.2--pyr36_0 busco --list-datasets --config /usr/local/config/config.ini 

が、エラーは解決せず(理由は不明)。

そこで、環境変数を指定する方法で試してみる。

$ export BUSCO_CONFIG_FILE=/usr/local/config/config.ini
$ singularity exec /usr/local/biotools/b/busco:4.0.2--pyr36_0 busco --list-datasets
WARNING: Skipping mount /opt/pkg/singularity/3.5.2/var/singularity/mnt/session/etc/resolv.conf [files]: /etc/resolv.conf doesn't exist in container
INFO:   Downloading information on latest versions of BUSCO data...

となって、無事にエラーは解決された。
しかし、画面には最新のデータをダウンロードしているように表示されているものの、すぐに終了してしまってデータが得られていない。これの解決方法は次項に続く。

[TIPS]

  • ホスト側で設定した環境変数はコンテナ内にも引き継がれる
  • (ただし、PATH など一部の環境変数は引き継がれない)

4. ネットワークへの接続を行う

前項でデータがダウンロードできなかった原因は起動時に表示されている警告にヒントがあった。/etc/resolv.confには DNS への参照情報が記載されているが、これがコンテナ内に存在しなかったために、インターネットへの接続ができなかったのが原因であった。

念の為 curl で確認してみると、

$ singularity exec /usr/local/biotools/b/busco:4.0.2--pyr36_0 curl http://example.com
WARNING: Skipping mount /opt/pkg/singularity/3.5.2/var/singularity/mnt/session/etc/resolv.conf [files]: /etc/resolv.conf doesn't exist in container
curl: (6) Could not resolve host: example.com

やはりネットワークへ接続ができていない。
そこで、/etc/resolv.confがコンテナ内から参照できるようにしてみる。
ちょっと乱暴だけどホスト側の /etc を丸ごとマウントする*。

$ singularity exec -B /etc:/etc /usr/local/biotools/b/busco:4.0.2--pyr36_0 busco --list-datasets 

結果、busco_downloadsというディレクトリができて、参照データのダウンロードもできた。なお、ホスト側とコンテナ側とで同じ場所にディレクトリをマウントする場合は、-B /etcというような指定でも良い。

* 本当は-B /etc/resolv.conf:/etc/resolv.confというように目的のファイルだけをマウントしたかったが出来なかった。コンテナ側の/etcを丸ごと置き換えてしまった形になったが、プログラムの動作に必要なファイルが/etcに置かれていたら動かなかったかもしれない。
その後、より安全な方法をご指摘いただいたので追記
コンテナ内の /etc/resolv.conf/tmp/resolv.confへのシンボリックリンクになっている。そのため、ホスト側であらかじめ/tmp/にresolv.confを配置しておき、/tmpをマウントするようにすれば良い。すなわち、

$ cp /etc/resolv.conf /tmp/
$ singularity exec -B /tmp /usr/local/biotools/b/busco:4.0.2--pyr36_0 curl http://example.com

で動作する。/tmp/にコピーした場合はログアウトすると消えてしまうので、カレントディレクトリに tmp ディレクトリを作成し、その中にコピーしてもよい。(その場合、-B $PWD/tmp:/tmp とする)

[TIPS]

  • /etc/resolv.confの問題でネットワークへの接続ができないときは-B /etcをつける
  • より良い方法は、あらかじめ/tmp/にresolv.confを配置しておき、/tmpをマウントするようにする(-B /tmp

5. いよいよ実行

バクテリアのゲノムデータを入力ファイルに使って実行。

$ singularity exec -B /etc /usr/local/biotools/b/busco:4.0.2--pyr36_0 busco -m genome -i genome.fa -o busco_out -l bacteria_odb10 

バクテリア用の参照データ(bacteria_odb10)が自動的にダウンロードされ、無事に BUSCO が実行できた。同じ参照データを使って再度実行する際にはネットワークへの接続が不要なので-B /etcを省いて実行可能。

次に、真核生物ゲノムを用いて実行テスト

$ singularity exec -B /etc /usr/local/biotools/b/busco:4.0.2--pyr36_0 busco -m genome -i genome_euk.fa -o busco_euk_out -l eukaryota_odb10 -f
WARNING: Skipping mount /etc/localtime [binds]: /etc/localtime doesn't exist in container
(中略)
ERROR:  The environment variable AUGUSTUS_CONFIG_PATH is not set
ERROR:  BUSCO analysis failed !
ERROR:  Check the logs, read the user guide, and check the BUSCO issue board on https://gitlab.com/ezlab/busco/issues

真核生物のゲノムの場合、遺伝子の予測に Augustus を使っている。その設定ファイルへの場所を環境変数AUGUSTUS_CONFIG_PATHに指定する必要があるようだ。
BUSCOのコンフィグファイルを環境変数で指定したのと同様に設定を行う。Augustusの設定ファイルは/usr/local/configディレクトリに存在しているので、

$ export AUGUSTUS_CONFIG_PATH=/usr/local/config

で環境変数を設定したのち、再度実行。しかし、今度は、

ERROR:  Cannot write to Augustus species folder, please make sure you have write permissions to /usr/local/config/species

ということで、ディレクトリへの書き込み権限がないと怒られてしまった。

6. コンテナ内から必要なファイルをコピー

前述のようにコンテナ内のディレクトリへの書き込み権限が問題でエラーが生じるケースは少なくない。そのような場合に、
1. コンテナ内からディレクトリをホームディレクトリにコピー
2. コピーしたディレクトリを、実行時に参照できるようにする
という手順で解決できることができる。

まずは、コンテナ内の/usr/local/configbusco_configという名称でカレントディレクトリにコピーする。

$ singularity exec /usr/local/biotools/b/busco:4.0.2--pyr36_0 cp -r /usr/local/config ./busco_config

ついで、コピーしたディレクトリを環境変数で指定して実行する。

$ export AUGUSTUS_CONFIG_PATH=$PWD/busco_config
$ singularity exec -B /etc /usr/local/biotools/b/busco:4.0.2--pyr36_0 busco -m genome -i genome_euk.fa -o busco_out -l eukaryota_odb10 -f

この時、自分のホームディレクトリはコンテナ実行時に自動でマウントされるため、明示的にマウントする必要はない。

これで動くかと思われたがまたしても別のエラー。

subprocess.CalledProcessError: Command '['/usr/local/bin/tblastn', '-version']' returned non-zero exit status 127.

どうやら tblastn の実行ができないらしい。

[TIPS]

  • コンテナ内のファイル・ディレクトリへの書き込み権限が必要な場合、いったんそれらをホームディレクトリにコピーしてから環境変数や実行時オプションなどで参照できるようにすれば動くことがある

7. コンテナへのライブラリの追加

状況を把握するため、コンテナ内の tbastn を単独で実行してみる。

$ singularity exec /usr/local/biotools/b/busco:4.0.2--pyr36_0 /usr/local/bin/tblastn
(中略)
/usr/local/bin/tblastn: error while loading shared libraries: libbz2.so.1: cannot open shared object file: No such file or directory

ライブラリが足りていないのがエラーの原因のようだ。

(コンテナ内に入って調べたところ /usr/local/lib/ に libbz2.so.1.0 は存在しているがlibbz2.so.1 が存在していなかったのが原因と考えられる。書き込み権限があればシンボリックリンクを作るなどで簡単に対処できそうだが、残念ながらコンテナ内のファイルに対してはそれができない。)

将来コンテナが更新された際にはライブラリ不足は修正される可能性もあるが、足りないライブラリをホスト側から追加してエラーを回避することもできる。
それには、環境変数SINGULARITY_CONTAINLIBSに追加したいライブラリを(複数あればカンマ区切りで)記述すればよい。

$ export SINGULARITY_CONTAINLIBS=/lib64/libbz2.so.1
$ singularity exec -B /etc /usr/local/biotools/b/busco:4.0.2--pyr36_0 /usr/local/bin/tblastn

ここではホスト側にあった/lib64/libbz2.so.1を追加することで無事に tblastn を起動することができた。

[補足]
環境変数 SINGULARITY_CONTAINLIBS で指定したライブラリはコンテナ内の /.singularity.d/libs にコピーされる。このディレクトリは環境変数LD_LIBRARY_PATH に含まれているため、tblastn 実行時にライブラリが参照できるようになっている。

[TIPS]

  • ライブラリがなく実行できない場合には SINGULARITY_CONTAINLIBS で追加することができる。

8. 最終的な実行スクリプト

このような過程を経て出来上がったのが下記のスクリプト。
最初の方では BUSCO のコンフィグファイルのパスを環境変数 BUSCO_CONFIG_FILE で指定したが、その後の手順でコンフィグファイル一式を含んだディレクトリをコンテナ内からホームディレクトリにコピーしたので、実行時オプション --config で指定する方法に変えている。

#$ -S /bin/bash
#$ -cwd
#$ -l mem_req=25G,s_vmem=25G

GENOME=/home/xxxxx/path/to/mygenome.fa
OUTDIR=busco_result

# コンテナ内から resolv.conf が参照できるように /tmp にコピーしておく
# 注)コンテナ内では /etc/resolv.conf は /tmp/resolv.conf へのリンクになっている
cp /etc/resolv.conf /tmp/

# BUSCO実行前にコンテナ内からBUSCO・Augustusの設定ファイルを含んだディレクトリをコピーしておく
# 一度コピーした後は、再実行する必要はない
# busco_config/config.ini は必要に応じて編集してもよいが、そのままでも動く
singularity exec /usr/local/biotools/b/busco:4.0.2--pyr36_0 cp -r /usr/local/config ./busco_config

# 環境変数 AUGUSTUS_CONFIG_PATH に先にコピーしておいたディレクトリを指定する
export AUGUSTUS_CONFIG_PATH=$PWD/busco_config

# Buscoが内部的に利用する tblastn の実行に libbz2.so.1 が不足しているので、ホスト側のライブラリを利用できるようにする
export SINGULARITY_CONTAINLIBS=/lib64/libbz2.so.1

# コンテナ内から resolv.conf が参照できるようにホスト側の /tmp をマウントする。
# resolv.conf は参照データのダウンロード時に必要なので、一度取得してしまったら以後は -B /tmp はなくても動作する。
# BUSCOの設定ファイルは --config busco_config/config.ini で指定する。(環境変数 BUSCO_CONFIG_FILE で指定することも可能)
singularity exec -B /tmp /usr/local/biotools/b/busco:4.0.2--pyr36_0 busco --config busco_config/config.ini -m genome -i $GENOME -o $OUTDIR -l eukaryota_odb10
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
2
Help us understand the problem. What are the problem?