Skip to content

Apptainer 简介

2026-01-23 · 1015字 · 4分钟 · 浏览量

参考资料:https://hsf-training.github.io/hsf-training-singularity-webpage/

动机

用 docker/apptainer 等容器工具是为了免去配置环境的痛苦。容器是封装系统环境的软件包。操作系统级别的虚拟化通过容器实现,任何在其上运行的程序都将使用容器内部隔离的上下文环境。它可以在任何系统上构建容器,只要目标平台与容器兼容,即可在任何地方执行该容器。

为什么不用 uv?

对纯 python 项目而言用 uv 管理虚拟环境是足够的,但是如果涉及到非 python 应用,例如我现在要使用 CDM 来评测 Texo,那么就涉及到 LaTeX 发行版的安装,这就比较麻烦了。

为什么不用 docker?

Docker 作为企业级容器框架的初衷是为微服务提供支持,这种方案契合行业惯用的模式:系统管理员以 root 权限启动容器引擎守护进程 daemon,并在各自容器中安装运行应用程序。这种模式与高性能计算(HPC)和高吞吐量计算(HTC)的工作流并不兼容,后者通常运行复杂应用程序时会耗尽所有可用资源,且无需任何特殊权限。运行 docker 需要 root 权限,不适合在公共的服务器集群上使用。

为什么用 apptainer?

  1. 无需 root 权限,运行时容器内部用户即容器外部用户,因此在高性能计算集群上能更安全的管理虚拟环境。
  2. 单文件容器镜像简化分发、归档、共享、使用。
  3. 兼容 docker 镜像,无需额外转换。
  4. 运行方式等同于常规应用,与 Slurm 等服务器调度框架天然兼容。

安装

首先安装 Apptainer。注意若在服务器上无 root 用户权限,可以 rootless 的方式安装,由于我的服务器上已经安装了,故略过这一步。

下载镜像 image

容器镜像是可执行文件.sif,它将应用程序或环境所需的所有组件打包在一起,如同容器的模板。容器则是镜像的运行时实例——它们是具有状态的镜像。Apptainer 可以在注册表(可搜索的镜像与容器目录库及存储库)中存储、搜索和检索镜像。用户可通过命令行界面访问其他用户构建的镜像,将其拉取下来,并在运行时转化为容器。

bash
apptainer pull <local_image_name>.sif <remote_image_url>

例如拉取 docker 环境镜像:

bash
apptainer pull <local_image_name>.sif docker://<docker_image_name>

这里把 dockerhub 上的镜像名放在 docker:// 后,apptainer 会将其识别为 docker 镜像,并将其转换为.sif格式的镜像文件。

运行

启动并退出 shell

用命令

bash
apptainer shell <container_image>.sif

将进入容器并打开一个交互式 shell,得到

Apptainer>

该 shell 类似一个常规 bash shell 与进入 shell 前的宿主机身份一致。此时我们执行的所有命令都是在宿主机中的。

退出方法

Apptainer> exit

或者按组合键 Ctrl+D。请注意,退出 Apptainer 镜像时所有运行进程都会被杀死。保存到绑定目录中的更改将被保留。默认情况下,容器中的其他内容都会丢失(关于可写镜像的内容我们稍后再谈)。

绑定目录

当外部目录在 Apptainer 内部也可访问时,我们称其为绑定或挂载。访问路径可能不同,但外部对其内容的任何操作在内部均可见,反之亦然。默认情况下,apptainer 将挂载用户主目录, /tmp$PWD 绑定到容器中,因此在容器内可以访问这些目录。

通过 --bind 选项可以挂载额外绑定,例如

bash
apptainer shell --bind <host_dir>:<mount_point_in_container> <container_image>.sif

执行命令

exec用于在某个指定容器镜像中运行命令。例如

bash
apptainer exec <container_image>.sif ls

其输出等价于先运行

bash
apptainer shell <container_image>.sif

再在其中运行

Apptainer> ls
返回

人同此心,心同此理;如风沐面,若水润心