HPCシステムズではエンジニアを募集しています。詳しくはこちらをご覧ください。
HPCシステムズのエンジニア達による技術ブログ

Tech Blog

UBIとSingularityと

UBIとは

先日Redhat Enterprise LInux 8がリリースされました。使い勝手の面ではあまり変わりませんが、内部的に多くの更新や変更がはいっており、期待が高まるところです。ところで、同時に発表されたUniversal Base Image(UBI)が話題になっています。これはコンテナ専用のOSイメージで、Redhat社の公式OSイメージであるにも関わらず無償で提供され、再配布まで可能になっています。そのため、自分でコンテナイメージを作る必要がなく、拾ってきたイメージに何かが仕込まれているといった懸念もありません。サブセットながら公式のリポジトリがあり、yumやdnfでアップデート可能なため、コンテナ内のシステムの更新が保証されています。

現時点ではRHEL7/8ベースで、素のイメージの他、PythonやNode.jsなど、いくつかの言語対応済みのイメージが公開されています。8限定ですが、.NET Core 対応イメージがあるのが時代を感じさせます。

Singularityについて

スパコン等のHPC環境で使うことを念頭に開発されたコンテナ実装です。昨年NVIDIAのNGCでサポートが発表され、今月3.2がリリースされ、ますます機能も使い勝手も充実してきました。イメージを1ファイルで作り、直接実行が可能です。実行ユーザーアカウント及びそのホームディレクトリをコンテナ内で共有するデフォルト仕様のため、コンテナを使っているということをユーザーは意識することなく、普通のアプリを使う感覚で動作確認済み環境を同梱したコンテナ内でアプリが使用できます。また、rootを共有しないため、管理者としても安心して使わせることができます。

マルチテナントを意識し、コンテナの内外を完全分離してセキュリティを担保しようとしたDockerとは根本的に方針が違います。

Singularityインストール

インストール方法にあるやり方でまず確実に入りますが、RHEL/CentOS7用のRPMパッケージ(無保証)を作成しております。ダウンロード後、yum install singularity-3.2.1-1.el7.x86_64.rpmとしてインストールしてください。インストールできたらsingularity versionとして3.2.1と出れば完了です。

以下は私の普段遣いの環境であるUbuntu19.04上で行っています。

UBI8のイメージ作成

dockerリポジトリから直接イメージ作成するだけであれば、一般ユーザーでもコマンド一発でイメージ作成ができます。RHEL8ベースでPython3.6セットアップ済みイメージは以下でできます。

$ singularity pull ubi8-python36.sif docker://registry.access.redhat.com/ubi8/python-36
INFO:    Starting build...
Getting image source signatures
<<<ダウンロード中略>>>
Writing manifest to image destination
Storing signatures
INFO:    Creating SIF file...
INFO:    Build complete: ubi8-python36.sif

出来上がったubi8-python36.sifの中身を見てみましょう。

$ singularity exec ubi8-python36.sif cat /etc/redhat-release
Red Hat Enterprise Linux release 8.0 (Ootpa)
$ singularity exec ubi8-python36.sif python3 -V
Python 3.6.8

確かにRHEL8ベースのようです。ここでSingularityの特徴の一つである、コンテナの中から外へアクセスできることを確認します。

$ singularity exec ubi8-python36.sif pwd
/home/hpcs/Singularity
$ singularity exec ubi8-python36.sif ls -l
-rwxr-xr-x  1 hpcs users      2038 May 23 15:32 sample.txt
-rwxr-xr-x  1 hpcs users 232947712 May 23 17:15 ubi8-python36.sif
$ singularity exec ubi8-python36.sif file *
sample.txt:        ASCII text
ubi8-python36.sif: a /usr/bin/env run-singularity script executable (binary data)
$ singularity exec ubi8p-python36.sif ps gux |grep firefox
hpcs     10002  1.3  3.6 2720336 595824 tty2   Sl+  May20  63:30 /usr/lib/firefox/firefox

コンテナからシームレスにホームディレクトリへアクセスできています。また、ユーザー権限やプロセス情報も共有されています。また、/dev以下が見えているのでディスクなどのデバイスへもアクセスできますし、ネットワークも直接共有されています。

カスタムイメージの作成

