コンテナの使い方¶
はじめに¶
本ページでは、コンテナプラットフォームApptainerを利用する方法を説明します。
コンテナ¶
コンテナは仮想化技術の一種で、ホスト側のカーネルを共有したまま、ルートディレクトリ以下のユーザ環境のみを切り替えて専用の環境でアプリケーションを実行する方式です。
次のような利点があります。
- カーネルは起動済みのものを共有するため、起動が高速でオーバーヘッドが小さい
- OS環境・アプリケーション・設定を1つにまとめられ、再現性が高い
- 一度作成したイメージを複数のシステムで再利用でき、環境構築・検証の手間を減らせる
一方で、次の制限があります。
- コンテナはハードウェアのエミュレーションを行わないため、CPUアーキテクチャ(aarch64 / x86_64など)が異なるイメージは動作しない
- カーネルはホスト側のものを使うため、カーネルバージョンやドライバに依存する機能には注意が必要
コンテナイメージ¶
コンテナイメージは、ホストとは別のOS環境・ランタイム・アプリケーションをファイルシステムとして構築し、ファイルに保存したものです。
ApptainerはSIF(Singularity Image Format)と呼ばれる単一ファイル形式を採用しています。ランタイムを含む実行環境一式を1ファイルとして所有でき、保存・転送が容易です。また、Docker Hubなどで配布されている他形式のコンテナイメージを取得してSIFに変換したり、直接実行したりすることもできます。
実行¶
Apptainerはコンテナの起動とアプリケーションの起動を統合しており、コンテナ内のアプリケーションを、あたかもスタティックリンクされた1つのバイナリのように実行できます。
実行方法は大きく4通りあります。
- コンテナ起動時にシェルを起動し、手動で操作する(
apptainer shell) - イメージ内の任意のコマンドをコンテナ起動と同時に実行する(
apptainer exec) - イメージ内に事前設定されたコマンドを実行する(
apptainer run/ SIFの直接実行) - コンテナのみ起動しておき、外部からコマンドを投入する(
apptainer instance)
バッチジョブでは通常2. と3. を使います。4. は多数のデータを繰り返し処理する場合や、Jupyter Notebookなどのサービスを立ち上げておく場合に適しています。
利用の手順¶
本節では、既存イメージの取得からコンテナ起動までの基本的な流れを説明します。イメージを入手・作成する方法は3通りあります。
- Docker Hubなどで公開されている既存イメージを取得して再利用する
- イメージをファイルシステムに展開(sandbox化)し、手作業で変更する
- 定義ファイルを書いてビルドを自動化する
手作業(2.)はデバッグには便利ですが、再現性の観点からは、定義ファイル(3.)をリポジトリ等で管理してビルドする方法を推奨します。ベースイメージにはDocker Hubで配布されているUbuntu、AlmaLinux、Red Hat Universal Base Image(UBI)などの利用を想定しています。
Note
本システムはログインノード・計算ノードともaarch64アーキテクチャです。イメージの取得・作成・実行のいずれもアーキテクチャの食い違いを気にせず行えますが、取得するイメージはarm64(aarch64)版である必要があり、x86_64(amd64)用のイメージは動作しません。本システム上でpull / buildした場合は自動的にarm64版が選択されますが、イメージによってはarm64版が提供されていないことがあります。
コマンドラインでのイメージ作成¶
公開リポジトリからイメージを取得するにはpullコマンドを使います。docker://に続けてイメージ名とタグを指定します。本システムからの取得は内部のレジストリミラー(zot)を経由し、docker.io(Docker Hub)・nvcr.io(NVIDIA NGC)・quay.ioのイメージが利用できます。
apptainer pull ubuntu2404.sif docker://ubuntu:24.04
apptainer pull alma9.sif docker://almalinux:9
apptainer pull cuda13-base.sif docker://nvcr.io/nvidia/cuda:13.0.0-base-ubuntu24.04
apptainer pull busybox.sif docker://quay.io/prometheus/busybox:latest
取得の際、Docker形式のイメージレイヤはSIF形式に変換され、レイヤデータは~/.apptainer/cache以下にキャッシュされます。SIFイメージの実体はSquashFS形式で、起動すると読み込み専用になります。イメージにアプリケーションを追加するには、後述の定義ファイルによるビルド、またはファイルシステムに展開するsandboxを利用します。
sandboxは、buildコマンドに--sandboxオプションを付けて作成します。
sandbox内のファイルはユーザ自身がオーナとなり、コンテナを起動しなくても直接編集できます。ただし、sandboxからコンテナを起動した場合も既定では読み込み専用です。書き込み可能な状態で起動するには--writableオプションを指定します(SIFイメージでは指定できません)。また、root権限を前提とするapt / dnf / rpmなどのパッケージ管理コマンドを使うには--fakerootオプションが必要です。
Note
本システムから外部へのHTTP接続は制限されており、aptなどによる外部からのパッケージ取得は失敗することがあります。
SIFとsandboxは相互に変換できます。
手元にあるSIFイメージのアーキテクチャは、sif listコマンドで確認できます。
出力例:
------------------------------------------------------------------------------
ID |GROUP |LINK |SIF POSITION (start-end) |TYPE
------------------------------------------------------------------------------
1 |1 |NONE |32176-32214 |Def.FILE
2 |1 |NONE |32214-36205 |JSON.Generic
3 |1 |NONE |36205-36438 |JSON.Generic
4 |1 |NONE |36864-28946432 |FS (Squashfs/*System/arm64)
TYPE欄にFS (Squashfs/*System/arm64)のようにアーキテクチャが表示されます。arm64であれば本システムで実行できます。
イメージからのコンテナ起動¶
shellコマンドでコンテナを起動し、シェルで対話的に操作できます。ここでは、ホストと異なるディストリビューションの例として、コマンドラインでのイメージ作成で取得したAlmaLinuxイメージを起動してみます。
apptainer shell alma9.sif
Apptainer> cat /etc/os-release
NAME="AlmaLinux"
VERSION="9.8 (Olive Jaguar)"
...
ホストOSはUbuntuですが、コンテナ内ではイメージのOS環境(この例ではAlmaLinux)に切り替わり、イメージ内のコマンド・ライブラリのみが利用可能になります。カーネルとユーザはホスト側のものがそのまま使われます。
コンテナ内からは自身のホームディレクトリがそのまま見えます(他ユーザのホームディレクトリは見えません)。コンテナ内の/etc/passwdには起動時に自身のエントリーのみが追加されます。また、プロセス空間はホストと共有されるため、psやkillはコンテナ内外で相互に有効です。
execコマンドを使うと、コンテナ起動と同時に任意のコマンドを実行できます。
SIFファイルには実行属性が付いており、スクリプトのように直接起動することもできます。
Tip
イメージ内容を固定して運用したい場合や、起動オーバーヘッドを最小化したい場合は、SIFイメージでの利用を推奨します。SIFは内部が圧縮されており、総ファイル量に比してサイズが小さく、メタデータアクセスの負荷も低いため、アプリケーションの起動が高速かつ安定します。
イメージの作成¶
本節では、実行用のSIFイメージを作成する方法を説明します。
sandboxを用いる方法¶
sandboxを編集してSIFに固める方法です。手軽な反面、作業履歴が残らないため、確定した手順は定義ファイルに保存することを推奨します。
コンテナを起動せずに済む場合は、既成のアプリケーションやリファレンスデータをsandboxに展開して固めるだけです。
apptainer build --sandbox ubi9_py312 docker://registry.access.redhat.com/ubi9/python-312
tar xvzf ~/application.tar.gz -C ubi9_py312
vi ubi9_py312/usr/local/etc/application.config
apptainer build appl.sif ubi9_py312
パッケージの追加など、コンテナを起動してシステムを変更する場合は、--writableと--fakerootを指定してsandboxを編集します。
apptainer build --sandbox /tmp/ubuntu-sandbox ubuntu2404.sif
apptainer shell --fakeroot --writable /tmp/ubuntu-sandbox
Apptainer> apt-get update
Apptainer> apt-get install -y XXXXXXX
Apptainer> exit
apptainer build ~/from-sandbox.sif /tmp/ubuntu-sandbox
Tip
sandboxは多数の小ファイルで構成されるため、共用ストレージ(ホーム領域・グループ領域)上に置くとメタデータアクセスの負荷が大きくなります。sandboxの作成・編集はスクラッチ領域(/tmp)上で行うことを推奨します。スクラッチ領域はジョブ終了時に削除されるため、完成したSIFイメージはホーム領域またはグループ領域に保存してください。
定義ファイルによるカスタムイメージ¶
定義ファイルを書くと、イメージのビルドを自動化・再現可能にできます。定義ファイルは主に次の要素で構成されます。
- ヘッダ(
Bootstrap:,From:): ベースイメージの指定 %files: ホストからイメージへのファイル取り込み%post: イメージ内で実行する構築処理(パッケージ追加など)%environment/%runscript: 実行時の環境変数と既定コマンドの定義%labels: メタデータ
例として、Ubuntu 24.04をベースにパッケージとデータを追加する定義ファイルexample.defを示します。
Bootstrap: docker
From: ubuntu:24.04
%files
some_data.tar.gz /
%post
apt-get update
apt-get install -y python3 python3-lxml
tar xzf /some_data.tar.gz -C /usr/share
rm /some_data.tar.gz
apt-get clean
%environment
export LC_ALL=C.UTF-8
%runscript
python3 "$@"
%labels
Author USER@example.org
ビルドはbuildコマンドに--fakerootを付けて実行します。
Tip
ビルド時の一時展開先は既定でスクラッチ領域(/tmp)が使われます。一時領域を明示したい場合は、環境変数APPTAINER_TMPDIRで展開先を、APPTAINER_CACHEDIRでキャッシュ先を変更できます。ホーム領域の容量を圧迫したくない場合は、APPTAINER_CACHEDIRをスクラッチ領域やグループ領域(/data1/GROUP)に向けることも有効です。
実行環境の埋め込み¶
定義ファイルの%runscriptに実行コマンドを記述しておくと、SIFイメージを直接実行するだけでアプリケーションを起動できます。定義ファイルによるカスタムイメージのexample.defでは%runscriptにpython3 "$@"を設定しているため、次のように使えます。
%environmentに環境変数を埋め込んでおけば設定漏れを防止でき、ジョブスクリプトも簡素になります(実行方法のイメージへの埋め込みを参照)。
Note
定義ファイルのFrom:にlatestタグを指定すると、ビルドのたびに取得される内容が変わる可能性があります。再現性を重視する場合は、バージョンを固定したタグを指定してください。
ジョブ投入によるイメージ作成¶
軽量なイメージであればログインノード上で直接ビルドできますが、多数のパッケージをインストールする大規模なビルドはCPU・メモリ・ストレージへの負荷が大きいため、バッチジョブとして計算ノードで実行することを推奨します。ビルド時の一時ファイルは多数の小ファイルを生成して共用ストレージに負荷をかけるため、作業領域にはスクラッチ領域(/tmp)を使い、成果物のみホーム領域またはグループ領域へコピーしてください。
ジョブスクリプトの例を示します(資源の要求方法は Slurmとの連携を参照)。
#!/bin/bash
#SBATCH -A PROJECT
#SBATCH --time=01:00:00
# スクラッチ領域 (/tmp。ジョブ終了時に削除) を作業領域にしてビルドし、
# 成果物のみホーム領域 (大きい場合はグループ領域) に保存する
export APPTAINER_TMPDIR=/tmp/build
mkdir -p $APPTAINER_TMPDIR
apptainer build --fakeroot $APPTAINER_TMPDIR/create_job.sif ~/example.def
cp $APPTAINER_TMPDIR/create_job.sif ~/
電子署名によるイメージ管理¶
Apptainerは公開鍵暗号によるイメージの署名・検証機能を持ち、イメージの作成者と改竄の有無を確認できます。
キーペアの作成:
名前・メールアドレス・コメント・パスフレーズを対話的に入力します。作成した鍵は~/.apptainer以下に保存され、次のコマンドで確認できます。
署名と検証:
apptainer sign ubuntu2404.sif # パスフレーズを入力して署名
apptainer verify ubuntu2404.sif # 署名者・フィンガープリント・検証結果を表示
verifyによる検証には署名者の公開鍵が必要です。署名されていないイメージをverifyすると、次のように "signature not found" エラーで失敗します。
出力例:
INFO: Verifying image with PGP key material
WARNING: No default remote in use, falling back to default keyserver: https://keys.openpgp.org
FATAL: Failed to verify container: integrity: signature not found for object group 1
Note
上の出力にあるとおり、手元に該当する公開鍵がない場合、既定では外部のキーサーバ(keys.openpgp.org)が参照されます。
公開鍵のエクスポート・インポート:
1つのイメージに複数の署名を付けられるため、作成者と管理者による多段階の承認といった運用も可能です。
実行時オプションと挙動¶
ホスト側の環境の取り込み¶
環境変数の取り扱い¶
Apptainerはコンテナ起動時に、ホスト側の環境変数をほぼすべてコンテナ内に引き継ぎます。ただしPATHとLD_LIBRARY_PATHは例外で、コンテナ側で再設定されます。定義ファイルの%environmentセクションに記述した内容は、イメージ内にスクリプトとして転記され、コンテナ起動時に読み込まれます。
ホスト側でAPPTAINERENV_***(***は任意の変数名)という環境変数を設定しておくと、コンテナ内では***という名前の変数として設定されます。ホスト環境に干渉せずにコンテナ内の変数を事前設定でき、イメージを再作成することなく%environmentの設定を一時的に上書きできます。
出力例:
同じ変数が複数の方法で設定されている場合、APPTAINERENV_***が最優先され、次に%environmentの設定、最後にホスト側から引き継がれた値の順で適用されます。個別の変数を渡すには--envオプションも利用できます。
ディレクトリのバインド¶
Apptainerはコンテナ起動時に、次のディレクトリを自動的にバインド(コンテナ内から見えるようにマウント)します。
- ホームディレクトリ
/tmp,/var/tmp/dev,/proc,/sys- 起動時のカレントディレクトリ(コンテナ内に同名ディレクトリが存在する場合)
これ以外のディレクトリをバインドするには-Bオプション(--bindの短縮形)を使います。ホスト側パスとコンテナ内のマウントポイントをコロンで区切って指定します(マウント先を省略すると同名パスにバインドされます)。グループ領域/data1/GROUPは自動バインドされないため、コンテナ内から利用する場合は明示的に指定してください。
apptainer exec -B /data1/GROUP ubuntu2404.sif ls /data1/GROUP
apptainer exec -B /data1/GROUP:/work ubuntu2404.sif ls -al /work
読み取り専用でマウントするには、さらにコロンでroを追加します。次の例は、グループ領域に置いたリファレンスデータを読み取り専用で参照するものです。
複数のディレクトリは-Bを列挙するか、カンマで区切って指定できます。環境変数APPTAINER_BINDにあらかじめ設定しておくこともできます。
Warning
カレントディレクトリは既定で自動バインドされるため、/usr/binや/usr/libなどからコンテナを起動すると、コンテナ内の同名ディレクトリがホスト側のもので置き換わり、ランタイムエラーの原因になることがあります。システムディレクトリからの起動は避けてください。
インスタンス化によるコンテナの常駐¶
execやrunはアプリケーション終了と同時にコンテナも終了するため、繰り返し実行するとコンテナ起動のオーバーヘッドが累積します。また、サーバのように常駐するサービスの運用にも向きません。インスタンス化は、コンテナを起動したまま維持し、その中で複数のアプリケーションを実行できる機能です。
出力例:
起動中のインスタンスはinstance://INSTANCE_NAMEで参照できます。
多数のファイルを繰り返し処理する場合、毎回コンテナを起動する代わりにインスタンスを使うと、起動オーバーヘッドを削減してスループットを上げられます。
apptainer instance start appl.sif worker
for data in data.*
do
apptainer exec instance://worker appl ${data}
done
apptainer instance stop worker
複数のインスタンスを同時に起動して、異なる環境での処理を1ジョブ内で並行実行することもできます。一般的には、データベースやWebサーバなど、ノード内に何らかのサービスを起動させておく用途で利用されます。インスタンス起動時に自動実行させたい処理は、定義ファイルの%runscriptの代わりに%startscriptに記述します。
インスタンスの停止:
リポジトリを指定した直接実行¶
execなどにリポジトリを直接指定して実行できます。初回実行時はSIFイメージ化が行われ、~/.apptainer以下にキャッシュされます。
再実行時はリポジトリに更新がないかをチェックし、キャッシュを最大限利用して同期をとった上で実行されます。更新がなければキャッシュ済みのSIFイメージが直接起動されます。
キャッシュの確認・削除:
apptainer cache list -v
NAME DATE CREATED SIZE TYPE
1991bd789d7184290c3cce 2026-07-16 11:33:11 0.61 KiB blob
2c999b3bd705fad8b11574 2026-07-16 18:02:14 1.01 KiB blob
3f26bc2dec0b515f1c2818 2026-07-16 18:01:58 3.90 MiB blob
45e09956dc667c5eff3583 2026-07-16 18:01:58 1.00 KiB blob
4b987da45db4d6278590ab 2026-07-13 11:21:35 27.55 MiB blob
5de55e5ef9c03399744146 2026-07-16 11:33:11 3.99 MiB blob
7f622ca8766bccb22f0424 2026-07-13 11:21:35 0.41 KiB blob
ab3fe4defd29ba6231229a 2026-07-16 18:01:58 0.61 KiB blob
ac1e79f92e8f480400c312 2026-07-16 18:02:14 67.29 MiB blob
b8ccdf7026bcaa90f19f3b 2026-07-16 18:02:14 0.61 KiB blob
e7a1a92a5bfeee40966aea 2026-07-16 11:33:11 1.00 KiB blob
ea17ec341c4211d1dd7f18 2026-07-13 11:21:35 2.02 KiB blob
4980a8b73e769874ff1544 2026-07-16 18:02:16 65.32 MiB oci-tmp
5f34df5144d4fcbe7d206e 2026-07-16 18:01:59 3.82 MiB oci-tmp
d8695c491922692fbdb835 2026-07-16 17:25:50 27.61 MiB oci-tmp
tmp_1601666898 2026-07-16 18:02:18 0.00 KiB oci-tmp
There are 4 container file(s) using 96.75 MiB and 12 oci blob file(s) using 102.74 MiB of space
Total space used: 199.49 MiB
apptainer cache clean
Note
この実行方法はリポジトリ側の更新に追従するため、動作実績のある実行環境を維持したい場合には向きません。常に最新版を取り込みたい場合などに限定して利用することをお勧めします。
Overlay機能について¶
SIFイメージは読み込み専用ですが、LinuxカーネルのOverlayFSを使って書き込み可能なレイヤを重ね合わせることができます。方法は2つあります。
--writable-tmpfsオプション: メモリ上のtmpfsを一時的な書き込み領域として重ねる--overlayオプション: 永続的な書き込み可能領域(overlayイメージ)を別途用意して重ねる
--writable-tmpfsでは任意の場所に新しいファイル・ディレクトリを作成できますが、イメージ内の既存ファイルの変更はできず、コンテナ終了後に変更内容は消失します。
apptainer shell --writable-tmpfs something.sif
Apptainer> echo hogefuga > /etc/testfile # 新規作成は可能
Apptainer> echo hogefuga > /etc/os-release # 既存ファイルは変更不可
bash: /etc/os-release: Permission denied
永続的なoverlayイメージは次のように作成・利用します。
# 1GB の overlay イメージを作成し、マウント用ディレクトリを予め作っておく
apptainer overlay create --size 1024 --create-dir /usr/share/apps overlay.img
# overlay を重ねてデータを展開する (書き込みは overlay 側に保存される)
apptainer exec --overlay overlay.img core.sif tar xzf reference-data.tar.gz -C /usr/share/apps
# 実行時に重ね合わせる
apptainer exec --overlay overlay.img core.sif ls -al /usr/share/apps
SIFとoverlayの両方に同一のファイルがある場合はoverlay側が優先されるため、イメージの部分的な改変にも活用できます。overlayイメージはext3形式の単なるファイルであり、resize2fsによるリサイズも可能です。また、apptainer overlay createの引数にSIFファイルを指定すると、overlayをSIFに埋め込んで1ファイルで運用することもできます。
小サイズのファイルが多数あるワークロードでは、overlayに取り込んでおくことで共用ストレージのメタデータアクセス負荷の軽減にも寄与します。
GPUとMPI¶
GPUの利用¶
ホスト側のGPUドライバはCUDA 13.0に対応していますが、コンテナ内で利用するCUDAツールキットは13.0以下のバージョンである必要があります。
コンテナ内からGPUを利用するには、--nvオプションを指定します。次の例は、GPUを4基割り当てたジョブ内での実行例です。
出力例:
GPU 0: NVIDIA GB200 (UUID: OMITTED)
GPU 1: NVIDIA GB200 (UUID: OMITTED)
GPU 2: NVIDIA GB200 (UUID: OMITTED)
GPU 3: NVIDIA GB200 (UUID: OMITTED)
このように、コンテナからホストのGPUを認識できます。なお、ジョブ内ではSlurmが割り当てたGPUのみが見えます(例:--gpus=1のジョブではGPU 0のみが表示されます)。--nvを指定すると、Apptainerは次の処理を行います。
/dev/nvidia*などのGPUデバイスをコンテナ内で利用可能にする(コンテナ内に/dev/nvidia*が現れます)- ホスト側のNVIDIAドライバ関連ライブラリをコンテナ内にバインドする
- バインドしたライブラリが使われるよう、コンテナ内の
LD_LIBRARY_PATHを設定する
CUDAツールキットやフレームワーク(PyTorch等)はコンテナイメージ側に含め、ドライバはホスト側のものを--nvで取り込む、という分担が基本です。GPU用イメージはNVIDIA NGC(docker://nvcr.io/...)からarm64(aarch64)版を取得できます(コマンドラインでのイメージ作成を参照)。
MPI並列¶
ノード内並列¶
1ノード内で完結するMPI並列は、コンテナ内でmpirun / mpiexecを起動するだけで実行できます。プロセスマネージャがコンテナ内で直接アプリケーションを起動するため、コンテナ外との連携は不要です。コンテナ内にMPIランタイムが含まれていることが前提です。
この場合、起動されるコンテナは1つだけで、その中で複数のプロセスが動作します。
Note
HPC-XビルドのOpen MPIを内蔵するイメージ(NGCのnvhpc系など)では、ノード内実行でも コンテナ内蔵Open MPI + srun --mpi=pmixの注記にあるOPAL_PREFIX / LD_LIBRARY_PATHの指定が必要です。
マルチノード並列の考え方¶
複数ノードにまたがるMPI並列を、ノード内並列と同じ方法で起動することはできません。他ノードでのプロセス起動時点ではコンテナ環境が立ち上がっていないためです。マルチノード並列では、プロセスの起動にコンテナ起動を含める、すなわち ホスト側のプロセスマネージャからapptainer execを起動する形をとります。ノード内並列とはmpirun(srun)とapptainerの順番が逆になっている点に注意してください。
複数ノードの確保はGPU数の指定で行います(1ノード4基のため、--gpus=8で2ノード。ジョブスケジューラ(Slurm)との連携を参照)。
次は--gpus=8 --ntasks-per-node=4のジョブ内(2ノードが確保されている状態)で実行した例です。
出力例:
この方式では、ホスト側とコンテナ内のMPIが連携して動作する必要があるため、両者のバージョン整合が重要になります。本システムでは次の2つの方式を利用できます。
ホスト提供MPIのバインド方式¶
本システムのホスト側にはNVIDIA HPC-Xがnvhpc-hpcxモジュールとして用意されています。HPC-XはHPC SDKの一部として導入されているOpen MPI系で、GPUとInfiniBand相互結合網に最適化されています。
Open MPIやUCXの実体ライブラリはHPC SDKツリー側にあるため、コンテナへのバインドはHPC SDKのディレクトリごと行い、コンテナ内にライブラリの場所を環境変数で伝えます。アプリケーションはホスト側のmpiccでビルドすると、ホストMPIとABI(Application Binary Interface)が一致し確実です。
#!/bin/bash
#SBATCH -A PROJECT
#SBATCH --gpus=8
#SBATCH --ntasks-per-node=4
#SBATCH --time=01:00:00
module load nvhpc-hpcx
# ホスト側 Open MPI の場所 (OPAL_PREFIX) を mpirun の実体パスから求める
OMPI_PREFIX=$(readlink -f "$(which mpirun)"); OMPI_PREFIX=${OMPI_PREFIX%/bin/mpirun}
UCX_LIB="UCX_LIB_DIR" # HPC SDK 内の hpcx-*/ucx*/lib (libucp.so のある場所。
# 例: find /shared/software/hpc_sdk -name libucp.so で確認)
mpirun --bind-to none -np 8 apptainer exec --nv -B /shared/software/hpc_sdk \
--env OPAL_PREFIX=$OMPI_PREFIX \
--env LD_LIBRARY_PATH=$OMPI_PREFIX/lib:$UCX_LIB \
mpi-apps.sif ~/myapps/hoge inputfile
コンテナ内蔵Open MPI + srun --mpi=pmix¶
ホスト側MPIに依存せず、コンテナの可搬性を優先したい場合は、コンテナ内にOpen MPIを内蔵し、SlurmのPMIx連携でプロセスを起動する方式が利用できます。
この方式では、ホスト側のSlurmが各ノードでコンテナを起動し、コンテナ内蔵のMPIランタイムがPMIxを介してプロセス群を集合させます。
Note
NGCのnvhpc系イメージなど、HPC-XビルドのOpen MPIを内蔵するイメージは、ビルド時のインストール先パスが焼き込まれているため、そのままではMPI_Initに失敗します(PML ob1 cannot be selected等)。実行時に--env OPAL_PREFIX=OMPI_PREFIXと--env LD_LIBRARY_PATH=OMPI_LIB:UCX_LIBを指定してください。プレフィックスはコンテナ内のhpc_sdk/**/hpcx-*/ompiを探して確認します。
実行時に共有メモリ転送のUCX ERROR(mm_posix ... Permission denied)が多数出力されることがありますが、別のトランスポートにフォールバックして正常に完走します。別系統のMPIを内蔵する場合は、事前に疎通確認してください。
MPI並列ジョブ¶
コンテナ内蔵Open MPI + PMIx方式のジョブスクリプト例を示します。
#!/bin/bash
#SBATCH -A PROJECT
#SBATCH --gpus=8
#SBATCH --ntasks-per-node=4
#SBATCH --time=01:00:00
srun --mpi=pmix apptainer exec --nv ~/mpi-apps.sif ~/myapps/hoge inputfile
利用可能なMPIプラグインはsrun --mpi=listで確認できます。
出力例:
Slurmとの連携¶
Apptainerはホスト環境との親和性が高く、ジョブスクリプト内でコンテナであることをあまり意識せずに利用できます。ジョブの投入方法そのものは Slurmの使い方、指定できるGPU数と確保されるノード数・CPUコア数・メモリ量は ジョブ実行資源を参照してください。
実行方法のイメージへの埋め込み¶
%environmentと%runscriptをイメージに設定しておくと、ジョブスクリプトをシンプルにできます。
定義ファイル:
Bootstrap: docker
From: ubuntu:24.04
%environment
export OMP_NUM_THREADS=8
export MYCODE_CONFIG=/usr/share/MyApps/hoge.json
%runscript
python3 /usr/share/MyApps/hoge.py "$@"
このイメージをhogeという名前でPATHの通ったディレクトリに実行属性付きで保存しておくと、ジョブスクリプトは通常のアプリケーション実行と変わらなくなります。
インタラクティブ実行¶
計算ノードを対話的に利用するにはsallocでノードを確保し、srunでシェルを起動します。
計算ノード上でシェルが起動したら、そのままコンテナを操作できます。
インタラクティブジョブ内では、本ページで紹介したすべての操作(イメージのビルド、sandboxの編集、GPUを使った動作確認など)を対話的に実行できます。