Singularity 容器技术介绍.md

参考文档链接:

sylabs/singularity: SingularityCE is the Community Edition of Singularity, an open source container platform designed to be simple, fast, and secure. (github.com)

SingularityCE User Guide — SingularityCE User Guide 4.1 documentation (sylabs.io)

北鲲云 Singularity 基本使用 | 用户手册 (bkunyun.com)

武汉大学运行 Singularity · GitBook (whu.edu.cn)

Singularity 使用 - 北京大学高性能计算校级公共平台用户文档 (pku.edu.cn)

Apptainer/Singularity使用方法记录 - 我的小破站 (shelven.com)

简介

生物信息中的分析流程往往需要消耗很大的内存,读写以TB计算的数据,属于典型的高性能计算(HPC)应用。生信分析流程中要调用大量的分析程序以及内部开发脚本,环境的配置与管理极为复杂,可重复性低,导致流程的升级、管理、迁移成为大难题。

为了规避软件与现有环境依赖冲突,我们往往会把一个pipeline的软件封装到一个容器中。容器技术是一种以应用软件为中心的虚拟化技术。以应用软件为单元,将软件及所有的依赖打包成容器镜像,启动时与宿主节点共享操作系统内核,打包后的容器镜像可直接拷贝到不同的Linux主机上运行。通过容器技术,可以很好的解决安装软件时,依赖库的安装问题、软件环境的隔离以及软件环境的移植问题。

镜像(Image):可执行的独立软件包,用于保存环境

实例(Instance):基于镜像启动的运行实例,运行实际任务,不同实例之间互相隔离

由于镜像文件自带了可执行文件和依赖库,因此不需要用到宿主机的依赖库,也就从源头上避免了环境冲突的情况。听起来这种实现方式类似于虚拟化技术,但还是有一些区别的:前面说过容器启动时与宿主机共享操作系统内核,没有运行独立的操作系统任务,在资源的占用上明显低于虚拟机。虚拟化可以认为它更全面和彻底一些,每个虚拟机从宿主机的物理框架中分割出来,有自己的一整套操作系统,会运行各种独立的操作系统任务,即使没有运行程序也会消耗内存和系统资源。

特性 容器 虚拟机
隔离 容器通常提供与主机和其他容器的轻度隔离,但容器不像虚拟机那样提供强大的安全边界。 虚拟机提供与主机操作系统和其他虚拟机的完全隔离。当强大的安全边界至关重要时(例如,在相同服务器或群集上托管来自竞争公司的应用),这种分离非常有用。
操作 容器运行操作系统的用户模式部分,可以对其进行定制,使之只包含应用所需的服务。此方法可以帮助你使用更少的系统资源。 虚拟机运行包含内核的完整操作系统,这需要更多的系统资源(CPU、内存和存储)。
部署 可以通过命令行使用Docker部署单个容器。可以使用Azure Kubernetes服务等业务流程协调程序部署多个容器。 可以使用Windows Admin Center或Hyper-V管理器部署单个虚拟机。可以使用PowerShell或System Center Virtual Machine Manager部署多个虚拟机。
永久性存储 容器使用Azure磁盘作为单个节点的本地存储,或将Azure文件存储(SMB共享)用于由多个节点或服务器共享的存储。 虚拟机将虚拟硬盘(VHD)用于单个计算机的本地存储,或将SMB文件共享用于多个服务器共享的存储。
容错 如果某个群集节点发生故障,则在该节点上运行的所有容器都将在另一个群集节点上由业务流程协调程序快速重新创建。 虚拟机可以故障转移到群集中的另一台服务器,而虚拟机的操作系统将在新服务器上重启。

上表来自Microsoft Azure容器与虚拟机的比较。总结来说,在安全性和隔离性上虚拟机优于容器,在资源占用、可移植性和运行速度上,容器优于虚拟机。

现有的容器软件比较多,Docker(5.8k star)是代表性的软件之一,其他开源容器化工具还有Podman(17.4k star,无守护进程的容器技术,无需root权限)、LXD(3.8k star,可运行多个进程)、Apptainer(以前叫singularity,2.4k star,无需root权限)、Containerd(13.5k star)和RunC(10.1k star)等。

然而生信分析集群和普通的IT服务器又有很大区别,如开发人员无root权限,分析任务需要进行资源管理(内存,CPU)。这些问题都让Docker技术在HPC环境的应用受限,Singularity因此应运而生。

