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 在集群上的玩法要复杂得多。你需要:

  1. 每个节点都启动 docker daemon(通常需要 sudo)
  2. 把本地镜像同步到所有节点(或者搭私有 registry)
  3. 小心处理网络和共享存储的挂载

我个人在搭建基因测序流程时,就是因为 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 知识结构

下面这张图我想帮你理清选择的逻辑:

容器化技术选型决策流程 部署环境? 本地工作站 / 云服务器 HPC 集群 / 超算 推荐 Docker 生态丰富 · 易于测试 推荐 Singularity 安全 · 无特权 · 调度友好 灵活策略:Docker 构建 → Singularity 运行 利用 Docker 镜像 + singularity pull 转换 💡 我的建议 先在本机用 Docker 调试 部署集群时统一转 SIF

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 部署 也就是本课程的核心策略