📦

WSL2にApptainer環境 (with GPU) を構築する

2023/03/18に公開

📌 一部 Ubuntu (ver. 22.04) の場合について補足しました

コードブロック における 🍅 は、プロンプトを表している

🍅 はじめに

自分もあまり把握できていなかったのだけど、今後は Singularity-CE よりも Apptainer (旧 Singularity ) を利用したほうが良さそう。

Singularityというプロジェクトはやや込み入った状況があります。例えば理化学研究所のスーパーコンピュータ富岳で採用されているコンテナ環境はSingularityPROと呼ばれているものですが、これはSylabsという会社が上記のプロジェクトをフォークしたもので、現在では実質的に独立して開発が続けられています。2つのプロジェクトが同じSingularityという名前で開発されている事による混乱を避けるため、またSylabsが引き続きSingularityという名称を商用に使えるように、Linux Foundationに移管された方のプロジェクトは別名に変更される事になったようです。

Zenn | Apptainer導入

ということで自宅の環境をいじったのでその備忘録です。

別に Ubuntu でも良かったのですが、気分を変えて RHEL 系でやってみました。なんとなく Rocky Linux でと思ったのですが、Microsoft Storeになかったので AlmaLinux を使うことにしました。

以下、本記事を執筆した際の環境。

specifications
CPU Ryzen 7 5700X (AMD)
グラフィックボード GeForce RTX 2080 Ti VENTUS GP OC (MSI)
メモリ DDR4-3200 16 GB×2 (Crucial)
version
Windows 10 22H2
NVIDIA グラフィクス ドライバー 528.49
WSL2 1.0.3.0
AlmaLinux 8 on WLS2 8.7
Apptainer 1.1.5-2.el8

🍅 AlmaLinux 8 on WSL2環境

WLS2のインストール

基本的には公式ドキュメントに従う。
Microsoft | WSLを使用してWindowsにLinuxをインストールする

管理者権限で PowerShell を起動して以下のコマンドを入力し、WSL2 をインストールする。

# WSL2のみをインストール
🍅 wsl --install --no-distribution

--no-distribution オプションをつけることで、ディストリビューションはインストールせず、WSL2 のみをインストールしている ( AlmaLinux 8 がインストールリストにないため)。

WSL2 のインストールが完了したら Windows を再起動する。

AlmaLinux 8のインストール

再起動したらMicrosoft Storeから AlmaLinux 8 をインストールする。
Microsoft Store | AlmaLinux 8 WSL

インストールされたらCUIに従い AlmaLinux 8 用のユーザー名とパスワードを作成する。

AlmaLinux 8 on WSL2のセットアップ

※ このセクションは筆者用メモの意味合いが強く、Apptainer 環境構築とはあまり関係がないことに注意

WSL2の設定

公式ドキュメントなどを参考にしながら WSL2 の設定をする。
Microsoft | WSLでの詳細設定の構成

Windows のホームディレクトリ ( %UserProfile% ) に以下の .wslconfig を作成する。

%UserProfile%/.wslconfig
# Settings apply across all Linux distros running on WSL 2
[wsl2]

# Limits VM memory to use no more than 24 GB, this can be set as whole numbers using GB or MB
memory=24GB 

.wslconfigWSL2 全体に対する設定を記述するファイルで、インストールされているすべてのディストリビューションに影響を及ぼす。

次に、AlmaLinux 8/etc ディレクトリに以下の wsl.conf ファイルを作成する。

/etc/wsl.conf
[boot]
systemd = true

[automount]
options = "metadata,umask=022"

[interop]
appendWindowsPath= false

こちらの wsl.conf はそれを配置したディストリビューションにのみ影響を及ぼす。/etc に作成するため、管理者権限が必要である ( sudo vim /etc/wsl.conf などお好きな方法で)。

appendWindowsPath= false によってコマンドTab補完時にWindowsのコマンドを検索しないようにしている (デフォルトだとレスポンスが遅いため。ただし code コマンドも使用できなくなるため、 alias に設定するなど対応が必要)。

AlmaLinux 8に必要そうなパッケージをインストールする

dnf コマンドを用いてパッケージのインストールを行う ( yum を使うものだと思っていたらいつの間にか dnf になっていて驚いた)。

# インストールされているパッケージのアップデート
🍅 sudo dnf update