Singularity 为劳伦斯伯克利国家实验室开发专门用于高性能计算场景的容器技术,Singularity 完全基于可移植性进行虚拟化,更加轻量级,部署更快,Singularity 目前被广泛地各高性能计算中心。

安装

软件包安装

直接访问github发布页:https://github.com/sylabs/singularity/releases

下载对应系统的安装包进行安装

编译安装

先决依赖

在基于 Debian 的系统上,包括 Ubuntu:

# Ensure repositories are up-to-date
sudo apt-get update
# Install debian packages for dependencies
sudo apt-get install -y \
   autoconf \
   automake \
   cryptsetup \
   git \
   libfuse-dev \
   libglib2.0-dev \
   libseccomp-dev \
   libtool \
   pkg-config \
   runc \
   squashfs-tools \
   squashfs-tools-ng \
   uidmap \
   wget \
   zlib1g-dev

在 RHEL / CentOS 版本 7 上:

# Install basic tools for compiling
sudo yum groupinstall -y 'Development Tools'
# Install RPM packages for dependencies
sudo yum install -y \
   autoconf \
   automake \
   cryptsetup \
   fuse3-devel \
   git \
   glib2-devel \
   libseccomp-devel \
   libtool \
   runc \
   squashfs-tools \
   wget \
   zlib-devel

安装GO

GO下载:All releases - The Go Programming Language

可以示例命令操作,根据需要替换特定值,这里下载一个linux的x86-64平台:

export VERSION=1.21.0 OS=linux ARCH=amd64 && \
  wget https://dl.google.com/go/go$VERSION.$OS-$ARCH.tar.gz && \
  sudo tar -C /usr/local -xzvf go$VERSION.$OS-$ARCH.tar.gz && \
  rm go$VERSION.$OS-$ARCH.tar.gz

设置环境变量

echo 'export PATH=/usr/local/go/bin:$PATH' >> ~/.bashrc && \
  source ~/.bashrc

下载源码包

export VERSION=4.1.0 && \
    wget https://github.com/sylabs/singularity/releases/download/v${VERSION}/singularity-ce-${VERSION}.tar.gz && \
    tar -xzf singularity-ce-${VERSION}.tar.gz && \
    cd singularity-ce-${VERSION}

编译

./mconfig && \
    make -C builddir && \
    sudo make -C builddir install

镜像获取

Singularity包括两种格式文件

  • sif:一个压缩的只读Singularity Image File(SIF)格式,适合直接使用(默认)
  • sandbox:一个可写目录,称为沙盒,用于交互式开发(需要添加--sandbox选项)

云平台镜像下载

现在有很多计算软件已经将容器镜像制作好了,存储在一些云平台上,只需要直接下载使用即可。在需要使用容器的时候,可以先在云平台上搜索是否已经有制作好的镜像,如果没有,再考虑自行制作容器镜像。

Singularity 支持很多云平台,用户可以在云平台上搜索,并下载所需镜像

build/pull 这两个命令都可以拉取镜像文件,第一个参数指定容器的路径和名称,第二个参数提供要从中下载的容器库 URI

Sylabs Cloud

singularity pull ubuntu.sif library://library/default/ubuntu:21.04

Docker Hub 是 Docker 的镜像云平台,singularity 程序会将 docker 格式转换为 singularity 使用的 .sif 格式

singularity pull ubuntu.sif docker://ubuntu:latest

Singularity Hub

singularity pull singularity-images.sif shub://vsoch/singularity-images

支持 ORAS 的 OCI 镜像云平台

singularity pull image.sif oras://registry/namespace/image:tag

交互式shell制作

build可以制作两种格式(sif/sandbox)文件,之间可以相互转化

在沙盒中交互操作时,最好以 root 身份执行,也可以使用--fakeroot的模拟root用户(对系统有要求)

lammps示例

# 以沙盒的形式创建,使用docker hub上现有的容器 ubuntu:20.04 作为基础镜像,放在ubuntu20_lammps这个沙盒中
singularity build --sandbox ./ubuntu20_lammps docker://ubuntu:20.04

# 进入创建好的沙盒,并进行修改;
# 其中-w表示可写。进入后singularity会自动挂载的HOME目录,如果是用root用户进入,则会挂载/root目录
singularity shell -w ./ubuntu20_lammps

