日本語 English
世界中のHPC専門最先端技術製品の販売・サポート

スパコン生まれのコンテナ実装 Singularity -2-

「コレ、RHEL/Ubuntuじゃん!」

HPC/AIを日々使うユーザーなら一度は口(耳)にしたことがある言葉ではないでしょうか?ディストリビューションこそ同じでも、バージョンが違えば内部構成は大きく違ってきます。それゆえ使いたいアプリケーションに対応できないケースが頻発します。そうした場合、必要な環境をどうやって用意すればよいでしょうか?

かつては開発元からソースのtar ballをダウンロードして来たり、今なら多くはgit cloneしてビルドしてインストールすることになります。しかし、ビルド自体に必要なツールやライブラリ、コンパイラのバージョンまで合わせる必要があったりと、芋づる式に作業が増え、だんだん何をしたかったのか訳が分からなくなってきます。ようやく目的のものが出来上がっても、他のツールの利用に支障がでたり、手元の環境でrootで作業している場合など、システムを損壊しているケースもあります。その後に動作確認やベンチマークによる性能を確認し、得られた結果の再現性もチェックします。状況によっては最初からやり直しになることもあります。実行環境を含めたアプリケーション環境の構成とは、かように骨の折れる仕事になります。複数のアプリケーションや、バージョンを共存させようとすると、さらに別のギミックが必要になります。

一部のインテグレータはそうした作業をサービスとして販売していますし、昨今では動作環境の構築手順をリポジトリ等で共有したり、内容をレシピと呼ばれるJSON等のファイルで記述して、半自動的に動作環境を再現してくれるツール(Spack等)があります。多用されるPythonに限ってみても、ディストリビューションによるパッケージ、pip を使ってシステムやユーザー環境にばらばらにインストールされたパッケージ群、pyenv, anaconda等による環境切り替えなど多岐に渡っており、自分がどれを使っているのか訳が分からなくなっているケースを散見します。こうした場合、動作環境そのものを個別に分離して管理し、システム毎の相性を排除できるコンテナを利用する方が、ずっと有利かつ安心でしょう。また、コンテナの場合は出来上がったイメージや、それを再現する定義ファイルをリポジトリにおいて配布するというフローが標準的に用意されています。

Singularityをインストールする

Singularityの主な開発者を擁するSylabs社からは、無償のオープンソース(BSDライセンス)であるCE(CommunityEdition)版と、有償サポート付きのPRO版を提供しています。もちろん基本的な使い勝手は変わりません。一方で脆弱性対応などセキュリティ問題については、CE版は最新版にのみ対策が取られるため、機能や仕様を維持したままセキュリティ対応が必要な場合はPRO版の導入を検討してください。またHPCngというコミュニティのリポジトリがしばらくコミュニティ版として運用されて来ましたが、2021年5月にプロジェクトをフォークしています。しばらく混乱しそうですが、弊社としてはSylabs社の仕様を標準として取り扱います。フォーク自体は3.8のリリース直前だったので現時点では機能的にほぼ同一です。

既にPRO版を導入されている環境の場合はそのままお使いいただき、手元の環境に管理者権限があれば公開リポジトリにある通りの方法でビルドしてインストールします。Golangの導入さえできれば先述のような困難はありません。権限を持っていない一般ユーザーがホームディレクトリへインストールしても、一部の機能を除いて利用可能です。RHEL/CentOSの場合はEPELリポジトリに最新ではないもののパッケージがありますが、UbuntuのuniverseリポジトリにあるSingularityは同名のゲームですのでご注意ください(筆者はプレイしたことありません)。またWSLではカーネルの問題で、イメージ変換の一部は可能ですが、肝心のコンテナ実行ができません。

まずイメージを作って実行してみる

SingularityのイメージはSIF(Singularity Image Format)という独自のシングルファイル形式と、それを手元のファイルシステムに展開したsandbox形式の2種類となっています。一方、その元になるイメージとしては配布されているさまざまなイメージを再利用できます。またSingularityは以下のメジャーなリポジトリから直接イメージを取得して利用することができます。

ここではCentOS7の環境上で、DockerHubからUbuntu21.04LTSのイメージを取得して使ってみます。

$ singularity version 
3.7-4.el7
$ singularity pull docker://ubuntu:21.04
INFO: Converting OCI blobs to SIF format
INFO: Starting build…
Getting image source signatures
Copying blob 966b3c5c8637 done
Copying config 7077954789 done
Writing manifest to image destination
Storing signatures
2021/07/19 17:01:13 info unpack layer: sha256:966b3c5c8637e41360eed39a59e6c16ee1e986f7f2b92244e4d39f7ca6669618
INFO: Creating SIF file…
$ ls -l ubuntu_21.04.sif
-rwxrwxr-x 1 pteck pteck 30900224 Jul 19 17:01 ubuntu_21.04.sif

