> For AI agents: the site index is available at https://www.juniortree.com/llms.txt; this page is available as Markdown at https://www.juniortree.com/blog/bring-cloud-native-into-bioinfo.md.
> 云原生以容器化、工作流编排和弹性计算，让生物信息学告别环境配置噩梦，实现高效可复现的科研分析

## Page metadata

- **Published:** 2025-11-14
- **Updated:** 2025-11-14
- **Tags:** 云原生, bioinfo
- **Source URL:** https://www.juniortree.com/blog/bring-cloud-native-into-bioinfo

# 把云原生带入生物信息学

## 什么是云原生

在正式进入生物信息学的科研训练之前，我对云原生（Cloud Native）充满兴趣，云原生指的并不是一个具体的产品，而是一套思想和方法，它的核心思想就是：应用从设计之初，就假设它会运行在“云”这种动态、分布式的环境中

“云原生”这个词现在非常火，但确实很容易让人“不明觉厉”，我来举出一个简单的例子

比如说你要做一个雕塑，传统的方法，你找来一整块巨大的石头，在上面精心雕刻出城堡的每一个部分——城墙、塔楼、吊桥... 最终，你得到一个完美的、连成一体的“城堡”雕塑

这种方法的优点是很坚固，一体性强，但当你要对其中的局部进行修改，比如你不喜欢这个塔楼，你可能得把整个雕塑砸掉重来，或者费巨大力气去“凿”，而且如果吊桥塌了，有可能会影响到整个雕塑

云原生的方法更像是用“乐高”去搭建整个雕塑，你不用一整块石头，而是用一堆标准化的“乐高积木”来搭建，“城墙”是一块积木（一个服务），“塔楼”是另一块积木（另一个服务），吊桥”又是另一块积木（再一个服务）

你把这些积木（微服务）都放进一个个透明的小盒子里（容器，比如 Docker），再把这些盒子交给一个“超级管家”（编排系统，比如 Kubernetes）来管理

云原生的方式有几个优点，第一个是快速迭代，比如说你要是不喜欢这个塔楼，你只要把塔楼的“乐高积木”给换掉即可，完全不影响“城墙”和“吊桥”，可以迅速开发

第二个是高可用性，如果吊桥塌掉了，“超级管家”会自动丢弃掉这个积木，并且迅速替换一个新的上去，在这个过程中，其他部件的功能完全不受影响

第三个是弹性伸缩，如果某天来参观你的雕塑的人非常多，“超级管家”会立刻自动复制 100 个“城堡”盒子（容器），游客一走，再把多余的盒子收回来

普通人接触到的不是“云原生技术”，而是“云原生体验”，最相关的体验就是：那些“理所当然”的丝滑和便捷

最典型的例子就是“双十一”抢购，会有几亿人同时涌入淘宝或京东，云原生系统（那个“超级管家”）检测到史无前例的访问量，它会在几分钟甚至几秒钟内，自动把“支付服务”、“订单服务”这些“乐高盒子”复制成千上万份，分布到全国的服务器上，几小时后，高峰过去，“超级管家”又会自动把多余的几万个“盒子”收回（省钱），这种“需要时无限变多，不需要时立刻消失”的超能力，就是云原生追求的弹性伸缩 (Scalability)

## 云原生能给生物信息学带来什么

### 「一次编译、到处运行」

我想，现在其实接触到云原生技术的同行其实非常多，基本上每台集群上都装的有 Singularity（现在改名叫 Apptainer）

就我自己而言，我跑流程非常讨厌配环境，尤其是我本地的开发环境是 macOS/Ubuntu，集群上使用比较“稳定”（老）的 CentOS，经常是写代码半天，配环境两天，尤其是碰到一些由 C/C++写的“金标准”软件，我们必须要在本地进行手动编译，这下更麻烦啦

但如果我们使用 Docker，这个问题将非常容易解决，我们可以将这些软件封装到容器中，就可以实现“一次编译，到处运行”的效果

比如说我这几天在折腾一个生成残基图的工具—— `ERRAT`[^1]，这个工具是 C++写的，意味着它依赖底层的 C/C++ 库 (like `libstdc++`)，而且你必须配置好完整等构建工具链

结果就是，在本地 (macOS/Ubuntu) 辛辛苦苦编译通过了，一拿到集群 (CentOS) 上，要么是动态链接库（`.so` 文件）缺失，要么是 `glibc` 版本太低，要么是 CPU 架构不匹配……总之就是跑不起来