# Ubuntu下安装LAMMPS并行版需要安装必要的依赖包
apt update && apt upgrade -y
apt install openmpi-bin openmpi-doc libopenmpi-dev -y
apt install gcc g++ gfortran make wget vim -y

# 安装fftw
wget http://www.fftw.org/fftw-3.3.9.tar.gz
tar zxvf fftw-3.3.9.tar.gz
cd fftw-3.3.9
./configure --prefix=/opt/software/fftw_3.3.9 --enable-shared --enable-static --enable-fma
make -j && make install

# 设置临时fftw环境变量
export PATH=/opt/software/fftw_3.3.9/bin:$PATH
export LD_LIBRARY_PATH=/opt/software/fftw_3.3.9/lib:$LD_LIBRARY_PATH

# 安装lammps
wget https://download.lammps.org/tars/lammps-4May2022.tar.gz
tar zxvf lammps-4May2022.tar.gz
cd  lammps-4May2022
cd src
vim MAKE/OPTIONS/Makefile.g++_openmpi # 修改如下行
  FFT_INC = -DFFT_FFTW -I/opt/software/fftw_3.3.9/include
  FFT_PATH = -L/opt/software/fftw_3.3.9/lib
  FFT_LIB = -lfftw3
 
make  g++_openmpi

mkdir /opt/software/lammps
cp ./lmp_g++_openmpi /opt/software/lammps/

# 设置临时lammps环境变量
export PATH=/opt/software/lammps:$PATH

# 验证(容器内)
cd /root
cp /opt/lammps-10Feb21/bench/in.lj .
mpirun --allow-run-as-root  lmp_g++_openmpi -in M-1.in

# 退出容器,设置永久环境变量(宿主机)
vim ./ubuntu20_lammps/environment
# 加入下面两行
export PATH=/opt/software/fftw_3.3.9/bin:/opt/software/lammps:$PATH
export LD_LIBRARY_PATH=/opt/software/fftw_3.3.9/lib:$LD_LIBRARY_PATH

# 验证(宿主机)
singularity exec /root/singularity/ubuntu20_lammps mpirun --allow-run-as-root  lmp_g++_openmpi -in M-1.in

# 把修改好的sandbox打包成sif格式;
# 删除不必要的安装包, 如 fftw-3.3.9.tar.gz lammps-10Feb21.tar.gz
# 使用前面创建的沙盒目录生成singularity image file格式镜像。
singularity build ubuntu20_lammps.sif ./ubuntu20_lammps

SIF 和 sandbox 两种格式的镜像是可以相互转换的

# 1. 将SIF格式的容器转换成sandbox;
singularity build --sandbox ubuntu20_lammps ubuntu20_lammps.sif

# 2. 将sandbox容器镜像转化成SIF格式;
singularity build ubuntu20_lammps.sif ubuntu20_lammps

SingularityCE 定义文件

详见:https://docs.sylabs.io/guides/latest/user-guide/definition_files.html

SingularityCE 定义文件(简称“def 文件”)就像一组蓝图,用于说明如何构建自定义容器。

定义文件具有标头和正文。标头确定基础容器开始,身体进一步分为 执行软件安装、环境等任务的部分 设置,并将文件从主机系统复制到容器中。

包括两部分:

  1. Header:标头描述了要在容器内构建的核心操作系统。在这里,您将配置容器内所需的基本操作系统功能。您可以指定 Linux 发行版、特定版本以及必须作为核心安装一部分的软件包(从主机系统借用)。
  2. 节:定义的其余部分由节组成(有时称为脚本片段或数据块)。每个节由一个%字符后跟特定节的名称定义。所有节都是可选的,def 文件可能包含给定节的多个实例。在构建时执行的节由解释器执行/bin/sh,可以接受/bin/sh选项。同样,生成要在运行时执行的脚本的节可以接受用于的选项 /bin/sh

标头应位于 def 文件的开头。它告诉 SingularityCE 应使用哪个基本操作系统来构建容器。它由几个关键字组成

每种构建类型都需要的唯一关键字是 Bootstrap。确定将用于创建要使用的基础操作系统的引导代理,包含以下几种

  • library: SingularityCE 容器库中的映像
  • docker:Docker Hub 上托管的映像
  • ...

示例文件:lolcow.def

BootStrap: library
From: ubuntu:22.04

%post
   apt-get -y update
   apt-get -y install cowsay lolcat

%environment
   export LC_ALL=C
   export PATH=/usr/games:$PATH