ここまでは、作り付けのイメージでしたが自身でカスタムしたオリジナルイメージを作成します。それには、基本的に2つの方法があります。

  1. Sandboxイメージを作成したのち、カスタムを施してそれをベースにsifイメージ作成。
  2. 定義ファイル(レシピ)を作成してsifイメージをビルド。

ここでは定義ファイルを使う方法を試します。インストールするアプリとしてはLAMMPSとします。ターゲットとするOSはUBI8なので、一通り最新で揃えてみましょう。ただし、コンパイラはOS標準のgcc-g++とします。MPIはOpenMPI-4.0.1, LAMMPSはpatch_30Apr2019です。定義ファイルは以下のようなものを作成しました。

Bootstrap: docker
From: registry.access.redhat.com/ubi8/ubi

%post
  dnf -y install cmake gcc-c++ zlib-devel diffutils make wget git bzip2
  dnf mark install openssh-clients libgomp libmpc

  BUILDDIR=/tmp/build-lammps

  rm -rf ${BUILDDIR}; mkdir -p ${BUILDDIR}
  cd ${BUILDDIR}

  wget https://www.open-mpi.org/software/ompi/v4.0/downloads/openmpi-4.0.1.tar.bz2
  tar xvfj openmpi-4.0.1.tar.bz2
  cd openmpi-4.0.1
  ./configure --prefix=/usr/local && make -j 12 && make install

  cd ${BUILDDIR}
  git clone -b 'patch_30Apr2019' https://github.com/lammps/lammps.git
  mkdir lammps/build; cd lammps/build
  cmake -D PKG_OPT=yes -D PKG_POEMS=yes -D PKG_MANYBODY=yes ../cmake
  make -j 12 && cp lmp /usr/local/bin/

  rm -rf ${BUILDDIR}
  dnf -y remove cmake make wget git bzip2 *-devel
  dnf clean all

%environment
  export LD_LIBRARY_PATH=/usr/local/lib:${LD_LIBRARY_PATH}
  export OMP_NUM_THREADS=${OMP_NUM_THREADS:-1}

%labels
  Author HPCS-TechBlog
  Version 0.01

%help
  UBI8 from Red Hat; OpenMPI-4.0.1 ; LAMMPS patch_30Apr2019  

%runscript
  /usr/local/bin/lmp $@

このファイルをubi8_lammps.defとして保存します。パッケージとしてはOPT, POEMS, MANYBODYを有効にしています。また、内部ではビルドを12並列で行っていますが、環境に合わせて適当に変更してください。

ありもののdockerイメージを持ってきただけの先程と違い、手元の環境でイメージをビルドするにはroot権限が必要です。Singularity開発元であるSylabsのクラウドサービスを使ってリモートでビルドすることもできますが、現時点では無償利用には制限があります。

# singularity build u8l.sif ubi8_lammps.def

これでイメージの取得から開発環境のインストール、OpenMPIのダウンロード・ビルド・インストール、LAMMPSの取得・ビルド、インストールまで完了します。

実行

コンテナ内のビルド環境は削除してしまっているので、配布されているexampleインプットや必要であればポテンシャルファイルは別途用意してください。簡単なのでin.meltを実行してみましょう。

$ singularity exec u8l.sif /usr/local/bin/lmp -i in.melt
LAMMPS (12 Dec 2018)
using 1 OpenMP thread(s) per MPI task
Lattice spacing in x,y,z = 1.6796 1.6796 1.6796
Created orthogonal box = (0 0 0) to (16.796 16.796 16.796)
1 by 1 by 2 MPI processor grid
Created 4000 atoms
Time spent = 0.000614967 secs
Neighbor list info ...
update every 20 steps, delay 0 steps, check no
・・・・・

以下のようにすればMPIを使った並列計算もできます。

$ singularity exec u8l.sif mpirun -np 4 /usr/local/bin/lmp -i in.melt

さて、sifイメージは%runscriptを指定していると、そのまま実行ファイルとして扱うことができます。やってみましょう。

$ ./u8l.sif -i in.melt

どうでしょうか?ちゃんと計算できたと思います。つまり、イメージファイルを実行ファイルと同名にしてしまえば、ユーザーはこれがコンテナだとは気づかないかもしれません。この使い方のままMPI並列をするのは難しいのですが、それは別の機会に。