Singularity用于GUI应用的容器发布是非常方便的,另外一个场景是拥有HPC MPI并行计算求解器发布。

1 安装

参考: https://sylabs.io/guides/3.8/admin-guide/installation.html

1.1 Ubuntu /CentOS环境依赖
=====Ubuntu 系统=====
$ sudo apt-get update && sudo apt-get install -y \
    build-essential \
    uuid-dev \
    libgpgme-dev \
    squashfs-tools \
    libseccomp-dev \
    wget \
    pkg-config \
    git \
    cryptsetup-bin
    
=====CentOS系统=====
$ sudo yum update -y && \
     sudo yum groupinstall -y 'Development Tools' && \
     sudo yum install -y \
     openssl-devel \
     libuuid-devel \
     libseccomp-devel \
     wget \
     squashfs-tools \
     cryptsetup
1.2 安装golang环境

参考:https://golang.org/doc/install

Step0:下载golang 
$ wget https://files.michaelapp.com/install/go1.16.5.linux-amd64.tar.gz

Step1:删除旧版本,解压到指定目录.
$ rm -rf /usr/local/go && tar -C /usr/local -xzf go1.16.5.linux-amd64.tar.gz

Step2:在环境命令文件(/etc/profile)中最后一行添加下面这两行:
export PATH=$PATH:/usr/local/go/bin
export GOPROXY=https://goproxy.cn,direct

Step3:检查是否生效
$ go version
go version go1.16.5 linux/amd64
1.3 下载和编译singularity

源码安装

$ mkdir install 
$ cd install
$ wget https://files.michaelapp.com/install/singularity-ce-3.8.0.tar.gz
$ tar zxvf singularity-ce-3.8.0.tar.gz
$ cd singularity-ce-3.8.0
$ ./mconfig #默认安装在/usr/local,如果为其他路径 ./mconfig --prefix=/opt/singularity
======================没有这一步,下面的步骤会很慢=============
$ vim .builddir/Makefile,修改下面这行
将
GOPROXY := https://proxy.golang.org
改为
GOPROXY := https://goproxy.cn,direct
=========================================================
$ make -C ./builddir
$ sudo make -C ./builddir install

安装完成,验证一下

$ singularity version
3.8.0

2 Singularity简单使用

2.1 拉取预编译镜像
1)拉取ubuntu镜像
$ singularity pull docker://ubuntu:20.04
2)拉取centos镜像
$ singularity pull docker://centos:7
2.2 运行镜像
交互式运行
$ sudo singularity run ubuntu_20.04.sif
执行命令并退出
$ sudo singularity run ubuntu_20.04.sif pwd
$ sudo singularity run ubuntu_20.04.sif ls /bin
2.3 挂载外部目录
$ sudo singularity run -B /opt:/opt ubuntu_20.04.sif
2.4 其他命令
比如 sudo singularity instance start xxx / sudo singularity instance stop xxxx

比如 sudo singularity shell 等

3 定制镜像功能

Singularity 从原始镜像,添加自己的内容,然后打包成自己的镜像并运行

3.1 定制CentOS镜像,并运行GUI 程序
思路:通过sandbox的方式制作可运行图像程序的镜像。从CentOS原始镜像开始,通过安装gnome桌面支持GUI.

(1) 以root身份创建一个centos的sandbox
$ sudo singularity build --sandbox centos_gui/ centos_7.sif

(2) 以root用户可以写的方式运行sandbox容器,并且安装桌面环境
$ sudo singularity shell --writable centos_gui/
Singularity> yum groupinstall -y "GNOME Desktop"
运行完成后,CTRL+C退出容器。

(3) 打包带GUI的容器centos_gui.sif
$ sudo singularity build centos_gui.sif centos_gui/

(4) 测试1:运行 gedit程序
$ singularity run centos_gui.sif gedit
即可看到gedit gui应用运行起来了,比docker运行gui要简单容易的多。

(5) 测试2:运行 firefox程序
$ singularity run centos_gui.sif firefox

备注:如果运行gui出现错误."cannot open display: :0". 先执行xhost +,然后再执行相应的命令即可运行GUI应用

4 通过镜像定义文件(.def)创建Redis镜像

​ 备注:类似Docker里的dockerfile, singularity也支持通过文件定义流程,创建镜像

4.1 Redis 镜像文件定义,redis.def配置如下
Bootstrap:docker
From: ubuntu:20.04

%help

    Singularity container running Redis 5.0.0 for Ubuntu20.04

%post

    #Update and install dependencies
    apt-get update
    apt-get install -y wget build-essential

    #Get redis and install it
    wget http://download.redis.io/releases/redis-5.0.0.tar.gz
    tar xzf redis-5.0.0.tar.gz
    cd redis-5.0.0
    make
    