%runscript
   date | cowsay | lolcat

%labels
   Author Sylabs

创建

singularity build lolcow.sif lolcow.def

在此示例中,标头告诉 SingularityCE 使用基本的 Ubuntu 22.04 映像 从容器库。此定义文件中的其他部分如下 遵循:

  • ``%post`:在构建时在容器中执行,之后 已安装基本操作系统。因此,该部分是地方 执行新库和应用程序的安装
  • %environment:定义了环境变量,这些变量将 在运行时可供容器使用。
  • %runscript:定义容器在以下情况下要执行的操作 被执行。(因此,这些命令不会在生成时运行。
  • %labels:最后,该部分允许将自定义元数据添加到容器中

这是可以使用定义文件执行的操作的一个非常小的示例。除了构建容器 从容器库中,可以从 Docker Hub 中的基础映像开始,然后 直接使用来自官方存储库的映像,例如 Ubuntu、Debian、CentOS、 Arch 和 BusyBox。还可以将主机系统上的现有容器用作一个base。定义文件还支持“模板化”: 能够从命令行或定义文件传递值 将在生成时替换定义文件中的占位符。

从 Dockerfiles 构建

从 4.1 版本开始,SingularityCE 可以直接从 Dockerfiles构建 OCI-SIF 镜像,创建可使用 SingularityCE 的OCI 模式运行的镜像

示例

$ cat ./Dockerfile
FROM debian
CMD cat /etc/os-release

$ singularity build --oci ./debian.oci.sif ./Dockerfile
INFO:    Did not find usable running buildkitd daemon; spawning our own.
INFO:    cfg.Root for buildkitd: /home/myuser/.local/share/buildkit
INFO:    Using crun runtime for buildkitd daemon.
INFO:    running buildkitd server on /run/user/1000/buildkit/buildkitd-0179484509442521.sock
[+] Building 4.3s (5/5)
[+] Building 4.4s (5/5) FINISHED
=> [internal] load build definition from Dockerfile               0.0s
=> => transferring dockerfile: 131B                               0.0s
=> [internal] load metadata for docker.io/library/debian:latest   1.2s
=> [internal] load .dockerignore                                  0.0s
=> => transferring context: 2B                                    0.0s
=> [1/1] FROM docker.io/library/debian:latest@sha256:fab22df3737  2.9s
=> => resolve docker.io/library/debian:latest@sha256:fab22df3737  0.0s
=> => sha256:8457fd5474e70835e4482983a5662355d 49.58MB / 49.58MB  2.8s
=> exporting to docker image format                               3.1s
=> => exporting layers                                            0.0s
=> => exporting manifest sha256:9fec77672dfa11e5eb28e3fe9377cd6c  0.0s
=> => exporting config sha256:4243e816256d45bb137ff40bafe396da5f  0.0s
=> => sending tarball                                             0.2s
Getting image source signatures
Copying blob 8457fd5474e7 done   |
Copying config 46c53efffd done   |
Writing manifest to image destination
INFO:    Converting OCI image to OCI-SIF format
INFO:    Squashing image to single layer
INFO:    Writing OCI-SIF image
INFO:    Cleaning up.
INFO:    Build complete: ./debian.oci.sif

$ singularity run --oci ./debian.oci.sif
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

# exec或shell执行
$ singularity exec --oci ./debian.oci.sif uname -a
Linux myhost 5.14.0-284.30.1.el9_2.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Aug 25 09:13:12 EDT 2023 x86_64 GNU/Linux

$ singularity shell --oci ./debian.oci.sif uname
Singularity> uname -a
Linux myhost 5.14.0-284.30.1.el9_2.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Aug 25 09:13:12 EDT 2023 x86_64 GNU/Linux
Singularity>

执行容器

直接执行

可通过singularity exec命令运行一个容器内的程序,程序执行完毕,容器退出。类似于docker run命令。

singularity exec lammps.sif bash -c  "pwd && id"

用户运行singularity run 命令会执行singularity 镜像默认的 runscript 命令

singularity run lammps.sif

运行singularity shell命令可以交互式的方式运行容器,执行一系列命令。这种执行方式与docker run -it类似。例如:

singularity shell lammps.sif

目录挂载

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-B选项映射主机目录到容器内。

singularity shell --bind /home/cloudam:/home/cloudam lammps.sif

   
  • Singularity

    1 引用
  • Docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口

    29 引用
  • 容器

    2 引用