単純にDockerのイメージを取得し、SIF形式に変換して保存します。pull サブコマンドの次に次のようにファイル名を指定することもできます。

$ singularity pull hippo.sif docker://ubuntu:21.04

できたイメージは意外なほど小さいことにお気づきでしょうか。SIFは内部でSquashFSという圧縮ファイルシステムを利用しており、デフォルトではgzip圧縮がかかっているためです。それではコンテナを起動し、その中で何らかの処理を実行してみましょう。

$ head -n 2 /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"

$ singularity exec hippo.sif head -n 2 /etc/os-release
NAME="Ubuntu"
VERSION="21.04 (Hirsute Hippo)"

$ singularity exec hippo.sif dpkg -l bash
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-============-============-=================================
ii bash 5.1-2ubuntu1 amd64 GNU Bourne Again SHell
$ rpm -q bash
bash-4.2.46-34.el7.x86_64

CentOS7の中にいるにも関わらず、hippo.sifにインストールされているUbuntu 21.04の内容が見えています。つまりこのコンテナの中ではユーザーはUbuntuの環境で作業ができます。ただし、コンテナはOSそのものを入れ替えているわけではないので、カーネルはCentOS7のままです。試してみます。

$ uname -r
3.10.0-1160.15.2.el7.x86_64
$ singularity exec hippo.sif uname -r
3.10.0-1160.15.2.el7.x86_64

確かに同一のカーネルです。このためカーネルバージョンに依存するプログラムなどでは問題が生ずることがあります。

イメージの直接実行とユーザー・プロセス空間

さて、ここからがSingularityの主な特徴であるイメージファイルがシングルファイルで、かつ直接実行可能ということを示します。

$ ./hippo.sif head -n 2 /etc/os-release
NAME="Ubuntu"
VERSION="21.04 (Hirsute Hippo)"

そして、デフォルトでは起動したユーザーがコンテナ内に引き継がれており、ホームディレクトリも共有されていて、コンテナの外と同様に使うことができます。また、プロセス情報もコンテナの内外で同様に確認できます。以下のようにして試してみましょう。

$ ./hippo.sif ls -l ~
total 125776
drwx--x--x. 26 pteck pteck  4096 Jul 13 16:11 .
drwxr-xr-x   1 pteck pteck    60 Jul 19 17:19 ..
-rw-------   1 pteck pteck 16518 Jul 19 11:19 .bash_history
-rw-r--r--.  1 pteck pteck    40 Oct 30  2020 .bash_logout
-rw-r--r--.  1 pteck pteck   234 Oct 27  2020 .bash_profile
-rw-r--r--.  1 pteck pteck   274 Nov 27  2020 .bashrc
drwxrwxr-x.  8 pteck pteck    86 Mar 25 10:43 .cache
.......

$ ./hippo.sif ls -l ~/..
total 4
drwx--x--x. 26 pteck pteck 4096 Jul 13 16:11 pteck 

$ ./hippo.sif tail /etc/passwd
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
pteck:x:1000:1000:Pacific Teck Japan:/home/pteck:/bin/bash

このようにホームディレクトリは自身のものだけが取り込まれており、他のユーザーについてはホームディレクトリのみならず、ユーザー名も引き継がれません。他のユーザーのホームディレクトリへシンボリックリンクがあっても、コンテナ内ではリンク切れとなりますのでご注意ください。

$ ./hippo.sif sleep 120 &
[1] 30871
$ ps gux
USER  PID   %CPU %MEM VSZ    RSS   TTY   STAT START TIME COMMAND
pteck 11166  0.0  0.0 139208 25700  tty1  Ss  Jun08 0:00 -bash
pteck 27618  0.0  0.0 173904  2528     ?   S  16:06 0:00 sshd: pteck@pts/0
pteck 27619  0.0  0.0 139352 26048 pts/0  Ss  16:06 0:00 -bash
pteck 30871  1.3  0.0 903344 19512 pts/0  Sl  17:30 0:00 Singularity runtime parent
pteck 30885  0.3  0.0   2520   692 pts/0   S  17:30 0:00 /usr/bin/sleep 120
pteck 30904  0.0  0.0 155452  1876 pts/0  R+  17:30 0:00 ps gux

プロセス空間も同一になるので、このようにコンテナの中と外のプロセスをどちらからも透過的に見ることができます。

まとめ

今回はSingularityを使ってDockerHubにあるイメージからSIFイメージを作成・実行して、Singularityの基本的な動作を見てみました。

次回はこれにカスタマイズを入れて、独自イメージの作成を実施してみます。