Singularity/Apptainer 安装、配置与常用操作完整指南

适用场景:Linux 工作站、HPC、Slurm 集群、R/Python 科研分析、Docker 镜像转 SIF。

重点兼容:Singularity 3.5.x。

你的当前版本:Singularity 3.5.0。

文档格式:Markdown 源码,可直接复制、修改并保存为 .md

更新时间:2026-07-11。


Apptainer(原名Singularity)是一种专为高性能计算(HPC)设计的开源容器技术,现已成为Linux基金会的一部分。它以轻量级、快速部署和高安全性为特点,广泛应用于科学计算、工程仿真和数据分析等领域。

核心特点

Apptainer支持将应用程序及其依赖项打包成单一的不可变文件格式(SIF),实现了高可移植性,便于在不同计算环境中迁移和共享。其轻量级虚拟化技术无需模拟整个硬件环境,启动速度快且资源占用低。此外,Apptainer采用用户权限隔离机制,确保容器内外的安全性。

使用场景

Apptainer在高性能计算中表现尤为突出,适用于科学研究、数据处理和分布式系统等场景。它能够快速部署容器,支持GPU、高速网络和并行文件系统的无缝集成,显著提升计算效率。

1. Singularity、SingularityCE 与 Apptainer 的关系

Singularity 是面向 HPC 和科研计算的容器平台。

历史关系可以简化为:

text 复制代码
早期 Singularity
        │
        ├── SingularityCE
        │   命令:singularity
        │
        └── Apptainer
            命令:apptainer

SingularityCE 和 Apptainer 是不同项目,但都延续了早期 Singularity 的使用方式。

你的服务器执行:

bash 复制代码
command -v singularity
singularity version

得到:

text 复制代码
/usr/local/bin/singularity
3.5.0

因此本文默认使用:

bash 复制代码
singularity ...

而不是:

bash 复制代码
apptainer ...

常见命令替换关系:

text 复制代码
SingularityCE                  Apptainer
singularity exec              apptainer exec
singularity shell             apptainer shell
singularity run               apptainer run
singularity pull              apptainer pull
singularity build             apptainer build
SINGULARITY_CACHEDIR          APPTAINER_CACHEDIR
SINGULARITY_TMPDIR            APPTAINER_TMPDIR
SINGULARITYENV_VAR            APPTAINERENV_VAR

Apptainer 仍兼容很多 SINGULARITY_* 环境变量,但在你当前系统上应优先使用 Singularity 原生写法。


2. Singularity 的核心概念

Singularity 最重要的对象包括:

text 复制代码
definition file(.def)
        ↓ singularity build
SIF 镜像(.sif)
        ↓ singularity exec / run / shell
容器化进程

2.1 SIF 镜像

SIF 是 Singularity Image Format。

一个 SIF 通常就是一个普通文件:

text 复制代码
r431-analysis-1.0.sif

它可以:

bash 复制代码
ls -lh r431-analysis-1.0.sif
cp r431-analysis-1.0.sif /groups/project/containers/
scp r431-analysis-1.0.sif user@server:/path/
sha256sum r431-analysis-1.0.sif

SIF 默认是不可变的只读镜像。

2.2 sandbox

sandbox 是一个目录形式的容器根文件系统:

text 复制代码
r431-sandbox/
├── bin/
├── etc/
├── lib/
├── opt/
├── usr/
└── var/

sandbox 可以在具备权限时以可写方式使用,适合开发和调试。

2.3 persistent overlay

overlay 是叠加在只读 SIF 上方的可写层:

text 复制代码
基础环境:r431-analysis.sif
        +
变化文件:r431-overlay.img
        =
实际运行环境

SIF 不变,新安装的软件和修改保存在 overlay 中。

2.4 instance

普通 execrunshell 结束后,不会留下类似 Docker 的停止容器对象。

若要在后台长期运行服务,需要使用:

bash 复制代码
singularity instance start

2.5 definition file

definition file,简称 def 文件,是 Singularity 的构建说明书,作用类似 Dockerfile。

示例:

text 复制代码
Bootstrap: docker
From: ubuntu:22.04

%post
    apt-get update
    apt-get install -y curl

%runscript
    exec bash "$@"

3. 检查 Singularity 状态

3.1 检查命令位置

bash 复制代码
command -v singularity
which singularity
type -a singularity

3.2 检查版本

bash 复制代码
singularity version
singularity --version

你的结果:

text 复制代码
3.5.0

3.3 查看主帮助

bash 复制代码
singularity --help
singularity help

3.4 查看子命令帮助

bash 复制代码
singularity help build
singularity help exec
singularity help shell
singularity help instance start

也可以:

bash 复制代码
singularity build --help
singularity exec --help

3.5 查看安装路径

bash 复制代码
readlink -f "$(command -v singularity)"

查看相关目录:

bash 复制代码
ls -l /usr/local/bin/singularity
ls -ld /usr/local/libexec/singularity 2>/dev/null
ls -ld /usr/local/etc/singularity 2>/dev/null

3.6 基础运行测试

直接运行远程容器:

bash 复制代码
singularity exec \
  docker://alpine:latest \
  cat /etc/os-release

建议正式使用时先拉取为本地 SIF:

bash 复制代码
mkdir -p "$HOME/containers"

singularity pull \
  "$HOME/containers/alpine-latest.sif" \
  docker://alpine:latest

测试:

bash 复制代码
singularity exec \
  "$HOME/containers/alpine-latest.sif" \
  cat /etc/os-release

3.7 调试模式

bash 复制代码
singularity --debug exec \
  "$HOME/containers/alpine-latest.sif" \
  true

增加详细输出:

bash 复制代码
singularity --verbose exec \
  "$HOME/containers/alpine-latest.sif" \
  true

安静模式:

bash 复制代码
singularity --quiet exec \
  "$HOME/containers/alpine-latest.sif" \
  command

4. Singularity 是否需要后台服务

普通 Singularity 运行不依赖类似 Docker 的中央 daemon。

Docker 常见结构:

text 复制代码
docker CLI
    ↓
dockerd 后台服务
    ↓
镜像和容器

Singularity 常见结构:

text 复制代码
singularity 命令
    ↓
直接启动容器化进程
    ↓
程序结束后退出

所以通常不存在:

bash 复制代码
systemctl status singularity

也不需要:

bash 复制代码
systemctl start singularity

检查 Singularity 是否可用,主要使用:

bash 复制代码
command -v singularity
singularity version
singularity exec image.sif true

注意:管理员可能配置了 Singularity 的辅助组件、远程服务或 setuid 安装,但普通用户通常不需要管理常驻 daemon。


5. 安装 Singularity

5.1 HPC 上最推荐的安装方式

在共享 HPC 上,最好由管理员统一安装到:

text 复制代码
/usr/local/bin/singularity

或者通过 environment module 提供:

bash 复制代码
module avail 2>&1 | grep -i singularity
module load singularity
singularity version

管理员安装可以保证:

text 复制代码
登录节点和计算节点版本一致
setuid / user namespace 策略一致
GPU 绑定配置一致
共享文件系统配置一致
fakeroot 配置一致

5.2 你当前已经安装,不需要重新安装

你当前:

bash 复制代码
command -v singularity
# /usr/local/bin/singularity

singularity version
# 3.5.0

可以直接进入后续使用章节。

5.3 安装 Singularity 3.5.x 的历史方法

以下用于理解旧版 3.5.x 安装,不建议在 2026 年新部署时继续安装 3.5。

