Singularity日常使用
Singularity 介绍
Singularity容器技术在功能上类似于Docker,使用上与Docker略有不同。Docker用户可以轻松上手使用。用户访问网站 (https://sylabs.io/guides/3.7/user-guide/introduction.html) 可以了解详细使用方法。这里仅仅结合Docker介绍一下Singularity的日常使用方法。 Singularity与Docker的一个很大区别是生产环境使用的Singulariy容器是只读的SIF格式文件。用户可以将Hub上的容器存储成本地的SIF文件运行,确保Singularity容器执行的可重复性。这意味着SIF容器一旦创建并签名,运行时不发生改变。Docker容器由于镜像的管理方式,往往不能确保可重复性。
Singularity 技术几个重要概念
- 容器(container): 容器是一个包含用户软件和依赖的镜像系统,可独立运行某一条或者多条命令。Singularity没有镜像的概念,用户创建和运行的都是一个一个容器。
- SIF(Singularity Image File):压缩后的只读(read-only)的Singularity镜像文件,是生产使用的主要形式。
- Sandbox :可写(writable)的容器存在形式,是文件系统中的一个目录,常用于开发或者创建自己的容器,是开发使用的主要形式。
构建自己的容器
Singularity容器有两种存在形式:SIF和sandbox。SIF只读,主要用来执行用户程序。sandbox可修改,可用来开发和创建新容器。用户可以通过三种方式创建自己需要的容器。
方法一: 从外部源下载容器
用户可通过singularity pull
或singularity build
命令从外部容器仓库下载容器到本地,存储为SIF文件。用户通过指定不同的容器的URI,从不同的源下载容器。
例如用户可以通过如下的命令从Docker Hub(存储标准的Docker镜像)下载容器,自动转换成Singularity容器,存储为SIF格式:
singularity build ./jason-tensorflow.sif docker://tensorflow/tensorflow:latest-gpu
# 或者
singularity pull ./jason-tensorflow.sif docker://tensorflow/tensorflow:latest-gpu
用户也可使用其它类型的URI(源)下载容器:
singularity build lolcow.sif library://sylabs-jms/testing/lolcow # 从Container Library
singularity pull hello.sif shub://vsoch/hello-world # 从Singularity Hub下载容器
方法二: 手动定制
用户常常不能直接使用外部源提供的容器,需要进行手动定制。用户可将外部容器下载为sandbox格式,然后本地修改,再build成生产使用的只读SIF格式。通过下述例子说明向一个标准的tensorflow的Docker容器添加脚本,定制自己的SIF容器。
#步骤1: 从Docker Hub下载Tensorflow GPU镜像,存储为本地sandbox
singularity build --sandbox sandbox docker://tensorflow/tensorflow:latest-gpu
#步骤2: sandbox目录为可修改的容器,可以直接进行修改
mkdir sandbox/opt/train -p
cp train.sh sandbox/opt/train
...
#步骤3: 从修改后的sanbox生成只读的SIF格式容器,用于生产
singularity build jason-tf.sif sandbox/
上述步骤2中,用户也可以选择以可写(writable)方式运行容器,进行修改。
#步骤1: 从Docker Hub下载Tensorflow GPU镜像,存储为本地sandbox
singularity build --sandbox sandbox docker://tensorflow/tensorflow:latest-gpu
#步骤2: 从sandbox以可修改的方式运行容器,进行修改和定制
singularity shell --writable sandbox/
...
#步骤3: 从修改后的sanbox生成只读的SIF格式容器,用于生产
singularity build jason-tf.sif sandbox/
方法三: 通过Definition文件制作容器
Singularity支持用户编写Definition文件创建容器,详细的指令参考链接 (https://sylabs.io/guides/3.7/user-guide/definition_files.html) 。为了创建上述Tensorflow的容器,用户可以编写下述jason_tf.def
文件。
Bootstrap: docker
From: tensorflow/tensorflow:latest-gpu
Stage: build
%files
/var/py/train.py /opt/train.py
%labels
Author jason.zhang@xtaotech.com
Version v0.0.1
%help
This is a demo container used to illustrate a def file that uses all
supported sections.
编写好自己的def文件,通过运行下述命令产生SIF格式的容器用于生产。
singularity build jason-tf.sif jason_tf.def
运行容器
运行一个程序
用户可通过singularity exec
命令运行一个容器内的程序,程序执行完毕,容器退出。类似于docker run
命令。
singularity exec jason-tf.sif python /opt/train.py
运行容器中默认命令
用户运行singularity run
命令会执行singularity 镜像默认的 runscript
命令,例如
[root@host] singularity run jason-tf.sif
________ _______________
___ __/__________________________________ ____/__ /________ __
__ / _ _ \_ __ \_ ___/ __ \_ ___/_ /_ __ /_ __ \_ | /| / /
_ / / __/ / / /(__ )/ /_/ / / _ __/ _ / / /_/ /_ |/ |/ /
/_/ \___//_/ /_//____/ \____//_/ /_/ /_/ \____/____/|__/
WARNING: You are running this container as root, which can cause new files in
mounted volumes to be created as the root user on your host machine.
To avoid this, run the container by specifying your user's userid:
$ docker run -u $(id -u):$(id -g) args...
Singularity> python /opt/test.py
2021-06-01 11:04:46.541868: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudart.so.11.0
2021-06-01 11:04:48.771502: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 AVX512F FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2021-06-01 11:04:48.781848: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcuda.so.1
2021-06-01 11:04:48.781898: E tensorflow/stream_executor/cuda/cuda_driver.cc:328] failed call to cuInit: UNKNOWN ERROR (34)
2021-06-01 11:04:48.781926: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:169] retrieving CUDA diagnostic information for host: Cc5Apc
2021-06-01 11:04:48.782068: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:176] hostname: Cc5Apc
2021-06-01 11:04:48.782135: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:200] libcuda reported version is: Not found: was unable to find libcuda.so DSO loaded into this program
2021-06-01 11:04:48.782180: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:204] kernel reported version is: 455.23.5
[name: "/device:CPU:0"
device_type: "CPU"
memory_limit: 268435456
locality {
}
incarnation: 17604286807710674827
]
Singularity>
交互式启动容器运行命令
用户运行singularity shell
命令可以交互式的方式运行容器,执行一系列命令。这种执行方式与docker run -it
类似。例如:
[root@host] singularity shell jason-tf.sif
INFO: Using cached SIF image
Singularity>
如何映射和访问存储卷
Singularity容器与Docker容器最大区别是生产使用的SIF格式容器是只读的。容器启动的时候,singularity
命令自动挂载一些主机的目录到容器($HOME , /sys:/sys , /proc:/proc, /tmp:/tmp, /var/tmp:/var/tmp, /etc/resolv.conf:/etc/resolv.conf, /etc/passwd:/etc/passwd, 和 $PWD)。如果需要访问主机上的其它目录或者挂载的存储卷,用户需要使用--bind
选项映射主机目录到容器内。
singularity exec --bind /mnt/nfs:/mnt/nfs jason-tf.sif python /opt/test.py