概要
Singularityコンテナのビルド方法は以下のようなものがあります。
- Singularity HubからPullする
- Docker HubからPullする
- Sandbox環境を使いビルドする
- 書き込み可能なイメージを使いビルドする
- 他のイメージフォーマットから変換する(例:Squashfs → writable ext3)
- Recipeファイルを使いビルドする
コンテナの再現性を確保すること、本番環境用のコンテナを作成することを目的とする場合には、Recipeファイルを使ったコンテナ作成方法が適しています。Recipeファイルを使う場合には、以下のようなメリットもあります。
- ファイルや環境変数を追加しやすい
- カスタムソフトウェアをインストールしやすい
本稿では、Recipeファイルのフォーマットを俯瞰するとともに、実際にRecipeファイルからイメージを生成する手順を説明します。詳細については公式ページを参照ください。
予備知識
Recipeファイルは大別すると2つの要素から構成されます。
- Header:ベースとなるOSを指定する部分
- Sections (Body):環境変数の設定やソフトウェアインストールについて記述する部分
Header
まずBootstrap:
でベースとするイメージの取得先を指定します。この記述に依り、以降に続くキーワードは変化します。Bootstrap:
に指定できる参照先は以下のようなものがあります。
Singularity Hubを指定する場合は以下のようになります。Bootstrap: shub
にFrom:
が続きます。
Bootstrap: shub
From: shub://<registry>/<username>/<container-name>:<tag>@<digest>
registry
、tag
、digest
はオプションです。From:
の冒頭、shub://
も省略可能のようです。
例えば、白鳥氏のOpenFOAMのイメージを取得してビルドする場合には以下のようになります。
Bootstrap: shub
From: TakahisaShiratori/openfoam:4
Docker Hubを指定する場合は以下のようになります。上記と同様に、From:
が続きます。
Bootstrap: docker
From: <registry>/<namespace>/<container>:<tag>@<digest>
例えば、Ubuntu 16.04のイメージを取得する場合は以下のようになります。
Bootstrap: docker
From: ubuntu:16.04
Sections
Sectionsはsection(scriptlet)から構成され、%
から始まる文字列で区切られた領域に内容が記述されます。全てオプションとして記述されるものになり、必ず記述が必要なわけではありません。
Sectionの指定には以下のようなコマンドを利用できます。
Notation | 説明 |
---|---|
%help | Singularityコマンドにhelpオプションを指定した際に表示されるコメントを記述する。 |
%setup | コンテナにbase OSがインストールされた後にホスト側で実行する処理を記述する。 |
%files | ホストからコンテナへのファイルコピーの処理を記述する。 |
%labels | コンテナに格納するメタデータを記述する。 |
%enviroment | コンテナが実行される際に読み込まれる環境変数を記述する。(ビルド時は無効) |
%post | ビルド時にコンテナにbase OSがインストールされた後にコンテナ側で実行する処理を記述する。(ホストからコンテナへのファイルコピーは不可) |
%runscript | コンテナが実行された際に呼び出される処理を記述する。 |
%test | ビルドの最後の段階で行う処理、または、コンテナが実行された際に検証のために行う処理を記述する。 |
以下にいくつかの注意点を列記します。
-
%files
の処理は%post
およびインストールの処理の後に行われるため、%post
処理中に必要となるファイルは%setup
に置いてコピー処理を行います。 -
%setup
においてコンテナ内にファイルをコピーするには$SINGULARITY_ROOTFS
を使います。この指定がない場合はホスト側での処理になってしまいます。 -
%files
の処理は<source> <destination>
のペアで記述されます。<destination>
を省略した場合は、/
直下にコピーされます。 - ビルド時に有効にさせたい環境変数がある場合には、
%environment
ではなく%post
に設定を記述します。 -
%labels
に記述されたメタデータは/.singularity.d/labels.json
に格納されます。ここの記述は、singularity inspect
で確認できます。 - Sectionが処理される順序は、[Build]
%setup
→%post
→%files
→%test
、[Run]%environment
→%runscript
となると考えられます。 - Sectionのいずれかの処理に失敗するとビルドは停止します。
Recipeファイルのフォーマット詳細については公式ページを参照ください。
準備
Singularityのイメージファイルのデフォルトのファイルフォーマットはsquashfsです。simgイメージが取り扱えるようにパッケージをインストールします。
sudo yum install -y squashfs-tools
なお、Recipeファイルからのビルドにはroot権限が必要になります。
操作
分子動力学計算ソフトウェアLAMMPSのコンテナイメージをRecipeファイルから作成する手順を説明します。
この操作は以下の手順で行います。
- Recipeファイルを作成する。
- Recipeファイルを指定して
build
コマンドを実行し、コンテナイメージを作成する。
Recipeファイルの作成
Recipeファイルの中では以下のような順序で操作を記述します。
- HeaderにDocker Hubからbase OS(CentOS)を取得する記述を行います。
-
%post
に必要パッケージのインストール、LAMMPSのビルド・インストール処理を記述します。 -
%environment
に共有ライブラリの環境変数設定を記述します。 -
%runscript
にコンテナ実行時の処理を記述します。
以下内容は古家氏資料を参考にし、version 2.4における操作の説明に修正したものになります。
新規にRecipeファイルを作成します。
vi Singularity
Header情報を記述します。
Bootstrap: docker
From: centos:latest
次にインストール操作を%post
以下に記述します。
%post
yum -y update
yum -y install gcc gcc-gfortran gcc-c++ make wget git
mkdir /tmp/build
cd /tmp/build
wget https://www.open-mpi.org/software/ompi/v1.6/downloads/openmpi-1.6.4.tar.gz
tar xvfz openmpi-1.6.4.tar.gz
cd openmpi-1.6.4
./configure --prefix=/usr/local
make
make install
cd /tmp/build
git clone -b 'patch_22Sep2017' https://github.com/lammps/lammps.git
cd lammps/src/
make g++_openmpi
cp lmp_g++_openmpi /usr/local/bin/
cd /
mkdir /enc
rm -rf /tmp/build
yum clean all
次に、共有ライブラリの環境変数を%enviroment
に記述します。
%environment
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
続いて、run
実行時の処理を記述します。
%runscript
/usr/local/bin/lmp_g++_openmpi
Recipeファイルを使ったイメージのビルド
上述のRecipeファイルを使い、lammps.simg
を作成します。
sudo singularity build lammps.simg Singularity
なお、version 2.4以前においては、create
コマンドを使い空のイメージを作成してからOSやアプリケーションのインストールを行う手法が取られていましたが、version 2.4以降はbuild
コマンドを使い、イメージ作成とインストールを同時実行することが推奨されています。version 2.4では空のイメージを作成する場合は、image.create
コマンドで代替することになりました。
補足
Proxy環境下において、Recipeファイルからのイメージ生成に失敗することがあります。http_proxy
、https_proxy
といった環境変数の設定を行っているにも関わらずエラーが発生する場合があります。
/usr/local/libexec/singularity/python/base.py
に以下のコマンドを追記することでこのエラーを回避できます。詳細はリンクを参照ください。
os.environ['http_proxy'] = "http://host:port"
os.environ['https_proxy'] = "http://host:port"
また、Recipeファイルからのビルドの際にもProxy設定が必要になります。%post
の最初に以下のような記述の追記します。(ディストリビューションにより記述方法は異なります。)
export http_proxy="http://host:port"
export https_proxy="http://host:port"