Ubuntu/Debian 依赖:

bash 复制代码
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

旧版 Singularity 3.5.3 要求 Go 1.13 或更高。

下载历史版本:

bash 复制代码
export VERSION=3.5.3

wget \
  "https://github.com/sylabs/singularity/releases/download/v${VERSION}/singularity-${VERSION}.tar.gz"

tar -xzf "singularity-${VERSION}.tar.gz"

cd singularity

构建:

bash 复制代码
./mconfig
make -C builddir
sudo make -C builddir install

检查:

bash 复制代码
/usr/local/bin/singularity version

5.4 新安装应使用较新的 SingularityCE

新版本的下载包名称通常类似:

text 复制代码
singularity-ce-VERSION.tar.gz

通用流程:

bash 复制代码
export VERSION="请替换为准备安装的当前版本"

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

新安装前必须根据对应版本的官方文档确认:

text 复制代码
Go 版本要求
系统依赖
FUSE 版本
squashfs 工具
是否启用 setuid
是否启用 OCI mode

不要直接将旧版 3.5 的依赖命令用于所有新版本。

5.5 指定安装路径

管理员可指定 prefix:

bash 复制代码
./mconfig --prefix=/opt/singularity
make -C builddir
sudo make -C builddir install

普通用户个人安装可能使用:

bash 复制代码
./mconfig \
  --prefix="$HOME/software/singularity" \
  --without-suid

但无特权安装依赖内核 user namespace,功能可能受限。共享 HPC 上应先咨询管理员。


6. Singularity 配置文件和安装位置

6.1 默认配置路径

从源码默认安装时常见位置:

text 复制代码
/usr/local/etc/singularity/

查看:

bash 复制代码
ls -lah /usr/local/etc/singularity/

主要配置文件可能包括:

text 复制代码
singularity.conf
ecl.toml
capability.json
network/

6.2 查看主配置

bash 复制代码
grep -vE '^[[:space:]]*(#|$)' \
  /usr/local/etc/singularity/singularity.conf

普通用户通常只有读取权限。

6.3 常见管理员配置项

可能涉及:

text 复制代码
allow setuid
allow user bind mounts
mount home
mount tmp
mount hostfs
bind path
enable overlay
sessiondir max size

实际行为以本集群配置为准。

6.4 查看 fakeroot 配置

检查系统映射:

bash 复制代码
grep "^$(whoami):" /etc/subuid
grep "^$(whoami):" /etc/subgid

如果没有结果,通常不能使用完整 fakeroot。

测试:

bash 复制代码
singularity exec --fakeroot \
  "$HOME/containers/alpine-latest.sif" \
  id

理想情况下容器内显示:

text 复制代码
uid=0(root)

但这只是容器 user namespace 内的"假 root",并不获得宿主机 root 权限。


7. SIF 镜像、sandbox 和 overlay 的存储位置

7.1 SIF 位置由用户完全指定

bash 复制代码
singularity pull \
  /users/$USER/containers/r431.sif \
  docker://repository/image:tag

最终 SIF 就位于:

text 复制代码
/users/用户名/containers/r431.sif

可以自由移动:

bash 复制代码
mv r431.sif /groups/project/containers/
cp r431.sif /backup/

7.2 sandbox 位置由用户指定

bash 复制代码
singularity build \
  --sandbox "$HOME/containers/r431-sandbox" \
  docker://ubuntu:22.04

它是一个目录,而不是单一文件。

7.3 overlay 位置由用户指定

text 复制代码
$HOME/containers/r431-overlay.img

运行时:

bash 复制代码
singularity exec \
  --overlay "$HOME/containers/r431-overlay.img" \
  "$HOME/containers/r431.sif" \
  command

7.4 缓存位置

Singularity 3.5 默认缓存通常位于:

text 复制代码
$HOME/.singularity/cache

查看:

bash 复制代码
singularity cache list

自定义:

bash 复制代码
export SINGULARITY_CACHEDIR="$HOME/singularity/cache"

7.5 临时构建位置

默认通常使用:

text 复制代码
/tmp

自定义:

bash 复制代码
export SINGULARITY_TMPDIR="/tmp/$USER/singularity-tmp"
mkdir -p "$SINGULARITY_TMPDIR"

镜像最终路径、缓存路径和临时路径是三个不同概念:

text 复制代码
最终 SIF:
$HOME/containers/r431.sif

缓存:
$HOME/singularity/cache

构建临时文件:
/tmp/$USER/singularity-tmp

8. 下载和拉取镜像

8.1 从 Docker Hub 拉取

bash 复制代码
mkdir -p "$HOME/containers"

singularity pull \
  "$HOME/containers/ubuntu-22.04.sif" \
  docker://ubuntu:22.04

8.2 从 Singularity Library 拉取

bash 复制代码
singularity pull \
  "$HOME/containers/alpine.sif" \
  library://alpine:latest

Singularity 3.5 的远程 Library 是否仍可访问,取决于远程服务兼容性和集群配置。

8.3 直接运行远程镜像

bash 复制代码
singularity exec \
  docker://ubuntu:22.04 \
  cat /etc/os-release

不建议在多个并行作业中反复直接使用远程 URI。

推荐:

text 复制代码
先 singularity pull 得到本地 SIF
再让所有作业运行同一个 SIF

8.4 指定架构

查看帮助:

bash 复制代码
singularity pull --help

若版本支持,可用:

bash 复制代码
singularity pull \
  --arch amd64 \
  image.sif \
  docker://repository/image:tag

源镜像架构必须与运行节点兼容,除非使用额外模拟机制。

8.5 私有 Docker 仓库登录

Singularity 3.5 可尝试:

bash 复制代码
singularity pull \
  --docker-login \
  private-image.sif \
  docker://registry.example.com/user/image:tag

根据提示输入用户名和密码。

避免把密码直接写进 shell 历史。

8.6 禁用缓存

bash 复制代码
singularity pull \
  --disable-cache \
  image.sif \
  docker://ubuntu:22.04

这会增加重复下载,不适合日常使用,只用于缓存异常排查。


9. Docker/OCI 镜像转 SIF

9.1 直接从 Docker Hub 转换

bash 复制代码
singularity pull \
  "$HOME/containers/r431-analysis-1.0.sif" \
  docker://yourname/r431-analysis:1.0

Singularity 会:

text 复制代码
下载 Docker/OCI 层
    ↓
解压并合并
    ↓
生成 SIF

9.2 使用 build 转换

bash 复制代码
singularity build \
  "$HOME/containers/r431-analysis-1.0.sif" \
  docker://yourname/r431-analysis:1.0

pull Docker 镜像时,内部也需要完成 OCI 到 SIF 的转换。

9.3 Docker ENTRYPOINT 与 CMD 差异

Docker 镜像转换为 SIF 后,Docker 的 ENTRYPOINT、CMD 和环境变量不一定完全按照 Docker 运行时方式生效。

例如 Micromamba Docker 镜像通常依赖 entrypoint 自动激活环境,但 Singularity 中最好显式调用:

bash 复制代码
/opt/conda/bin/R
/opt/conda/bin/Rscript

示例:

bash 复制代码
singularity exec \
  r431-analysis.sif \
  /opt/conda/bin/Rscript \
  -e 'sessionInfo()'

不要假设:

bash 复制代码
singularity exec r431-analysis.sif Rscript ...

一定会找到正确的 R。

先检查:

