2. 容器化技术选型:Docker 与 Singularity 对比
当年我第一次给实验室搭建生信平台时,就被问住过一个问题:
“我们用 Docker 还是 Singularity?”
说实话,那时候我凭直觉选了 Docker,因为生态好、教程多。结果部署到 HPC 集群上,管理员直接拒绝了——没有 root 权限,Docker daemon 跑不起来。这事让我记住了:选容器技术,不能只看本地好不好用。
2.1 为什么这两个是主角?
生物信息学里,容器化有两个主流流派:
Docker —— 江湖老大哥,云计算、微服务、DevOps 几乎都是它的地盘。
Singularity —— HPC 亲儿子,专为高性能计算和共享集群而生。
我个人的经验是:**如果你只在个人工作站或云服务器上跑 MaxQuant,Docker 完全够用;但一旦要上学校或机构的超算,Singularity 几乎是必选项。** 我们来看它们到底差在哪。
2.2 核心差异一览
| 维度 | Docker | Singularity |
|---|---|---|
| 运行权限 | 需要 root / sudo 权限启动 daemon | 普通用户即可运行(无 daemon) |
| 用户模型 | 默认以 root 运行容器内进程(可映射) | 自动继承宿主机用户 ID,无提权风险 |
| 文件系统 | 分层镜像,写时复制(overlay2) | Singularity Image File (SIF),单文件 |
| GPU 支持 | 需 nvidia-docker2 或 --gpus 标志 | 原生支持 --nv 参数,开箱即用 |
| MPI 支持 | 需要额外配置网络和 IPC | 原生支持 InfiniBand 和 MPI |
| 镜像格式 | Docker Image(分层 tar) | SIF / sandbox / docker 镜像可转换 |
| HPC 友好度 | 差(daemon 模型、特权要求) | 好(无守护进程、资源管理器直接调度) |
| 生态丰富度 | 极高(Docker Hub 百万级镜像) | 中等(可使用 Docker Hub 镜像转换) |
一句话总结: Docker 强在生态和易用性,Singularity 强在安全性和 HPC 兼容性。我们的 MaxQuant 部署需要两者兼顾。
2.3 深入对比:三个关键场景
场景一:权限与安全性
我有个惨痛教训。一次在共享集群上,有人用 Docker 拉了个镜像,容器内进程无意中修改了 /tmp 下的文件,导致其他用户的作业全部崩溃。管理员查了半天,最后直接把 Docker 禁用了。
Singularity 就不会出这种问题。它默认以当前用户的 UID/GID 运行容器内进程,你想改 /etc/passwd 都改不了——权限被严格隔离。说白了,Singularity 的设计哲学是「容器里的进程就是你本人」,而不是「容器里的进程是 root」。
场景二:HPC 调度器集成
在 Slurm 或 PBS 集群上,你要这样提交 Singularity 作业:
#!/bin/bash
#SBATCH --job-name=MaxQuant_Test
#SBATCH --partition=gpu
#SBATCH --gres=gpu:1
singularity exec --nv /path/to/maxquant.sif \
/opt/MaxQuant/bin/MaxQuantCmd /data/rawfile.raw
而 Docker 在集群上的玩法要复杂得多。你需要:
- 每个节点都启动 docker daemon(通常需要 sudo)
- 把本地镜像同步到所有节点(或者搭私有 registry)
- 小心处理网络和共享存储的挂载
我个人在搭建基因测序流程时,就是因为 Docker 的这一套太重,最后全部迁移到了 Singularity。迁移过程其实不麻烦——SIF 可以直接从 Docker 镜像转换。
singularity pull maxquant.sif docker://maxquant/maxquant:v2.1.0
嗯,就是这么一行命令。Docker 镜像生态直接平移过来,你想想看,多省事。
场景三:GPU 与并行计算
MaxQuant 本身不直接调用 GPU(但很多生信工具需要)。不过为了未来的扩展,还是要对比一下。
Docker 的 GPU 支持经历了几个阶段:早期需要装 nvidia-docker2,后来 Docker 19.03 引入了 --gpus 参数,但还是要安装 nvidia-container-toolkit。
Singularity 就简洁得多——加一个 --nv 参数即可,自动挂载 NVIDIA 驱动和设备。
# Docker
docker run --gpus all nvidia/cuda:11.0-base nvidia-smi
# Singularity
singularity exec --nv docker://nvidia/cuda:11.0-base nvidia-smi
我个人偏好 Singularity 这种「不折腾」的风格,尤其是在已经配置好的 HPC 环境上。
2.4 知识结构
下面这张图我想帮你理清选择的逻辑:
2.5 避坑指南
- 不要在 HPC 上直接裸跑 Docker 容器。 我曾经试过在登录节点执行
docker run,结果被管理员直接 kill 了进程——因为 daemon 占用了大量内存。 - 注意 MaxQuant 的 Windows 原生依赖。 Docker 容器里跑 Mono/.NET 应用通常没问题,但 Singularity 对 Windows 兼容性稍弱。如果你遇到启动报错,先检查 SIF 是否从正确的 Docker 镜像转换而来。
- 共享存储的挂载点。 两种容器都支持 bind mount,但 Singularity 默认不会自动挂载家目录和 /tmp——你需要显式加上
-B /scratch参数。我就是因为这个忽略了,跑了两天的作业才发现结果没写进去。
小技巧: 你可以在本地用 Docker 构建和测试 MaxQuant 镜像,然后用 singularity build 命令生成 SIF 文件,直接传输到集群上运行。这样既享受 Docker 的调试便利,又获得 Singularity 的部署安全。
注意: 如果你选择 Singularity 3.x 版本,注意它的 --docker-username 和 --docker-password 参数传输的是明文密码,建议在安全的私有 registry 或使用环境中设置环境变量 SINGULARITY_DOCKER_USERNAME 来避免泄露。
2.6 选型总结
我把最终结论整理成一张快速决策表:
| 你的场景 | 推荐容器方案 | 备注 |
|---|---|---|
| 仅个人笔记本/PC | Docker | 轻量,调试方便 |
| 自建 Linux 服务器 | Docker 或 Singularity | 推荐 Docker + 定期备份 SIF |
| 共享集群(Slurm/PBS) | Singularity | 必选,无例外 |
| 多平台共存(本地开发+生产集群) | Docker 构建 + Singularity 部署 | 也就是本课程的核心策略 |