%environment
    export PAHT=$PATH:/opt/bin
    
%startscript

    #Start the server daemon with this command
    /redis-5.0.0/src/redis-server

%runscript

    #Start the Redis client with this command
    /redis-5.0.0/src/redis-cli

其中,%startscript 指容器启动时的运行命令,启动redis服务

%runscript 指容器执行时运行的命令,run 命令或者exec命令

$ sudo singularity build redis.sif redis.def
4.2 启动 redis server,并命名为redis001
$ singularity instance start redis.sif redis001
4.3 查看redis的实例
$ singularity instance list

如何要连入镜像,singularity shell instance://redis001
4.4 运行redis client
$ singularity run redis.sif
4.5 停止实例
$ singularity instance stop redis001

5、通过镜像定义文件(.def)创建QT应用镜像

详细见代码仓库: https://github.com/panyingyun/qtclientsingularity

5.1 创建qtclient.def文件

其目的是用于创建singularity镜像

# qtclient.def

BootStrap: docker
From: ubuntu:20.04

%labels
    Author panyingyun
    Version qtclient 0.1

# run、entrypoint 执行的命令
%runscript
    exec /usr/local/bin/qtclient

# 从宿主机实现文件拷贝到容器镜像目标路径中
%files
    ./qtclient /opt

# post之后执行的环境变量与操作
%environment
    export LANG="zh_CN.UTF-8"
    export LANGUAGE="zh_CN:zh:en_US:en"

# 安装依赖
%post
    echo "Basic Configuration of Ubuntu 20.04"

    # Replace Official Repository with 163 Repository (in China needed)
    sed -i 's/archive.ubuntu.com/mirrors.huaweicloud.com/g' /etc/apt/sources.list
    sed -i 's/security.ubuntu.com/mirrors.huaweicloud.com/g' /etc/apt/sources.list
    apt update

    echo "Install desktop and xcb"
    export DEBIAN_FRONTEND=noninteractive
    apt install -y build-essential wget zlib1g-dev vim  gfortran g++ gcc make cmake \
        qt5-default qtcreator libqt5x11extras5-dev libgl1-mesa-dev libx11-dev \
        libfontconfig1-dev libfreetype6-dev libx11-dev mesa-common-dev \
        libglu1-mesa-dev freeglut3-dev libxcb-keysyms1-dev libxcb-image0-dev \
        libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync0-dev libxcb-xfixes0-dev \
        libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev \
        libfontconfig1-dev libfreetype6-dev libx11-dev libxext-dev \
        libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libx11-xcb-dev libxcb-glx0-dev x11vnc \
        xauth build-essential mesa-common-dev libglu1-mesa-dev libxkbcommon-dev \
        libxcb-xkb-dev libxslt1-dev libxkbcommon-x11-0 freeglut3-dev
    apt install -y ubuntu-desktop
   
    echo "Asia/Shanghai" > /etc/timezone
    dpkg-reconfigure -f noninteractive tzdata

    apt install -y language-pack-zh-han* language-pack-gnome-zh-han*
    apt install -y $(check-language-support)
    apt remove thunderbird rhythmbox firefox libreoffice* -y
    
    export LANG="zh_CN.UTF-8"
    export LANGUAGE="zh_CN:zh:en_US:en"

    echo "Install qtclient"
    cd /opt/qtclient && sh auto_build_linux.sh && cp build/qtclient /usr/local/bin/
    chmod 755 /usr/local/bin/qtclient
    
    echo "Clean files"
    rm -rf /opt/qtclient
    
    echo "qtclient install successful."
%help
    singularity run-help qtclient.sif
    use-
    singularity exec qtclient.sif [command] [params]
    example-
    singularity exec qtclient.sif
5.2 打包singularity镜像
$ sudo singularity build qtclient.sif qtclient.def
5.3 运行镜像,可看到GUI
$ singularity run qtclient.sif 

qtclient

参考文献

1. 官方用户手册
- https://sylabs.io/guides/3.8/user-guide/build_a_container.html
- https://sylabs.io/guides/3.8/user-guide/definition_files.html
2. 官方用户手册-MPI支持
- https://sylabs.io/guides/3.8/user-guide/mpi.html 
3. singularity容器中运行GUI程序
- https://blog.csdn.net/kongxx/article/details/98101081
4. singularity通过def打包的案例
- https://github.com/sylabs/examples
5. redis def打包镜像案例
- https://blog.csdn.net/kongxx/article/details/100550919
6. singularity容器优缺点
- http://blog.zxh.site/2018/05/15/Singularity/