bash 复制代码
singularity exec r431-analysis.sif \
  bash -c '
    echo "$PATH"
    command -v R || true
    command -v Rscript || true
    ls -l /opt/conda/bin/R*
  '

10. Docker tar 文件转 SIF

这是你当前最推荐的迁移方式。

10.1 在有 Docker 的机器上导出

bash 复制代码
docker save \
  --output r431-analysis-1.0.tar \
  r431-analysis:1.0

建议使用未压缩 .tar,兼容旧版 Singularity 3.5 更稳妥。

生成校验值:

bash 复制代码
sha256sum r431-analysis-1.0.tar \
  > r431-analysis-1.0.tar.sha256

10.2 复制到 HPC

bash 复制代码
scp \
  r431-analysis-1.0.tar \
  r431-analysis-1.0.tar.sha256 \
  user@hpc:$HOME/containers/

10.3 在 HPC 验证

bash 复制代码
cd "$HOME/containers"

sha256sum -c r431-analysis-1.0.tar.sha256

10.4 转换为 SIF

bash 复制代码
export SINGULARITY_CACHEDIR="$HOME/singularity/cache"
export SINGULARITY_TMPDIR="/tmp/$USER/singularity-tmp"

mkdir -p "$SINGULARITY_CACHEDIR"
mkdir -p "$SINGULARITY_TMPDIR"

singularity build \
  "$HOME/containers/r431-analysis-1.0.sif" \
  "docker-archive:$HOME/containers/r431-analysis-1.0.tar"

注意 URI:

text 复制代码
正确:
docker-archive:/完整路径/image.tar

不要写成:
docker-archive://完整路径/image.tar

10.5 测试

bash 复制代码
singularity exec \
  --cleanenv \
  "$HOME/containers/r431-analysis-1.0.sif" \
  /opt/conda/bin/R --version

10.6 确认后删除 tar

bash 复制代码
rm "$HOME/containers/r431-analysis-1.0.tar"
rm "$HOME/containers/r431-analysis-1.0.tar.sha256"

保留:

text 复制代码
r431-analysis-1.0.sif

11. 查看和检查 SIF 镜像

11.1 查看文件大小

bash 复制代码
ls -lh image.sif
du -h image.sif

11.2 查看镜像元数据

bash 复制代码
singularity inspect image.sif

JSON:

bash 复制代码
singularity inspect --json image.sif

11.3 查看环境定义

bash 复制代码
singularity inspect --environment image.sif

11.4 查看 runscript

bash 复制代码
singularity inspect --runscript image.sif

11.5 查看 labels

bash 复制代码
singularity inspect --labels image.sif

11.6 查看 definition file

如果构建时保存了 def 元数据:

bash 复制代码
singularity inspect --deffile image.sif

11.7 查看 SIF 内部对象

bash 复制代码
singularity sif list image.sif

查看 header:

bash 复制代码
singularity sif header image.sif

11.8 查看镜像中的系统

bash 复制代码
singularity exec image.sif \
  cat /etc/os-release

11.9 查看关键软件

bash 复制代码
singularity exec image.sif \
  bash -c '
    uname -m
    cat /etc/os-release
    command -v R || true
    command -v python || true
    command -v micromamba || true
  '

12. 运行、执行和进入容器

12.1 exec

在容器中执行指定命令:

bash 复制代码
singularity exec image.sif \
  cat /etc/os-release

运行 R:

bash 复制代码
singularity exec image.sif \
  /opt/conda/bin/Rscript \
  analysis.R

12.2 shell

进入交互式 shell:

bash 复制代码
singularity shell image.sif

进入后提示符通常类似:

text 复制代码
Singularity>

退出:

bash 复制代码
exit

指定 bash:

bash 复制代码
singularity exec image.sif \
  /bin/bash

12.3 run

执行镜像定义的默认 runscript:

bash 复制代码
singularity run image.sif

SIF 也可能具有可执行权限,可直接:

bash 复制代码
./image.sif

这取决于文件权限和系统配置。

12.4 test

执行 definition file 中的 %test

bash 复制代码
singularity test image.sif

12.5 管道和标准输入

bash 复制代码
echo 'print(R.version.string)' \
  | singularity exec image.sif \
    /opt/conda/bin/R --vanilla --slave

12.6 设置工作目录

Singularity 3.5 可以使用:

bash 复制代码
singularity exec \
  --pwd /project \
  image.sif \
  pwd

--pwd 不可用或行为异常,可以:

bash 复制代码
singularity exec image.sif \
  bash -c 'cd /project && Rscript analysis.R'

13. 宿主机目录绑定与文件访问

Singularity 通过 bind mount 使用宿主机文件。

13.1 默认自动绑定

默认配置通常自动绑定:

text 复制代码
$HOME
$PWD
/tmp
/var/tmp
/proc
/sys
/etc/passwd
/etc/resolv.conf

具体以管理员配置为准。

13.2 显式绑定目录

bash 复制代码
singularity exec \
  --bind /groups/myproject:/project \
  image.sif \
  ls -lah /project

缩写:

bash 复制代码
singularity exec \
  -B /groups/myproject:/project \
  image.sif \
  ls -lah /project

格式:

text 复制代码
宿主机路径:容器内路径:权限

13.3 只读绑定

bash 复制代码
singularity exec \
  --bind /groups/myproject/data:/project/data:ro \
  image.sif \
  ls /project/data

13.4 可写绑定

bash 复制代码
singularity exec \
  --bind /groups/myproject/results:/project/results:rw \
  image.sif \
  command

默认一般是 rw

13.5 多个 bind

逗号分隔:

bash 复制代码
singularity exec \
  --bind \
  /groups/myproject/code:/project/code:ro,/groups/myproject/data:/project/data:ro,/groups/myproject/results:/project/results:rw \
  image.sif \
  command

也可多次写:

bash 复制代码
singularity exec \
  -B /groups/myproject/code:/project/code:ro \
  -B /groups/myproject/data:/project/data:ro \
  -B /groups/myproject/results:/project/results:rw \
  image.sif \
  command

13.6 使用环境变量统一 bind

bash 复制代码
export SINGULARITY_BINDPATH="/groups/myproject:/project"

singularity exec image.sif \
  ls /project

Singularity 3.5 也接受:

bash 复制代码
export SINGULARITY_BIND="/groups/myproject:/project"

13.7 不自动挂载 HOME

bash 复制代码
singularity shell \
  --no-home \
  image.sif

注意:若当前工作目录本身就是 HOME,HOME 仍可能因当前目录绑定而可见。

13.8 更严格隔离

bash 复制代码
singularity exec \
  --containall \
  --cleanenv \
  --bind /groups/myproject:/project \
  image.sif \
  command

这会更严格地隔离文件系统、环境和部分 namespace。

13.9 文件权限

Singularity 默认使用宿主机当前用户 UID/GID。

容器写入绑定目录的文件通常仍属于当前用户:

bash 复制代码
singularity exec \
  -B "$PWD":/project \
  image.sif \
  touch /project/test.txt

ls -l test.txt

这比传统 rootful Docker 更自然地适配 HPC 共享文件系统。


14. 环境变量和环境隔离

14.1 默认继承宿主机环境

不使用 --cleanenv 时,很多宿主机环境变量会进入容器:

bash 复制代码
export TEST_VAR=hello

singularity exec image.sif \
  env | grep TEST_VAR

14.2 清理宿主机环境

bash 复制代码
singularity exec \
  --cleanenv \
  image.sif \
  env

科研复现建议经常使用:

bash 复制代码
--cleanenv