# 開発関係パッケージのインストール
🍅 sudo dnf groupinstall "Development tools"

# zshのインストール
🍅 sudo dnf install zsh

# chshのためにインストール
🍅 sudo dnf install util-linux-user

あまりよくわかっていないが、dnf update はそれだけで apt update && apt upgrade と同じ意味合いらしい。

dnf groupinstall "Development tools"apt install build-essential みたいなもの。

Ubuntu と違ってデフォルトで chsh コマンドが使えないらしいので、util-linux-user パッケージをインストールしている。

Zsh関係のセットアップ

個人的に zsh 環境として Prezto を活用している。以下の公式ドキュメントに従って設定する。
GitHub | Prezto — Instantly Awesome Zsh

# ホームディレクトリに移動 (念のため)
🍅 cd ~

# zsh起動 (初回起動時の質問にはqでOK)
🍅 zsh

# Preztoのリポジトリをダウンロード
🍅 git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto"

# .zshrcなどを配置
🍅 setopt EXTENDED_GLOB
for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
  ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
done

# zshをデフォルトのシェルに設定する
🍅 chsh -s /usr/bin/zsh

作成された ~/.zshrc\# Customize to your needs... 以下に次のように追記する。

~/.zshrc
# zsh
autoload -Uz promptinit
promptinit
prompt pure

# Windows側VS code ([username] は自身のユーザー名に置換)
alias code="'/mnt/c/Users/[username]/AppData/Local/Programs/Microsoft VS Code/bin/code'"

AlmaLinux 8 からログアウトおよび再ログイン。

🍅 Apptainer環境

NVIDIA Container Toolkitのインストール

Apptainer のコンテナ内部の CUDA を参照して GPU を利用するために、以下の公式ドキュメントを参考にして NVIDIA Container ToolkitAlmaLinux 8 にインストールする。
NVIDIA Cloud Native Technologies | NVIDIA CONTAINER TOOLKIT: Installation Guide

ちなみに AlmaLinux 8 の項目はないため、CentOS 8 の項目を参考にする。

# Setup the repository and the GPG key
🍅 curl -s -L https://nvidia.github.io/libnvidia-container/centos8/libnvidia-container.repo | sudo tee /etc/yum.repos.d/nvidia-container-toolkit.repo

# Install nvidia-container-toolkit package
🍅 sudo dnf clean expire-cache --refresh
🍅 sudo dnf install nvidia-container-toolkit

Setup the repository and the GPG key のところ、公式では自動的にディストリビューション情報を読むように distribution=$(. /etc/os-release;echo $ID$VERSION_ID) としているが、上述のように AlmaLinux 8 用には用意されていないので、curl のURLに centos8 を自分で指定するように改変している。

📌 Ubuntu (ver. 22.04) の場合

# Configure the production repository
🍅 curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
  && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

# Install the NVIDIA Container Toolkit packages
🍅 sudo apt update
🍅 sudo apt install nvidia-container-toolkit

Apptainerのインストール

Apptainer を以下の公式ドキュメントに従ってインストールする。
Apptainer Admin Guide | Installing Apptainer

# EPELリポジトリを使えるようにする
🍅 sudo dnf install epel-release
🍅 sudo dnf update

# Apptainerのインストール
🍅 sudo dnf install apptainer

apptainer-suid は特別必要がなければセキュリティ的にも基本的にはインストールしなくてよさそう。

Setuid & User Namespaces

Using a setuid binary to run container setup operations used to be essential to support containers on the older Linux distributions that were previously common in HPC and enterprise.

Most distributions now have support for unprivileged user namespaces. This means a normal, unprivileged user can create a user namespace, in which most operations needed to run a container can be run.

Apptainer still supports running containers with a setuid starter, but by default it runs containers without setuid, using user namespaces. If user namespaces are available when compiling, the --without-suid option is implied. If user namespaces are not available when compiling, the installer must choose between --with-suid and --without-suid . Packages are compiled with --with-suid but then the setuid component is not installed by default and the installer must separately install the apptainer-suid package if setuid mode is desired.

Apptainer User Guide | Security in Apptainer

📌 Ubuntu (ver. 22.04) の場合

# リポジトリの追加
🍅 sudo add-apt-repository -y ppa:apptainer/ppa
🍅 sudo apt update