![](https://s3.juniortree.com/pic/2025/11/f29300a0f5ef2cb6232af89cb52471b3.webp)

很容易就想到用容器的方法，我们可以尝试在容器内对 `ERRAT` 进行编译，在这里使用了一种常见的优化容器体积的方法，多阶段编译，第一阶段因为安装了一些编译工具，导致容器的体积比较大；在第二阶段只有 `ERRAT` 的运行时，所以容器体积非常小

我自测第一阶段容器有 200 多 MB，实际编译出来的运行时只有 30 多MB

```dockerfile
# ====================================================================
# ERRAT-CLI 容器化
# 轻量级容器，仅包含 ERRAT-CLI 工具和必要依赖
# 使用多阶段构建优化镜像大小
# ====================================================================

# ====================================================================
# 第一阶段：构建阶段（Builder Stage）
# 安装编译工具并编译 ERRAT-CLI
# ====================================================================
FROM debian:12-slim AS builder

LABEL maintainer="Protein Analysis Pipeline Team"
LABEL version="1.0"
LABEL description="Builder stage for ERRAT-CLI"

# 设置非交互式安装
ENV DEBIAN_FRONTEND=noninteractive

# 配置 APT 使用清华源（可选，提高国内构建速度）
RUN sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list.d/debian.sources 2>/dev/null || \
    sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list 2>/dev/null || true

# 安装编译工具
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    g++ \
    make \
    ca-certificates \
    && rm -rf /var/lib/apt/lists/*

# 设置工作目录
WORKDIR /workspace

# 复制 ERRAT-CLI 源代码
COPY ERRAT-CLI /workspace/ERRAT-CLI

# 编译 ERRAT-CLI
RUN if [ -d "/workspace/ERRAT-CLI" ] && [ -f "/workspace/ERRAT-CLI/src/errat.cpp" ]; then \
        cd /workspace/ERRAT-CLI && \
        mkdir -p bin && \
        g++ -o bin/errat_cli src/errat.cpp -lm -O3 && \
        chmod +x bin/errat_cli && \
        echo "✓ ERRAT-CLI compiled successfully"; \
    else \
        echo "✗ ERRAT-CLI source not found"; \
        exit 1; \
    fi

# ====================================================================
# 第二阶段：运行阶段（Runtime Stage）
# 只复制编译好的二进制文件，不包含编译工具
# ====================================================================
FROM debian:12-slim

LABEL maintainer="Protein Analysis Pipeline Team"
LABEL version="1.0"
LABEL description="Lightweight container for ERRAT-CLI protein structure analysis tool"

# 设置非交互式安装
ENV DEBIAN_FRONTEND=noninteractive
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8

# 配置 APT 使用清华源
RUN sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list.d/debian.sources 2>/dev/null || \
    sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list 2>/dev/null || true

# 只安装运行时依赖（C++ 标准库等）
# libstdc++6 是 C++ 运行时库，libgcc-s1 是 GCC 运行时库
RUN apt-get update && apt-get install -y --no-install-recommends \
    ca-certificates \
    libstdc++6 \
    libgcc-s1 \
    && rm -rf /var/lib/apt/lists/*

# 设置工作目录
WORKDIR /workspace

# 从构建阶段复制编译好的二进制文件
COPY --from=builder /workspace/ERRAT-CLI/bin/errat_cli /workspace/ERRAT-CLI/bin/errat_cli

# 设置 PATH 环境变量
ENV PATH="/workspace/ERRAT-CLI/bin:$PATH"

# 设置入口点
ENTRYPOINT ["/workspace/ERRAT-CLI/bin/errat_cli"]
CMD ["--help"]
```

编译完成后，在本地的 macOS 上 `docker run ... errat_image ...`，完美运行；在集群上 `singularity run ... docker://your_username/errat_image ...`，也是完美运行

无论在哪里，`ERRAT` 感受到的都是它最“舒服”的、在编译时就固定下来的那个环境，它再也不用担心“水土不服”了

事实上生信就是有如此多的古董代码和软件，我刚开始的时候还尝试去手动修改里面的一些代码，使其能运行，后来越改越烦，这套方法论对于生物信息学这种重度依赖各种“祖传”编译工具的领域来说，简直是革命性的

事实上已经有生物信息学开发者这样干了，也就是 `BioContainers`[^4]，但是我看仓库的提交记录都非常老，而且有些容器没有写好注释，我也不知道能不能用

### 一起来搭乐高（Workflows）

上面我们尝试用 Docker/Singularity 造好了“塔楼” (`ERRAT`)、“城墙” (`BWA`)、“吊桥” (`Samtools`) 这些单个的积木

下一个问题是，要如何把这几十块积木按顺序拼成一个完整的“城堡”，即一个完整的生物信息分析流程

传统方法是，写一个巨大且复杂的 `bash` 脚本，这个脚本非常脆弱，中间任何一步（比如“吊桥”）塌了，都得手动去检查，然后从头再来，非常浪费时间和计算资源

在我刚开始接触 Pipeline 搭建的时候，我就在尝试用这种传统方法，我写了一个很长、很复杂的 Python 脚本，生物信息学的流程搭建通常会涉及到很多工具（调包），也并不所有的工具都给了 Python 的 SDK，比如说前面的 `ERRAT`，你必须使用 Python 里面的 `subprocess` 去调度

用 `subprocess.Run (["errat", ...])` 来调用 `ERRAT`，如果 `ERRAT` 因为某种原因（比如输入文件格式不对）崩溃了，它会返回一个“非零退出码”，但是我的脚本对此一无所知，它会继续运行，直到下一个工具（比如 `Ghostscript`）拿到一个损坏的、不完整的 `ERRAT` 输出文件，然后再次崩溃

然后作为开发者，我只能看到 `Ghostscript` 报错，但真正的案发现场在 `ERRAT`，我必须手动去翻找日志，十分痛苦和恶心

这就是“传统脚本”最大的痛点，它没有“状态”

“拼装说明书” (Workflow) 如何解决？

`Nextflow`[^2] 或 `Snakemake`[^3]，它们的核心思想就是来解决 ` subprocess ` 的这两个问题，它们不是“命令式”的（“第一步跑 A，第二步跑 B”），而是“声明式”的（“我想要 C，而 C 依赖 B，B 依赖 A”）

用 Snakemake 来写这个流程时，会这样写（一个“规则”）：

```python
# 这就是一个“乐高积木”的建造规则
rule run_errat:
    input:  "results/step3.bam"
    output: "results/errat.out"
    # 这里不再是脆弱的 subprocess
    # 而是被 Snakemake "管理" 起来的 shell 命令
    shell:
        """
        errat -i {input} -o {output}
        """
```

当运行 `Snakemake` 时，`Snakemake` 会主动检查 `errat` 命令的退出码，如果它失败了，`Snakemake` 会立刻停止，并明确告知“` run_errat ` 这条规则（这个积木）塌掉了！” 错误定位非常清晰

并且它有“断点断续”，当修复了流程存在的问题，重新运行同一个 `snakemake` 命令，它会检查 `results/step3.bam`，如果发现文件存在且规则没有更改，就会跳过

我目前只用过 `Snakemake`，因为我是一个 Python 开发者，`Snakemake` 的上手比较友好（对于熟练 Python 的人），相较于 `Snakemake`，`Nextflow` 的云原生更加彻底，等我用了再分析吧，目前似乎没有看到什么 based on Go 的流程编排系统

### 从本地迈向云（Beyond the Cloud）

对于云这个概念，我们不必要特别强调是类似于阿里云、腾讯云或者 Azure 和 GCP 那种云服务商，本地的集群也可以当作云，一切我们接触不到的实体都可以称为“云”

#### 集群调度

对于比较有钱的组，通常自己会有裸金属或者集群，但是很多集群都没有专职的人来进行管理，就导致实际的有效计算时间并不长，也就是著名的“科研计算的公地悲剧”（Tragedy of the Commons in Research Computing）

`Nextflow` + `Slurm` 也许可以帮助解决此类问题

基础层：`Slurm` 的 QoS（服务质量）策略：

```bash
# /etc/slurm/slurm.conf
# 为每个学生创建独立账户
AccountStudent1=cpu=100,mem=200G  # 学生1最多用100核+200G内存
AccountStudent2=cpu=100,mem=200G
# ...

# 创建优先级队列
QosName=normal Priority=100 MaxJobs=5  # 普通任务，最多5个并行作业
QosName=urgent Priority=1000 MaxJobs=2 # 紧急任务，高优先级但限2个
```

`Nextflow` 层：自动带上用户身份：

```groovy
// 每个学生在~/.nextflow/config中配置自己的Slurm账户
process {
    executor = 'slurm'
    queue = 'main'
    clusterOptions = '-A student1 --qos=normal'  // 自动带上账户和QoS
}
```

执行流程：

```bash
# 学生1提交（占用8核）
nextflow run rnaseq.nf -profile slurm

# 学生2提交（占用32核）
nextflow run variant.nf -profile slurm

# Slurm自动截停：如果学生2的32核申请会超限，作业进入PENDING队列
# 学生1完成后，学生2自动启动
```

`Nextflow` 本身提供了一些不依赖底层调度器的轻量级并发控制

全局并发限制（Global Concurrency），即使 8 个学生同时提交，`Nextflow` 会全局排队，避免集群瞬间过载

```groovy
// 在集群登录节点的全局配置 /etc/nextflow/config
executor {
    queueSize = 100  // 整个集群最多100个任务同时运行
}

process {
    maxForks = 50    // 单个Nextflow实例最多50个并行任务
}
```

动态资源申请（避免僵尸），学生 A 的 10G 样本自动申请 20G 内存，学生 B 的 1G 样本只申请 2G，资源精确匹配需求，杜绝浪费

```groovy
// 根据输入文件大小自动申请资源
process BWA_MEM {
    memory { 2.GB * fastq_file.sizeGb }  // 文件越大，内存越多
    cpus { fastq_file.sizeGb > 10 ? 16 : 8 } // 大文件用16核

    input:
    path fastq_file

    script:
    "bwa mem -t ${task.cpus} ref.fa $fastq_file"
}
```

如果是八个用户同时提交任务呢？实际的任务执行流程应该是这样的：

| 学生 | 流程              | 申请资源      | 优先级    | Slurm处理      |
| -- | --------------- | --------- | ------ | ---------------- |
| 1  | RNA-seq (N=10)  | 8核, 16G   | normal | 立即运行             |
| 2  | RNA-seq (N=50)  | 32核, 64G  | normal | **排队**（配额超限）     |
| 3  | RNA-seq (N=5)   | 4核, 8G    | urgent | **抢占**学生1资源，立即运行 |
| 4  | Variant calling | 16核, 32G  | normal | 排队               |
| 5  | FastQC (N=100)  | 2核, 4G    | normal | 立即运行             |
| 6  | Deep learning   | 48核, 200G | low    | **无限期等待**（配额最低）  |
| 7  | RNA-seq (N=20)  | 16核, 32G  | normal | 排队               |
| 8  | 测试任务            | 1核, 2G    | normal | 立即运行             |

`Nextflow ` 不管调度，它只负责把任务翻译成 `Slurm` `sbatch` ，真正的调度是由 `sbatch` 来完成，确保了资源调度的公平，尽可能提高实际有效的集群使用实验

#### 云计算

有一些组可能本身不是做生物信息学的，但是在某个课题中需要用到一些高性能计算，他们可能会尝试去购买或者租赁高性能的计算服务器，这其实是不划算的

实际上，一些云服务商，国外的有 Azure CycleCloud[^5]、AWS ParallelCluster[^6]，Google Batch[^7]；国内有阿里云的 E-HPC（弹性高性能计算）[^8]、腾讯云的 THPC[^9]，字节火山云似乎也在搞

它们的核心价值不是“提供一台服务器”，而是“一键部署一个临时的、弹性的 HPC 集群”

我们可以想象一个“优雅的”流程，看看它如何从根本上解决“不划算”的购买服务器问题

假设一个项目在第一天开始，一位以“湿实验”为主的博士生突然需要一个临时的高性能计算环境，来处理 1000 个蛋白质的结构预测。他无需填写冗长的采购申请，而是直接登录了 AWS、Azure 或阿里云，他使用了像 AWS ParallelCluster 或阿里云 E-HPC 这样的服务，仅凭一个简单的配置文件，点击“创建”

神奇的事情在 15 分钟后发生了：云服务商自动为他创建了一个完整、干净且功能齐备的 HPC 集群。这个集群包含了运行所需的一切：一个登录节点用于操作，一个预配置好的 Slurm 调度器（也就是提供 `qstat` 和 `sinfo` 命令的队列系统），以及——在初始状态下——零个计算节点，因为现在还没有任务，所以完全不产生计算费用

到了第一天下午，这位博士生便通过 ssh 登录到这个临时的登录节点，他从 Git 仓库克隆下了一个标准化的 Snakemake 或 Nextflow 分析流程——这是一个可复现、容器化的“作战蓝图”，随后，他运行了一个简单的命令，比如 `snakemake --profile slurm --use-singularity` 或 `nextflow run ... -profile awsbatch`

从这一刻起，“弹性”的魔力便开始显现，并在接下来的 72 小时内持续发挥作用

Snakemake 或 Nextflow 作为“总指挥”，开始读取作战计划，并向 Slurm 这支“执行部队”提交全部 1000 个计算任务。Slurm 的队列瞬间被任务填满。AWS ParallelCluster 这样的云平台检测到了队列中的等待任务，于是自动开始“创建”计算节点，它会根据任务需求，在几分钟内启动 1000 台服务器，让这 1000 个任务得以大规模并行计算

到了第四天，所有任务都已跑完，Snakemake 或 Nextflow 自动汇总了最终结果，此时，由于没有新任务，所有计算节点都已被自动销毁，这位博士生只需将 `results/` 目录打包下载，然后回到云平台控制台，点击“删除”集群

这就是新旧模式的鲜明对比，旧模式是购买服务器：投入 20 万固定资产，每年还需支付 2 万电费和 N 小时的管理员维护时间（如果没人管，很快就沦为“公地悲剧”）；为了跑 1000 个样本，可能要在这台机器上排队等待 1 个月

而新模式是云 HPC 加上“优雅的工作流”：成本是弹性的，假设总共花了 2 万块钱，这是按秒计费的实际用量，效率是惊人的，1 个月的计算量在 3 天内就完成了，最重要的是，维护成本为零，用完即走，不留下一片垃圾

这也是我为啥非常推崇“云”，它把 HPC 从一个“重资产”变成了一种像“自来水”一样的“服务”，而 Snakemake, Nextflow 和 Container，就是能让你拧开这个“水龙头”的完美工具

## 总结

把云原生带入到生物信息学中，能让我们聚焦于算法和数据本身，而无需去关注基础设施本身，这对于我们来说，是一场根本性的变革

这意味着研究者终于可以从“环境配置工程师”、“集群管理员”和“软件打包工”的多重身份中解放出来

当基础设施（无论是你组里的“裸金属”集群，还是公有云）变成一个按需取用、用完即走的“插座”时，“可复现性”就从一个需要额外努力去达成的崇高理想，变成了我们工作流中一个自动实现的“副产品”

你不再需要花费数天时间去解决“`conda` 卡死”或“`glibc` 冲突”，而是通过 `git push` 自动构建一个干净、可控的环境

你不再受限于本地硬件的“天花板”，而是可以（通过云）将一个月的计算任务，弹性扩展到三天内并行完成

最终，这彻底拉平了科研的门槛，一个“湿实验”的课题组可以即时获得并运行一个世界级的计算流程，而一个“干实验”的开发者也能确保自己的分析方法，在五年后、在任何地方，都能被同行 100%地重现

[^1]: [Colovos, C., & Yeates, T. O. (1993). Verification of protein structures: Patterns of nonbonded atomic interactions. Protein Science, 2(9), 1511–1519. https://doi.org/10.1002/pro.5560020916](https://pubmed.ncbi.nlm.nih.gov/8401235/)

[^2]: [Bal, H. E., Steiner, J. G., & Tanenbaum, A. S. (1989). Programming languages for distributed computing systems. ACM Computing Surveys, 21(3), 261–322. https://doi.org/10.1145/72551.72552](https://dl.acm.org/doi/abs/10.1145/72551.72552)

[^3]: [Mölder, F., Jablonski, K. P., Letcher, B., Hall, M. B., Tomkins-Tinch, C. H., Sochat, V., Forster, J., Lee, S., Twardziok, S. O., Kanitz, A., Wilm, A., Holtgrewe, M., Rahmann, S., Nahnsen, S., & Köster, J. (2021). Sustainable data analysis with Snakemake. F1000Research, 10, 33. https://doi.org/10.12688/f1000research.29032.2](https://doi.org/10.12688/f1000research.29032.2)

[^4]: [BioContainer - GitHub](https://github.com/BioContainers/containers)

[^5]: [Galaxy On Cyclecloud - Microsoft Azure](https://azure.microsoft.com/en-us/blog/genomic-analysis-on-galaxy-using-azure-cyclecloud/)

[^6]: [Quickly build HPC compute environments on AWS - AWS ParallelCluster](https://aws.amazon.com/cn/hpc/parallelcluster/)

[^7]: [Batch - Google Cloud](https://cloud.google.com/batch?hl=zh_cn)

[^8]: [弹性高性能计算E-HPC\_超算云\_高性能计算\_弹性计算-阿里云](https://www.aliyun.com/product/ehpc)

[^9]: [高性能计算平台简介\_高性能计算平台购买指南\_高性能计算平台操作指南-腾讯云](https://cloud.tencent.com/document/product/1527)