避免宿主机的:

text 复制代码
PATH
LD_LIBRARY_PATH
R_LIBS_USER
PYTHONPATH
CONDA_PREFIX
代理变量

干扰镜像环境。

14.3 设置容器内环境变量

Singularity 3.5 使用 SINGULARITYENV_ 前缀:

bash 复制代码
SINGULARITYENV_OMP_NUM_THREADS=8 \
singularity exec image.sif \
  env | grep OMP_NUM_THREADS

14.4 设置 PATH

在容器 PATH 前添加:

bash 复制代码
export SINGULARITYENV_PREPEND_PATH="/opt/conda/bin"

singularity exec image.sif \
  command -v R

追加:

bash 复制代码
export SINGULARITYENV_APPEND_PATH="/opt/custom/bin"

完全覆盖:

bash 复制代码
export SINGULARITYENV_PATH="/opt/conda/bin:/usr/local/bin:/usr/bin:/bin"

14.5 R 环境隔离

bash 复制代码
unset R_LIBS_USER
unset R_PROFILE_USER
unset R_ENVIRON_USER

然后:

bash 复制代码
singularity exec \
  --cleanenv \
  image.sif \
  /opt/conda/bin/Rscript \
  -e '
    print(R.version.string)
    print(.libPaths())
    print(Sys.getenv("R_LIBS_USER"))
  '

14.6 Slurm 线程环境变量

bash 复制代码
export OMP_NUM_THREADS="${SLURM_CPUS_PER_TASK:-1}"
export OPENBLAS_NUM_THREADS="${SLURM_CPUS_PER_TASK:-1}"
export MKL_NUM_THREADS="${SLURM_CPUS_PER_TASK:-1}"

export SINGULARITYENV_OMP_NUM_THREADS="$OMP_NUM_THREADS"
export SINGULARITYENV_OPENBLAS_NUM_THREADS="$OPENBLAS_NUM_THREADS"
export SINGULARITYENV_MKL_NUM_THREADS="$MKL_NUM_THREADS"

15. 缓存和临时目录配置

15.1 默认缓存

text 复制代码
$HOME/.singularity/cache

查看:

bash 复制代码
singularity cache list

详细查看:

bash 复制代码
singularity cache list --verbose

15.2 自定义缓存目录

bash 复制代码
mkdir -p "$HOME/singularity/cache"

export SINGULARITY_CACHEDIR="$HOME/singularity/cache"

写入 ~/.bashrc

bash 复制代码
cat >> ~/.bashrc <<'EOF'
export SINGULARITY_CACHEDIR="$HOME/singularity/cache"
EOF

15.3 自定义临时目录

bash 复制代码
mkdir -p "/tmp/$USER/singularity-tmp"

export SINGULARITY_TMPDIR="/tmp/$USER/singularity-tmp"

如果集群提供本地 scratch:

bash 复制代码
export SINGULARITY_TMPDIR="/local_scratch/$USER/singularity-tmp"
mkdir -p "$SINGULARITY_TMPDIR"

15.4 为什么临时目录优先使用本地磁盘

构建和转换镜像可能产生大量临时文件。

以下文件系统可能较慢或存在功能限制:

text 复制代码
NFS
Lustre
GPFS
FUSE
WebDAV

最终 SIF 可以放共享存储,但构建临时目录优先放节点本地 /tmp 或 scratch。

15.5 清理缓存前预览

bash 复制代码
singularity cache clean --dry-run

15.6 清理全部缓存

bash 复制代码
singularity cache clean

不询问:

bash 复制代码
singularity cache clean --force

15.7 按类型清理

bash 复制代码
singularity cache clean \
  --type=oci,blob

15.8 手工查看磁盘使用

bash 复制代码
du -sh "$SINGULARITY_CACHEDIR"
du -h --max-depth=2 "$SINGULARITY_CACHEDIR" 2>/dev/null

不要在缓存目录中手工添加不相关文件。


16. 使用 definition file 构建镜像

16.1 基础 def 文件

创建:

bash 复制代码
cat > ubuntu-tools.def <<'EOF'
Bootstrap: docker
From: ubuntu:22.04

%labels
    Author Your_Name
    Version 1.0
    Description Ubuntu tools container

