环境准备:本地Docker、Cromwell安装、虚拟机设置
说实话,很多混合云迁移项目最后栽在第一步——环境没搭利索。我见过团队花了两周调Cromwell,结果发现是Docker版本不兼容,一怒之下全重装了。咱们别走那个弯路。
这一章的目标很简单:在你的本地机器上搭出一个能跑Cromwell的最小环境。包括三块——Docker、Cromwell本体、还有必须的虚拟机/云主机连通配置。我会按我自己的安装流水线来讲,你跟着做就行。
基础设施概览
先看整体逻辑,心里有个谱:
关键链路:Docker 装在本地或跳板机上 → Cromwell 以 JAR 或容器方式运行 → 通过 SSH 或 HTTP 向远程虚拟机/云主机下发任务。三者网络必须打通,否则后面全是空转。
第一步:安装 Docker
Docker 这东西现在基本成了基础设施标配。但我建议你别图省事直接 apt install docker.io,那种版本经常落后一两个大版本。我习惯从官方仓库装,干净又可控。
Ubuntu 下标准操作:
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
装完别忘了把当前用户加入 docker 组,省得每次 sudo:
sudo usermod -aG docker $USER
newgrp docker # 或者重新登录一次
小技巧:检验是否成功,跑个 docker run hello-world。如果提示“permission denied”,那就是组没生效——我最开始也犯过这个错,后来学乖了,每次都先跑一遍这个测试。
第二步:安装 Cromwell
Cromwell 本质是个 Java 应用,一个 JAR 包搞定。我个人喜欢直接下载最新版,而不是用包管理器:
wget https://github.com/broadinstitute/cromwell/releases/download/87/cromwell-87.jar
mv cromwell-87.jar /opt/cromwell/
然后你需要一个配置文件。Cromwell 默认会连本地 H2 数据库,但混合云场景我强烈建议用 MySQL 或 PostgreSQL,后面任务多了 H2 扛不住。这是我的最小配置模板:
# cromwell.conf
include required(classpath("application"))
backend {
default = "Local"
providers {
Local {
actor-factory = "cromwell.backend.impl.sfs.config.ConfigBackendLifecycleActorFactory"
config {
root = "/mnt/cromwell-workflow-root"
filesystems {
local {
localization = "copy"
}
}
}
}
}
}
database {
profile = "slick.jdbc.MySQLProfile$"
db {
driver = "com.mysql.cj.jdbc.Driver"
url = "jdbc:mysql://localhost:3306/cromwell?useSSL=false&allowPublicKeyRetrieval=true"
user = "cromwell"
password = "your_password"
connectionTimeout = 5000
}
}
启动 Cromwell:
java -jar /opt/cromwell/cromwell-87.jar server --config /etc/cromwell/cromwell.conf
等几秒钟,看到日志输出 Server running at http://0.0.0.0:8000 就说明成功了。我记得有一次配置里漏写了数据库驱动,启动直接报错,查了半天才发现是 mysql-connector-java 没放到类路径里。所以如果你用 MySQL,记得额外下载 jar 放到 lib 目录:
wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.33/mysql-connector-java-8.0.33.jar
java -cp "/opt/cromwell/cromwell-87.jar:/opt/cromwell/lib/*" cromwell.CromwellApp server --config /etc/cromwell/cromwell.conf
第三步:配置虚拟机 / 云主机
Cromwell 只负责调度,实际干活的是远程机器。我常用的模式是:在本地或跳板机跑 Cromwell,然后通过 SSH 把任务发到一台或多台 Ubuntu 22.04 云主机上。
你需要确保远程机器满足这些条件:
| 项目 | 最低要求 | 推荐配置 |
|---|---|---|
| 操作系统 | Ubuntu 18.04 / CentOS 7 | Ubuntu 22.04 LTS / Rocky Linux 9 |
| CPU | 2 核 | 8 核以上 |
| 内存 | 4 GB | 16 GB + 交换空间 |
| 磁盘 | 40 GB(系统 + 临时数据) | 200 GB SSD + 单独数据盘 |
| 网络 | SSH 端口可达(默认 22) | 内网 VPC + 安全组放行 22、8000 |
| 运行时 | Docker CE 20.10+ | Docker CE 24+ |
关键的 SSH 配置。我通常创建一个专用用户 cromwell 并配好密钥:
# 在远程机器上
sudo useradd -m -s /bin/bash cromwell
sudo mkdir -p ~cromwell/.ssh
echo "ssh-rsa AAA... your-public-key" | sudo tee ~cromwell/.ssh/authorized_keys
sudo chmod 600 ~cromwell/.ssh/authorized_keys
sudo chown -R cromwell:cromwell ~cromwell/.ssh
# 允许该用户执行 docker(重要)
sudo usermod -aG docker cromwell
然后在 Cromwell 的配置里加一个 SSH 后端。我给个简化示例:
# cromwell.conf 增加 backend provider
backend {
default = "SshBackend"
providers {
SshBackend {
actor-factory = "cromwell.backend.impl.sfs.config.SshBackendLifecycleActorFactory"
config {
root = "/home/cromwell/cromwell-root"
filesystems {
local {
localization = "copy"
}
}
connection {
host = "10.0.1.100"
user = "cromwell"
key-file = "/home/youruser/.ssh/id_rsa"
timeout = 30
}
}
}
}
}
注意:我曾经踩过一个大坑——远程机器上的 Docker daemon 没有设置数据目录权限,导致 Cromwell 下发的容器创建失败,但错误信息只显示“exit code 125”。排查了半天。所以装完 Docker 后一定要用 docker run --rm hello-world 在远程机器上验证一遍。
验证端到端连通性
环境都搭好了,咱们跑个最小的 WDL 测试一下:
# hello.wdl
workflow hello {
call sayHello
}
task sayHello {
command {
echo "Hello from Cromwell!"
}
output {
String out = read_string(stdout())
}
runtime {
docker: "ubuntu:latest"
}
}
提交任务:
curl -X POST http://localhost:8000/api/workflows/v1 \
-F workflowSource=@hello.wdl \
-F workflowInputs={}
如果一切顺利,你会得到类似这样的返回:
{
"id": "a1b2c3d4-...",
"status": "Submitted"
}
然后轮询状态:
curl -s http://localhost:8000/api/workflows/v1/a1b2c3d4-.../status
看到 "Succeeded" 的那一刻,环境准备就算彻底完成了。嗯,其实还有一种更快的验证方式——直接看日志里有没有明晃晃的 Backend initialization complete.。
常见问题速查
- Docker daemon 没启动 → 手动跑
sudo systemctl start docker && sudo systemctl enable docker - Cromwell 启动报数据库连接失败 → 检查 MySQL 是否允许远程连接,以及
cromwell用户是否有建表权限 - 任务卡在 Queued 状态 → 大概率 SSH 连不上远程主机,先手动
ssh cromwell@10.0.1.100试试 - 容器退出的错误码 125/137 → 通常是资源限制导致 OOM,检查远程机器的
docker info中内存限制是否打开
一句话总结:本地 Docker 装好 → Cromwell JAR 跑起来 → 远程虚拟机配好 SSH 密钥和 Docker → 用 hello.wdl 走通全流程。底层网络连通是地基,数据库持久化是长期跑的保障。做到这两点,后面的混合云迁移就有了一个稳当的起点。