# Apptainerのインストール
🍅 sudo apt install apptainer

Apptainerの動作テスト

Apptainer の動作テストとして OmegaFold 実行コンテナを作成および実行してみる。
GitHub | OmegaFold

コンテナイメージの保管場所を作成する

自分の環境では ~/apps/apptainer_image.sif コンテナイメージを、その下の def_file ディレクトリに .def ファイルを配置している。

以下、$HOME/home/almalinux_v8 と仮定して記載する。

以下のコマンドで .sif イメージと def ファイルの置き場所を作る

# .sifイメージと.defファイルの置き場所を作る
🍅 mkdir -p ~/apps/apptainer_image/def_file

~/.zsharc に以下のように追記する。

~/.zshrc
# Apptainer
export APPTAINER_IMAGE="/home/almalinux_v8/apps/apptainer_image"
export PATH="${APPTAINER_IMAGE}:${PATH}"

OmegaFold実行コンテナをビルドする

${APPTAINER_IMAGE}/def_fileOmegaFold 実行コンテナのビルドレシピ OmegaFold.def を以下の内容で作成する。

${APPTAINER_IMAGE}/def_file/OmegaFold.def
BootStrap: docker
From: nvidia/cuda:11.7.1-cudnn8-devel-ubuntu22.04

%post
  # localtime関係のWARNINGに対処
  touch /etc/localtime
  
  # リポジトリを富山大学に変更
  sed -i.bak -e 's|archive.ubuntu.com|ubuntutym.u-toyama.ac.jp|g' /etc/apt/sources.list

  # OmegaFoldに必要なパッケージのインストール
  apt update && apt upgrade -y
  apt install -y build-essential python3 python3-venv git curl
  
  # localeにen_US.UTF-8を追加する (WSL2だけで使用するなら不要)
  apt install -y locales
  locale-gen en_US.UTF-8
  
  # OmegaFoldのインストールディレクトリの作成・移動
  mkdir -p /usr/local/apps/OmegaFold/weight
  cd /usr/local/apps/OmegaFold
  
  # /usr/local/apps/OmegaFoldにPython仮想環境.venvを作成しアクティベート
  python3 -m venv .venv
  . ./.venv/bin/activate
  
  # Python仮想環境内にpipでOmegaFoldをインストール
  python3 -m pip install --upgrade pip
  python3 -m pip install git+https://github.com/HeliXonProtein/OmegaFold.git
  
  cd /usr/local/apps/OmegaFold/weight
  curl -L -O https://helixon.s3.amazonaws.com/release1.pt

%environment
  # OmegaFold用のPython仮想環境をアクティベート
  export OMEGAFOLD_HOME="/usr/local/apps/OmegaFold"
  . ${OMEGAFOLD_HOME}/.venv/bin/activate

%runscript
  # コンテナ内にダウンロードしたweightを参照してOmegaFoldを実行する
  # "$@"でomegafoldの引数を利用するための設定
  omegafold --weights_file ${OMEGAFOLD_HOME}/weight/release1.pt "$@"
  

次に以下のコマンドで OmegaFold 実行コンテナ OmegaFold.sif をビルドする。

# OmegaFold実行コンテナのビルド
🍅 cd ${APPTAINER_IMAGE}
🍅 apptainer build ./OmegaFold.sif ./def_file/OmegaFold.def

--fakeroot オプションがなくても動くようになっていたけどなぜ? ( Apptainer では .def ファイルからビルドする場合に勝手に --fakeroot オプションがつく仕様らしい)

OmegaFoldの実行

適当な蛋白質のアミノ酸配列が記載された .fasta ファイルを用意する (ここでは test.fasta とする)。

以下のコマンドで OmegaFold を実行する。

# OmegaFoldの実行 (test.fastaのある場所で)
🍅 apptainer run --nvccli ${APPTAINER_IMAGE}/OmegaFold.sif ./test.fasta ./test

~/.zshrc に以下を追記して OmegaFold 用の alias を作成すると便利。

~/.zshrc
# OmegaFold
alias omegafold="apptainer run --nvccli --bind /mnt/d:/mnt/d ${APPTAINER_IMAGE}/OmegaFold.sif"

--bind /mnt/d:/mnt/d オプションをつけることで、Windows のDドライブ内のファイルについても OmegaFold.sif のコマンドを実行できるようになる。

Discussion