%post
    apt-get update

    DEBIAN_FRONTEND=noninteractive \
    apt-get install -y --no-install-recommends \
        ca-certificates \
        curl \
        git

    apt-get clean
    rm -rf /var/lib/apt/lists/*

%environment
    export LANG=C.UTF-8
    export LC_ALL=C.UTF-8

%runscript
    exec bash "$@"

%test
    curl --version
    git --version
EOF

16.2 使用 sudo 构建

在有管理员权限的工作站:

bash 复制代码
sudo -E singularity build \
  ubuntu-tools-1.0.sif \
  ubuntu-tools.def

-E 可保留 SINGULARITY_CACHEDIRSINGULARITY_TMPDIR 等环境变量。

16.3 使用 fakeroot 构建

前提:管理员已配置 /etc/subuid/etc/subgid

bash 复制代码
singularity build \
  --fakeroot \
  ubuntu-tools-1.0.sif \
  ubuntu-tools.def

16.4 检查 fakeroot

bash 复制代码
grep "^$(whoami):" /etc/subuid
grep "^$(whoami):" /etc/subgid

测试:

bash 复制代码
singularity exec \
  --fakeroot \
  ubuntu-tools-1.0.sif \
  id

16.5 运行测试

bash 复制代码
singularity test ubuntu-tools-1.0.sif

16.6 查看元数据

bash 复制代码
singularity inspect ubuntu-tools-1.0.sif
singularity inspect --deffile ubuntu-tools-1.0.sif
singularity inspect --runscript ubuntu-tools-1.0.sif

16.7 definition file 常见区段

text 复制代码
Bootstrap / From    基础镜像
%files              复制文件
%post               构建期安装软件
%environment        运行期环境变量
%labels             元数据标签
%runscript          singularity run 执行内容
%startscript        instance start 执行内容
%test               镜像测试
%help               容器帮助

16.8 %setup 要谨慎

%setup 在宿主机上以构建权限运行,并可通过 $SINGULARITY_ROOTFS 操作容器根目录。

由于它会接触宿主机,应尽量优先使用 %files%post


17. 构建 Micromamba + R 4.3.1 SIF

你可以采用两条路线:

text 复制代码
路线 A:
Docker 构建好镜像
    ↓
Singularity 转 SIF

路线 B:
Singularity definition file 直接构建

对 Singularity 3.5.0,路线 A 通常更稳。

17.1 路线 A:Docker 镜像转 SIF

Docker 机器:

bash 复制代码
docker build \
  -t r431-analysis:1.0 \
  .

导出:

bash 复制代码
docker save \
  -o r431-analysis-1.0.tar \
  r431-analysis:1.0

HPC:

bash 复制代码
singularity build \
  "$HOME/containers/r431-analysis-1.0.sif" \
  "docker-archive:$HOME/containers/r431-analysis-1.0.tar"

测试:

bash 复制代码
singularity exec \
  --cleanenv \
  "$HOME/containers/r431-analysis-1.0.sif" \
  /opt/conda/bin/Rscript \
  -e '
    print(R.version.string)
    print(Sys.which("R"))
    print(.libPaths())
    sessionInfo()
  '

17.2 路线 B:使用 definition file

创建 environment.yml

yaml 复制代码
name: base

channels:
  - conda-forge

dependencies:
  - r-base=4.3.1
  - r-data.table
  - r-dplyr
  - r-tidyr
  - r-ggplot2
  - r-mclust
  - r-survival
  - r-lme4
  - r-renv
  - r-remotes

创建 r431.def

text 复制代码
Bootstrap: docker
From: mambaorg/micromamba:2.8.1

%files
    environment.yml /tmp/environment.yml

%post
    export MAMBA_ROOT_PREFIX=/opt/conda

    micromamba install \
        --yes \
        --name base \
        --file /tmp/environment.yml

    micromamba clean --all --yes
    rm -f /tmp/environment.yml

    /opt/conda/bin/Rscript -e '
        stopifnot(as.character(getRversion()) == "4.3.1")
        library(mclust)
        library(survival)
        sessionInfo()
    '

%environment
    export MAMBA_ROOT_PREFIX=/opt/conda
    export PATH=/opt/conda/bin:$PATH
    export LANG=C.UTF-8
    export LC_ALL=C.UTF-8

%runscript
    exec /opt/conda/bin/R "$@"

%test
    /opt/conda/bin/Rscript -e '
        stopifnot(as.character(getRversion()) == "4.3.1")
        library(mclust)
        library(survival)
        cat("Environment test passed.\n")
    '

构建:

bash 复制代码
singularity build \
  --fakeroot \
  "$HOME/containers/r431-analysis-1.0.sif" \
  r431.def

若 Singularity 3.5 无法处理较新的 OCI 层,改用路线 A。


18. SIF 中如何安装新包

SIF 默认只读,因此不能直接永久修改。

例如:

bash 复制代码
singularity shell r431-analysis.sif

进入后执行:

bash 复制代码
apt-get install ...

通常会失败,因为容器根文件系统不可写。

可选方案:

text 复制代码
1. 修改 def 文件后重建新 SIF
2. 修改 Dockerfile 后重新构建,再转 SIF
3. 使用 sandbox
4. 使用 persistent overlay
5. 使用 --writable-tmpfs 临时测试
6. 将 R 包安装到宿主机绑定的用户库

正式科研最推荐:

text 复制代码
修改 Dockerfile / environment.yml / definition file
    ↓
重建有版本号的新镜像

例如:

text 复制代码
r431-analysis-1.0.sif
r431-analysis-1.1.sif

19. 使用 sandbox 修改环境

19.1 从 SIF 创建 sandbox

bash 复制代码
singularity build \
  --sandbox "$HOME/containers/r431-sandbox" \
  "$HOME/containers/r431-analysis-1.0.sif"

也可从 Docker 镜像创建:

bash 复制代码
singularity build \
  --sandbox "$HOME/containers/r431-sandbox" \
  docker://yourname/r431-analysis:1.0

19.2 可写进入

有 sudo:

bash 复制代码
sudo singularity shell \
  --writable \
  "$HOME/containers/r431-sandbox"

有 fakeroot:

bash 复制代码
singularity shell \
  --fakeroot \
  --writable \
  "$HOME/containers/r431-sandbox"

19.3 安装 Conda R 包

进入后:

bash 复制代码
micromamba install \
  -n base \
  -c conda-forge \
  r-lcmm \
  r-ggalluvial \
  -y

测试:

bash 复制代码
/opt/conda/bin/Rscript -e '
  library(lcmm)
  library(ggalluvial)
  sessionInfo()
'

19.4 转换为新的 SIF

退出:

bash 复制代码
exit

构建:

bash 复制代码
singularity build \
  "$HOME/containers/r431-analysis-1.1.sif" \
  "$HOME/containers/r431-sandbox"

某些安装和配置下可能需要:

bash 复制代码
sudo singularity build \
  "$HOME/containers/r431-analysis-1.1.sif" \
  "$HOME/containers/r431-sandbox"

或者:

bash 复制代码
singularity build \
  --fakeroot \
  "$HOME/containers/r431-analysis-1.1.sif" \
  "$HOME/containers/r431-sandbox"

19.5 sandbox 的缺点

手工修改 sandbox 与 Docker commit 类似:

text 复制代码
方便测试
但不容易记录安装历史
不利于长期复现

最终仍建议把成功步骤写回 def 文件或 Dockerfile。


20. 使用 persistent overlay 保存新包

20.1 overlay 的结构

text 复制代码
r431-analysis.sif       只读基础镜像
r431-overlay.img        可写变化

20.2 Singularity 3.5 手工创建 ext3 overlay

创建 10 GB 稀疏文件:

bash 复制代码
dd if=/dev/zero \
  of="$HOME/containers/r431-overlay.img" \
  bs=1M \
  count=0 \
  seek=10240

格式化:

bash 复制代码
mkfs.ext3 -F \
  "$HOME/containers/r431-overlay.img"

如果 mkfs.ext3 不存在:

bash 复制代码
command -v mkfs.ext3
command -v mke2fs

也可:

bash 复制代码
mke2fs -t ext3 -F \
  "$HOME/containers/r431-overlay.img"

20.3 使用 overlay 进入

bash 复制代码
singularity shell \
  --fakeroot \
  --overlay "$HOME/containers/r431-overlay.img" \
  "$HOME/containers/r431-analysis-1.0.sif"

安装:

bash 复制代码
micromamba install \
  -n base \
  -c conda-forge \
  r-lcmm \
  -y

退出后,新包保存在 overlay 中。

20.4 以后运行必须继续带 overlay

bash 复制代码
singularity exec \
  --overlay "$HOME/containers/r431-overlay.img" \
  "$HOME/containers/r431-analysis-1.0.sif" \
  /opt/conda/bin/Rscript \
  -e 'library(lcmm); sessionInfo()'

20.5 overlay 注意事项

不要让多个作业同时写同一个 overlay。

推荐:

text 复制代码
配置阶段:单独写
正式运行:只读使用或每个任务独立 overlay

网络文件系统上的 ext3 overlay 可能有兼容性或性能问题,优先询问集群管理员。

20.6 overlay 不等于修改 SIF

删除 overlay 后:

text 复制代码
新安装的软件会消失
基础 SIF 仍保持原样

因此迁移环境时需要同时复制:

text 复制代码
r431-analysis-1.0.sif
r431-overlay.img

21. 使用临时可写层

bash 复制代码
singularity shell \
  --writable-tmpfs \
  image.sif

在里面进行的修改:

text 复制代码
本次运行可见
退出后全部消失
SIF 不改变

适合:

text 复制代码
临时测试安装命令
检查包能否编译
测试配置文件

不适合:

text 复制代码
正式保存环境
长期复现

--writable-tmpfs 使用内存或 session 临时空间,安装大量软件时可能受 session 大小和内存限制。


22. 将修改后的环境固化为新 SIF

22.1 最规范:重建

text 复制代码
修改 environment.yml / def / Dockerfile
    ↓
构建 r431-analysis-1.1.sif

22.2 sandbox 转 SIF

bash 复制代码
singularity build \
  r431-analysis-1.1.sif \
  r431-sandbox

22.3 overlay 是否可以直接合并

Singularity 3.5 没有一个完全等价于:

bash 复制代码
docker commit

且简单可靠地把任意外部 overlay 直接合并到基础 SIF 的日常命令。

更稳妥的方法是:

text 复制代码
1. 从基础镜像创建 sandbox
2. 在 sandbox 中重做已验证的安装步骤
3. 从 sandbox 构建新 SIF

或者把安装步骤写入 def 后重建。

22.4 保存安装清单

Conda:

bash 复制代码
singularity exec \
  --overlay r431-overlay.img \
  r431-analysis.sif \
  micromamba list

导出 explicit:

bash 复制代码
singularity exec \
  --overlay r431-overlay.img \
  r431-analysis.sif \
  micromamba list --explicit \
  > conda-linux-64-explicit.txt

R 包:

bash 复制代码
singularity exec \
  --overlay r431-overlay.img \
  r431-analysis.sif \
  /opt/conda/bin/Rscript -e '
    x <- installed.packages()[, c("Package", "Version")]
    write.table(
      x,
      row.names = FALSE,
      sep = "\t",
      quote = FALSE
    )
  ' > r-packages.tsv

23. Singularity instance 后台实例

普通科研脚本不需要 instance。

需要运行后台服务时使用:

text 复制代码
Jupyter
RStudio Server
数据库
Web 服务
API

23.1 启动 instance

bash 复制代码
singularity instance start \
  image.sif \
  my-instance

23.2 查看 instance

bash 复制代码
singularity instance list

JSON:

bash 复制代码
singularity instance list --json

23.3 进入 instance

bash 复制代码
singularity shell \
  instance://my-instance

23.4 在 instance 中执行命令

bash 复制代码
singularity exec \
  instance://my-instance \
  ps -ef

23.5 停止 instance

bash 复制代码
singularity instance stop \
  my-instance

停止全部:

bash 复制代码
singularity instance stop --all

强制:

bash 复制代码
singularity instance stop \
  --force \
  my-instance

23.6 使用 bind 启动 instance

bash 复制代码
singularity instance start \
  --bind /groups/myproject:/project \
  image.sif \
  my-instance

23.7 instance 与 Docker 容器的区别

text 复制代码
Docker:
停止的容器对象通常仍可在 docker ps -a 中看到

Singularity:
普通 exec/run/shell 不留下对象
只有 instance 是后台可管理实例

24. 网络和端口

24.1 默认网络

普通 Singularity 容器通常直接使用宿主机网络 namespace。

因此:

text 复制代码
容器访问外网
通常与宿主机相同

容器监听端口
通常直接监听宿主机对应接口

这与 Docker 默认 bridge + -p 端口映射不同。

24.2 测试网络

bash 复制代码
singularity exec image.sif \
  getent hosts cloud.r-project.org
bash 复制代码
singularity exec image.sif \
  curl -I https://cloud.r-project.org

24.3 独立网络 namespace

bash 复制代码
singularity exec \
  --net \
  image.sif \
  ip addr

是否允许普通用户使用取决于管理员配置。

24.4 指定网络类型

bash 复制代码
singularity exec \
  --net \
  --network bridge \
  image.sif \
  command

24.5 端口映射

在独立网络模式下,可能使用:

bash 复制代码
singularity exec \
  --net \
  --network bridge \
  --network-args "portmap=8888:8888/tcp" \
  image.sif \
  command

Singularity 3.5 的网络功能受 CNI、setuid、fakeroot 和管理员配置影响。在 HPC 上更常见的是直接使用宿主网络,并通过 SSH 隧道访问 Jupyter。

24.6 Jupyter 常见用法

计算节点运行:

bash 复制代码
singularity exec \
  --bind /groups/myproject:/project \
  image.sif \
  jupyter lab \
  --ip=0.0.0.0 \
  --port=8888 \
  --no-browser

本地建立 SSH 隧道:

bash 复制代码
ssh -L 8888:计算节点名:8888 \
  user@登录节点

具体网络路径需要结合集群架构调整。


25. CPU、内存和多核

Singularity 不会默认把程序限制为单核。

程序能使用多少资源取决于:

text 复制代码
Slurm 分配
宿主机 cgroup
程序自身线程设置
算法是否支持并行

25.1 查看容器中的 CPU

bash 复制代码
singularity exec image.sif \
  nproc
bash 复制代码
singularity exec image.sif \
  grep -c '^processor' /proc/cpuinfo

这些命令有时会看到整台节点,而不是 Slurm 分配值。

在 R 中优先读取:

r 复制代码
n_cores <- as.integer(
  Sys.getenv("SLURM_CPUS_PER_TASK", "1")
)

25.2 线程变量

bash 复制代码
export OMP_NUM_THREADS=8
export OPENBLAS_NUM_THREADS=8
export MKL_NUM_THREADS=8

export SINGULARITYENV_OMP_NUM_THREADS=8
export SINGULARITYENV_OPENBLAS_NUM_THREADS=8
export SINGULARITYENV_MKL_NUM_THREADS=8

25.3 Singularity cgroups

Singularity 3.5 支持:

bash 复制代码
singularity exec \
  --apply-cgroups cgroups.toml \
  image.sif \
  command

但 3.5 中通常需要 root,HPC 上更推荐让 Slurm 管理 CPU 和内存。

25.4 Slurm 分配优先

bash 复制代码
srun \
  --cpus-per-task=8 \
  --mem=32G \
  singularity exec image.sif \
  command

Singularity 进程会在 Slurm 作业的资源限制内运行。


26. NVIDIA GPU 和 CUDA

26.1 宿主机要求

宿主机必须有:

text 复制代码
NVIDIA GPU
NVIDIA 驱动
可用的 /dev/nvidia* 设备

检查:

bash 复制代码
nvidia-smi

26.2 使用 --nv

bash 复制代码
singularity exec \
  --nv \
  gpu-image.sif \
  nvidia-smi

Singularity 会将宿主机的 NVIDIA 设备和必要驱动库暴露给容器。

26.3 Python GPU

bash 复制代码
singularity exec \
  --nv \
  gpu-image.sif \
  python -c '
import torch
print(torch.cuda.is_available())
print(torch.cuda.get_device_name(0))
'

26.4 Slurm GPU

bash 复制代码
#!/bin/bash
#SBATCH --gres=gpu:1
#SBATCH --cpus-per-task=8
#SBATCH --mem=32G

singularity exec \
  --nv \
  gpu-image.sif \
  python train.py

26.5 CUDA 兼容性

容器可以包含:

text 复制代码
CUDA runtime
cuDNN
PyTorch
TensorFlow

但宿主机驱动必须能支持容器所需 CUDA runtime。

26.6 GPU 可见性

Slurm 通常设置:

text 复制代码
CUDA_VISIBLE_DEVICES

检查:

bash 复制代码
echo "$CUDA_VISIBLE_DEVICES"

singularity exec \
  --nv \
  image.sif \
  env | grep CUDA_VISIBLE_DEVICES

27. Singularity 与 Slurm

27.1 基本提交脚本

bash 复制代码
#!/bin/bash

#SBATCH --job-name=r431
#SBATCH --cpus-per-task=8
#SBATCH --mem=32G
#SBATCH --time=04:00:00
#SBATCH --output=/groups/myproject/logs/r431_%j.log
#SBATCH --error=/groups/myproject/logs/r431_%j.err

set -euo pipefail

IMAGE="$HOME/containers/r431-analysis-1.0.sif"
PROJECT="/groups/myproject"

export OMP_NUM_THREADS="${SLURM_CPUS_PER_TASK:-1}"
export OPENBLAS_NUM_THREADS="${SLURM_CPUS_PER_TASK:-1}"
export MKL_NUM_THREADS="${SLURM_CPUS_PER_TASK:-1}"

export SINGULARITYENV_OMP_NUM_THREADS="$OMP_NUM_THREADS"
export SINGULARITYENV_OPENBLAS_NUM_THREADS="$OPENBLAS_NUM_THREADS"
export SINGULARITYENV_MKL_NUM_THREADS="$MKL_NUM_THREADS"

singularity exec \
  --cleanenv \
  --bind "${PROJECT}:/project" \
  "${IMAGE}" \
  /opt/conda/bin/Rscript \
  /project/code/analysis.R

提交:

bash 复制代码
sbatch run_r431.slurm

27.2 使用 srun

bash 复制代码
srun \
  --cpus-per-task=8 \
  --mem=32G \
  singularity exec \
  --cleanenv \
  --bind /groups/myproject:/project \
  image.sif \
  /opt/conda/bin/Rscript \
  /project/analysis.R

27.3 为什么不要在计算节点在线拉镜像

不推荐:

bash 复制代码
srun singularity exec \
  docker://repository/image:tag \
  command

原因:

text 复制代码
每个任务可能重复下载或转换
共享缓存可能发生竞争
计算节点可能没有外网
作业启动变慢
远程标签可能变化

推荐提前:

bash 复制代码
singularity pull image.sif docker://repository/image:tag

Slurm 只运行本地 SIF。

27.4 数组任务

bash 复制代码
#!/bin/bash

#SBATCH --array=1-100
#SBATCH --cpus-per-task=4
#SBATCH --mem=16G

IMAGE="$HOME/containers/r431.sif"
PROJECT="/groups/myproject"

singularity exec \
  --cleanenv \
  --bind "${PROJECT}:/project" \
  "${IMAGE}" \
  /opt/conda/bin/Rscript \
  /project/code/run_one.R \
  "${SLURM_ARRAY_TASK_ID}"

27.5 多任务并发读取同一个 SIF

只读 SIF 可以被多个作业同时读取:

text 复制代码
job 1 ─┐
job 2 ─┼── image.sif
job 3 ─┘

不要让多个作业同时写同一个 overlay。


28. MPI 和多节点任务

MPI 容器需要特别注意:

text 复制代码
宿主机 MPI
容器内 MPI
PMI/PMIx
高速互联库
Slurm 配置

常见模式:

bash 复制代码
srun \
  -N 2 \
  -n 32 \
  singularity exec \
  mpi-image.sif \
  /opt/app/mpi_program

但是否可用取决于:

text 复制代码
容器内 MPI 与宿主 MPI ABI 兼容
PMI/PMIx 配置
InfiniBand / UCX 库
管理员模块

不要直接假设单节点镜像可以无修改运行多节点 MPI。

先咨询管理员提供的:

text 复制代码
推荐 MPI 模块
推荐 Singularity 镜像构建方式
srun 参数
UCX/PMIx 绑定要求

普通 R 多进程分析不等于 MPI,多数情况下只需要:

bash 复制代码
#SBATCH --cpus-per-task=8

29. 镜像签名、验证和校验

29.1 SHA256 校验

最简单可靠的文件完整性检查:

bash 复制代码
sha256sum image.sif \
  > image.sif.sha256

验证:

bash 复制代码
sha256sum -c image.sif.sha256

29.2 Singularity 签名

查看密钥:

bash 复制代码
singularity key list

创建密钥:

bash 复制代码
singularity key newpair

签名:

bash 复制代码
singularity sign image.sif

验证:

bash 复制代码
singularity verify image.sif

旧版 Singularity 3.5 的远程 keyserver 可用性可能受服务变化影响。科研内部归档至少保存 SHA256。

29.3 查看 SIF 对象

bash 复制代码
singularity sif list image.sif

30. 镜像复制、迁移和归档

30.1 复制 SIF

bash 复制代码
cp image.sif /backup/containers/

30.2 远程传输

bash 复制代码
scp image.sif \
  user@server:/path/containers/

大文件可使用:

bash 复制代码
rsync -avP image.sif \
  user@server:/path/containers/

30.3 压缩是否必要

SIF 内部通常已经包含压缩的 SquashFS,额外 gzip 未必显著缩小。

可以比较:

bash 复制代码
ls -lh image.sif

gzip -k image.sif

ls -lh image.sif.gz

30.4 归档建议

同时保存:

text 复制代码
image.sif
image.sif.sha256
Dockerfile
environment.yml
definition file
renv.lock
代码版本
构建日期
镜像版本说明

30.5 镜像命名

推荐:

text 复制代码
r431-analysis-1.0.sif
r431-analysis-1.1.sif
r431-analysis-2026-07-11.sif

不要只使用:

text 复制代码
latest.sif
final.sif
new-final-2.sif

31. 日志、调试和故障排查

31.1 查看版本和位置

bash 复制代码
command -v singularity
singularity version
readlink -f "$(command -v singularity)"

31.2 调试运行

bash 复制代码
singularity --debug exec \
  image.sif \
  command

31.3 查看退出码

bash 复制代码
singularity exec image.sif command

status=$?

echo "$status"

31.4 FATAL: container creation failed

检查:

bash 复制代码
singularity --debug exec image.sif true

可能原因:

text 复制代码
SIF 文件损坏
内核功能不支持
管理员禁用 bind/overlay
/tmp 空间不足
共享文件系统限制
setuid 安装异常

31.5 no space left on device

检查:

bash 复制代码
df -hT
df -hT /tmp
du -sh "$HOME/.singularity/cache"
singularity cache list

清理:

bash 复制代码
singularity cache clean --dry-run
singularity cache clean

更换临时目录:

bash 复制代码
export SINGULARITY_TMPDIR="/local_scratch/$USER/singularity-tmp"

31.6 Docker 镜像拉取失败

使用详细模式:

bash 复制代码
singularity --debug pull \
  image.sif \
  docker://repository/image:tag

可能原因:

text 复制代码
Singularity 3.5 过旧
OCI manifest 或压缩格式不兼容
Docker Hub 限流
私有仓库认证
代理或证书问题
镜像架构不匹配

替代方案:

text 复制代码
在 Docker 机器 docker save 为 tar
再用 docker-archive 转 SIF

31.7 permission denied 写 SIF

SIF 默认只读。

使用:

text 复制代码
sandbox
overlay
--writable-tmpfs
宿主机绑定的可写目录

31.8 fakeroot 不可用

检查:

bash 复制代码
grep "^$(whoami):" /etc/subuid
grep "^$(whoami):" /etc/subgid

若没有映射,联系管理员。

31.9 bind 失败

检查宿主机源路径:

bash 复制代码
ls -ld /groups/myproject

查看帮助:

bash 复制代码
singularity exec --help | grep -A3 bind

测试:

bash 复制代码
singularity --debug exec \
  -B /groups/myproject:/project \
  image.sif \
  ls -ld /project

管理员可能关闭 user bind control。

31.10 宿主机 R 包污染容器

使用:

bash 复制代码
singularity exec \
  --cleanenv \
  --no-home \
  image.sif \
  /opt/conda/bin/Rscript \
  -e 'print(.libPaths())'

必要时将项目目录显式绑定。

31.11 GPU 不可见

先检查宿主机:

bash 复制代码
nvidia-smi

再检查容器:

bash 复制代码
singularity exec \
  --nv \
  image.sif \
  nvidia-smi

检查 Slurm 分配:

bash 复制代码
echo "$CUDA_VISIBLE_DEVICES"

31.12 GLIBC_x.x not found

容器程序通常使用容器用户空间 glibc,但仍可能因为:

text 复制代码
宿主机内核太旧
错误绑定宿主库
程序引用宿主路径
GPU 驱动库兼容问题

先使用 --cleanenv,避免错误的 LD_LIBRARY_PATH

31.13 清除环境变量干扰

bash 复制代码
env -i \
  HOME="$HOME" \
  USER="$USER" \
  PATH="/usr/local/bin:/usr/bin:/bin" \
  singularity exec \
  --cleanenv \
  image.sif \
  command

32. Singularity 3.5.0 的限制和升级建议

Singularity 3.5.0 已是较老版本。

可能遇到:

text 复制代码
现代 OCI manifest 不兼容
新型 layer 压缩不兼容
Docker Registry 认证变化
安全修复缺失
fakeroot 和 overlay 功能较旧
GPU 库发现不如新版完善
旧远程 Library/keyserver 不可用

可以先继续使用它运行已有 SIF。

推荐优先级:

text 复制代码
1. 运行已有 SIF
2. 使用 Docker tar 转 SIF
3. 避免直接依赖最新远程 OCI 特性
4. 请求管理员升级到较新的 SingularityCE 或 Apptainer

询问管理员时可以提供:

text 复制代码
当前版本:Singularity 3.5.0
需求:运行 Docker/OCI 转换的 R/Python SIF
需求:NVIDIA --nv
需求:fakeroot 或管理员构建
需求:Slurm 计算节点统一可用

33. Singularity 与 Docker 常用概念对照

text 复制代码
Docker                         Singularity

Dockerfile                     definition file(.def)

Docker image                   SIF 文件

docker build                   singularity build

docker pull                    singularity pull

docker run                     singularity run / exec

docker exec                    singularity exec instance://name
                               或直接 exec SIF

docker container               普通运行进程
                               后台服务用 instance

Docker writable layer          sandbox / overlay / tmpfs

docker ps                      singularity instance list
                               仅适用于 instance

docker commit                  没有完全同等日常命令
                               推荐 sandbox/def 重建

docker save                    SIF 本身可直接复制

Docker volume / bind mount     --bind / -B

Docker daemon                  普通 Singularity 无中央 daemon

Docker bridge + -p             默认共享宿主网络
                               独立网络需 --net/CNI

--gpus all                     --nv

34. 常用命令速查表

状态

bash 复制代码
command -v singularity
singularity version
singularity --help
singularity help exec

拉取镜像

bash 复制代码
singularity pull \
  image.sif \
  docker://repository/image:tag

Docker tar 转 SIF

bash 复制代码
singularity build \
  image.sif \
  docker-archive:/absolute/path/image.tar

运行

bash 复制代码
singularity exec image.sif command
singularity run image.sif
singularity shell image.sif
singularity test image.sif

隔离

bash 复制代码
singularity exec \
  --cleanenv \
  --containall \
  image.sif \
  command

bind

bash 复制代码
singularity exec \
  -B /host/path:/container/path \
  image.sif \
  command

只读:

bash 复制代码
singularity exec \
  -B /host/data:/data:ro \
  image.sif \
  command

环境变量

bash 复制代码
SINGULARITYENV_THREADS=8 \
singularity exec image.sif \
  env

PATH:

bash 复制代码
SINGULARITYENV_PREPEND_PATH=/opt/conda/bin \
singularity exec image.sif \
  command -v R

查看镜像

bash 复制代码
singularity inspect image.sif
singularity inspect --json image.sif
singularity inspect --deffile image.sif
singularity inspect --runscript image.sif
singularity sif list image.sif

缓存

bash 复制代码
singularity cache list
singularity cache list --verbose
singularity cache clean --dry-run
singularity cache clean

自定义缓存和临时目录

bash 复制代码
export SINGULARITY_CACHEDIR="$HOME/singularity/cache"
export SINGULARITY_TMPDIR="/tmp/$USER/singularity-tmp"

构建 def

bash 复制代码
sudo -E singularity build \
  image.sif \
  image.def

或者:

bash 复制代码
singularity build \
  --fakeroot \
  image.sif \
  image.def

sandbox

bash 复制代码
singularity build \
  --sandbox sandbox-dir \
  image.sif
bash 复制代码
singularity shell \
  --fakeroot \
  --writable \
  sandbox-dir
bash 复制代码
singularity build \
  new-image.sif \
  sandbox-dir

临时可写

bash 复制代码
singularity shell \
  --writable-tmpfs \
  image.sif

overlay

bash 复制代码
singularity exec \
  --overlay overlay.img \
  image.sif \
  command

instance

bash 复制代码
singularity instance start \
  image.sif \
  instance-name

singularity instance list

singularity shell \
  instance://instance-name

singularity instance stop \
  instance-name

GPU

bash 复制代码
singularity exec \
  --nv \
  image.sif \
  nvidia-smi

R 4.3.1

bash 复制代码
singularity exec \
  --cleanenv \
  r431-analysis.sif \
  /opt/conda/bin/Rscript \
  -e 'sessionInfo()'

校验

bash 复制代码
sha256sum image.sif \
  > image.sif.sha256

sha256sum -c image.sif.sha256

调试

bash 复制代码
singularity --debug exec \
  image.sif \
  command

35. 推荐的科研工作流

35.1 构建阶段

text 复制代码
Dockerfile + environment.yml
        ↓
Docker 构建和测试
        ↓
docker save 导出 tar

35.2 HPC 转换阶段

bash 复制代码
singularity build \
  r431-analysis-1.0.sif \
  docker-archive:r431-analysis-1.0.tar

35.3 正式运行阶段

bash 复制代码
singularity exec \
  --cleanenv \
  --bind /groups/myproject:/project \
  r431-analysis-1.0.sif \
  /opt/conda/bin/Rscript \
  /project/code/analysis.R

35.4 新增软件包

临时测试:

text 复制代码
sandbox 或 overlay

正式保存:

text 复制代码
修改 Dockerfile/environment.yml/definition file
    ↓
重建 r431-analysis-1.1
    ↓
转换 r431-analysis-1.1.sif

35.5 环境版本管理

text 复制代码
r431-analysis-1.0.sif
r431-analysis-1.1.sif
r431-analysis-1.2.sif

不要覆盖旧镜像,直到新版本验证完成。

35.6 项目目录

text 复制代码
/groups/myproject/
├── code/
├── data/
├── results/
├── logs/
├── Dockerfile
├── environment.yml
├── r431.def
└── README.md

镜像:

text 复制代码
$HOME/containers/
├── r431-analysis-1.0.sif
├── r431-analysis-1.0.sif.sha256
├── r431-analysis-1.1.sif
└── r431-analysis-1.1.sif.sha256

35.7 最核心原则

text 复制代码
SIF 保存软件环境
宿主机 bind 目录保存代码、数据和结果
Slurm 分配 CPU、内存和 GPU
Singularity 负责在作业中运行环境

36. 官方文档

Singularity 3.5 User Guide:

text 复制代码
https://docs.sylabs.io/guides/3.5/user-guide/

Singularity 3.5 Admin Guide:

text 复制代码
https://docs.sylabs.io/guides/3.5/admin-guide/

SingularityCE 当前 User Guide:

text 复制代码
https://docs.sylabs.io/guides/latest/user-guide/

SingularityCE 当前 Admin Guide:

text 复制代码
https://docs.sylabs.io/guides/latest/admin-guide/

Slurm Containers:

text 复制代码
https://slurm.schedmd.com/containers.html
相关推荐
点云SLAM7 个月前
Singularity 英文单词学习
人工智能·学习·奇异点·英文单词学习·雅思备考·singularity