Apache DolphinScheduler 在 AWS 云上的一键部署:基于 Packer 构建 AMI 与 Terraform 基础设施编排实战
【免费下载链接】dolphinschedulerApache DolphinScheduler is the modern data orchestration platform. Agile to create high performance workflow with low-code项目地址: https://gitcode.com/gh_mirrors/do/dolphinscheduler
Apache DolphinScheduler 在仓库中提供了面向 AWS 的整套基础设施即代码(IaC)方案,位于 deploy/terraform/aws 目录:先用 HashiCorp Packer 将 DolphinScheduler 发行包(官方发行 tar 或本地构建 tar)固化为自定义 AMI,再用 Terraform 一键拉起 VPC 网络、RDS PostgreSQL 数据库、S3 对象存储、ZooKeeper 与各服务组件(Master / Worker / Alert / API / Standalone)对应的 EC2 实例,实现 standalone 模式与分布式集群模式的分钟级部署。读完本文,你将掌握ds-ami.pkrvars.hcl与terraform.tfvars两个变量文件的完整配置方法、AMI 构建与资源创建的完整命令链路、全部输入/输出参数的含义,以及 cloud-init 在实例启动时自动完成建库与组件拉起的工作原理。
一、方案总览:Packer + Terraform 的分层架构
整套部署脚本分为两个阶段,对应两种工具、两个目录:
| 阶段 | 工具 | 目录 | 产出 |
|---|---|---|---|
| 构建镜像 | Packer | deploy/terraform/aws/packer | 预装 DolphinScheduler 的自定义 AMI |
| 编排资源 | Terraform | deploy/terraform/aws | VPC、RDS、S3、ZooKeeper、五类 EC2 实例 |
外层入口文档 deploy/terraform/README.md 明确说明了这套脚本的定位:在几分钟(甚至几秒)内搭建出 DolphinScheduler 环境(standalone 模式或集群模式)。
1.1 从仓库源码看整体资源拓扑
从 Terraform 的.tf文件可以还原出完整的基础设施拓扑,各.tf文件与职责对应关系如下:
- 网络层:network-main.tf 创建 VPC(默认 CIDR
10.0.0.0/16,enable_dns_hostnames = true)、互联网网关、公网子网(默认 4 段10.0.1.0/24~10.0.4.0/24)、私网子网(默认 4 段10.0.101.0/24~10.0.104.0/24)以及对应的路由表与关联关系; - 数据库层:rds-main.tf 创建 PostgreSQL 14.5 的 RDS 实例(默认
db.t3.micro、5GB 存储),并只放行 Master / Worker / Alert / API / Standalone 五个安全组对 5432 端口的访问; - 对象存储层:s3-main.tf 通过社区模块
terraform-aws-modules/s3-bucket(版本~> 3.6)创建私有 S3 桶,并创建一个专用 IAM 用户(${name_prefix}-s3)与访问密钥,授予该桶s3:*权限,供 DolphinScheduler 的资源存储(resource storage)使用; - 密钥层:key-pair-main.tf 生成 4096 位 RSA 私钥(
tls_private_key),注册为名为dolphinscheduler的 AWS Key Pair,并将私钥落盘为本地dolphinscheduler.pem文件(权限0700); - 注册中心层:zookeeper-main.tf 按需创建单节点 ZooKeeper(详见第 4.4 节);
- 计算层:dolphinscheduler-master.tf、dolphinscheduler-worker.tf、dolphinscheduler-alert.tf、dolphinscheduler-api.tf、dolphinscheduler-standalone.tf 分别创建各组件 EC2 实例;
- 镜像查找:os-versions.tf 通过
data "aws_ami" "dolphinscheduler"按ds_ami_name查找自己账号下(owners = ["self"])的自定义 AMI,同时用data "aws_ami" "amazon-linux"选取 Amazon Linux 2022 作为 ZooKeeper 节点的基础镜像; - 变量与输出:dolphinscheduler-variables.tf 定义组件副本数与 VM 规格,dolphinscheduler-output.tf 暴露各实例的 ID、公网/私网 IP 与公网 DNS。
1.2 组件端口与安全组设计
各组件之间通过内部端口通信,安全组规则严格按“最小开放”原则配置(均来源于各.tf文件中的aws_security_group资源):
| 组件 | 对外端口 | 安全组规则(源码位置) |
|---|---|---|
| API / Standalone | 12345(HTTP) | 对全网开放,另开放 22 端口 SSH(dolphinscheduler-api.tf、dolphinscheduler-standalone.tf) |
| Master | 5678(gRPC) | 仅放行 API 安全组;并通过aws_security_group_rule单独放行 Worker 安全组的 5678 入站(dolphinscheduler-master.tf) |
| Worker | 1234(gRPC) | 仅放行 Master 与 API 安全组,另开放 22 端口(dolphinscheduler-worker.tf) |
| Alert | 50052–50053(gRPC) | 仅放行 Worker 安全组,另开放 22 端口(dolphinscheduler-alert.tf) |
| ZooKeeper | 2181 | 仅放行上述五个组件安全组,另开放 22 端口(zookeeper-main.tf) |
| RDS | 5432 | 仅放行上述五个组件安全组(rds-main.tf) |
需要说明的是,安全组规则中的description字段沿用了模板文本(如 "Allow incoming HTTP connections"),但从端口用途看,12345 承载 Web UI/API,5678/1234/50052-50053 承载组件间 gRPC 通信。
二、环境准备
部署前需要在本地安装两个 HashiCorp 工具(官方 README 明确列为前置条件):
- Packer:用于构建 DolphinScheduler 的 AMI 镜像;
- Terraform:用于编排 AWS 云上资源。
同时你需要一个具备相应权限的 AWS 账号,并准备 Access Key / Secret Key(文章中的变量文件将直接写入,注意保管好密钥,生产环境建议改用环境变量或 Vault 等更安全的方式注入)。
三、构建自定义 AMI(第一步:Packer)
3.1 准备变量文件ds-ami.pkrvars.hcl
创建变量文件ds-ami.pkrvars.hcl,按需填写以下变量(这是原文档给出的完整模板,可直接复制使用):
cat <<EOF > ds-ami.pkrvars.hcl aws_access_key = "" aws_secret_key = "" aws_region = "cn-north-1" ds_ami_name = "my-test-ds-2" # 使用官方发行包:将 ds_version 设置为你要的版本即可 ds_version = "3.1.1" # 使用本地构建的发行包:将 ds_tar 指向本地 tar 文件 ds_tar = "~/workspace/dolphinscheduler/dolphinscheduler-dist/target/apache-dolphinscheduler-3.1.3-SNAPSHOT-bin.tar.gz" EOF变量说明:
| 变量 | 含义 | 必填 |
|---|---|---|
aws_access_key/aws_secret_key | AWS 访问密钥 | 是 |
aws_region | AWS 区域,默认cn-north-1(华北 1) | 否 |
ds_ami_name | 生成的 AMI 名称,后续 Terraform 靠这个名字查找镜像 | 是 |
ds_version | DolphinScheduler 官方发行版本号(官方包方式使用) | 视方式 |
ds_tar | 本地构建的*-bin.tar.gz路径(本地包方式使用) | 视方式 |
ds_version与ds_tar二选一:构建时选择对应的 Packer 模板即可(见 3.2)。
3.2 两种构建方式与命令
- 方式一:使用官方发行 tar
packer init --var-file=ds-ami.pkrvars.hcl packer/ds-ami-official.pkr.hcl packer build --var-file=ds-ami.pkrvars.hcl packer/ds-ami-official.pkr.hcl- 方式二:使用本地构建的 tar
packer init --var-file=ds-ami.pkrvars.hcl packer/ds-ami-local.pkr.hcl packer build --var-file=ds-ami.pkrvars.hcl packer/ds-ami-local.pkr.hclpacker init会按模板中的required_plugins自动安装 Amazon 插件(github.com/hashicorp/amazon,版本>= 0.0.1),packer build执行实际构建。
3.3 AMI 内部构建原理(源码级)
两份 Packer 模板 ds-ami-official.pkr.hcl 与 ds-ami-local.pkr.hcl 结构一致,差异仅在软件安装来源。其关键实现:
Builder(source)配置——amazon-ebs构建器:
- 基础镜像:通过
source_ami_filter筛选最新的 Amazon Linux 2022 AMI(name = "al2022-ami-*"、root-device-type = "ebs"、virtualization-type = "hvm"、architecture = "x86_64",owners = ["amazon"]); - 构建用实例规格
t2.micro,SSH 登录用户ec2-user; - 生成的镜像名
ami_name = var.ds_ami_name。
Provisioner(配置器)——共用同一套 shell 逻辑:
sudo yum remove -y java:移除系统自带 Java;sudo yum install -y java-1.8.0-amazon-corretto.x86_64:安装 Amazon Corretto 8;- 写入环境变量
export JAVA_HOME=/etc/alternatives/jre到/etc/profile.d/java_home.sh; mkdir -p /opt/dolphinscheduler:准备安装目录;- 官方方式用
curl从 Apache 归档下载apache-dolphinscheduler-${ds_version}-bin.tar.gz;本地方式先用provisioner "file"把ds_tar上传到~/dolphinscheduler.tar.gz,再解压; - 两种方式都以
--strip-components 1解压到/opt/dolphinscheduler,保证目录结构与后续 Terraform 脚本的约定一致; find /opt/dolphinscheduler/ -name start.sh | xargs chmod +x:为所有组件的启动脚本添加可执行权限。
最终产物是一个“开箱即用”的 AMI:/opt/dolphinscheduler下已包含完整发行目录结构(master-server/、worker-server/、alert-server/、api-server/、standalone-server/、tools/等子目录),后续每台 EC2 实例直接从该镜像启动,无需重复安装。
四、创建基础设施资源(第二步:Terraform)
4.1 准备变量文件terraform.tfvars
创建terraform.tfvars,按需填写(原文档完整模板):
cat <<EOF > terraform.tfvars aws_access_key = "" aws_secret_key = "" aws_region = "" name_prefix = "test-ds-terraform" ds_ami_name = "my-test-ds" ds_component_replicas = { master = 1 worker = 1 alert = 1 api = 1 standalone_server = 0 } EOF⚠️关键约束:ds_ami_name必须与 3.1 中ds-ami.pkrvars.hcl里的名称完全一致。Terraform 通过 os-versions.tf 中的data "aws_ami" "dolphinscheduler"(按名称精确匹配、owners = ["self"])来定位你刚构建的 AMI,名称不一致将导致terraform apply找不到镜像而失败。
4.2 执行 apply
terraform init -var-file=terraform.tfvars terraform apply -var-file=terraform.tfvars -auto-approveterraform init会下载 AWS Provider 与terraform-aws-modules/s3-bucket等模块,apply一次性创建全部资源。若想手动确认变更计划,可去掉-auto-approve先执行terraform plan。
4.3 组件副本数与实例规格
ds_component_replicas是核心控制开关(定义见 dolphinscheduler-variables.tf),五个键分别对应五类 EC2 实例(count = var.ds_component_replicas.<name>):
| 键 | 对应实例资源 | 默认副本数 | 启动的 DolphinScheduler 组件 |
|---|---|---|---|
master | aws_instance.master | 1 | master-server |
worker | aws_instance.worker | 1 | worker-server |
alert | aws_instance.alert | 1 | alert-server |
api | aws_instance.api | 1 | api-server |
standalone_server | aws_instance.standalone_server | 0 | standalone-server |
两个典型用法:
- 集群模式:保持 master / worker / alert / api 均为 ≥1,
standalone_server = 0(默认配置即此形态); - Standalone 模式:将
standalone_server设为 1,其余四项设为 0,即得到一个单机一体化实例(端口 12345)。
各组件实例的默认规格(同样定义于 dolphinscheduler-variables.tf):
| 组件 | 实例类型 | 根卷(默认) | 数据卷(默认) |
|---|---|---|---|
| master | t2.medium | 30GBgp2 | 10GBgp2 |
| worker | t2.medium | 30GBgp2 | 10GBgp2 |
| api | t2.small | 30GBgp2 | 10GBgp2 |
| alert | t2.micro | 30GBgp2 | 10GBgp2 |
| standalone_server | t2.small | 30GBgp2 | 10GBgp2 |
实例均启用了encrypted = true(EBS 加密)、delete_on_termination = true,并支持通过vm_associate_public_ip_address控制是否分配公网 IP(默认全部为true)。以上全部通过vm_instance_type、vm_root_volume_size、vm_data_volume_size、vm_root_volume_type、vm_data_volume_type等 map 类型变量按组件粒度自定义。
4.4 ZooKeeper 的按需创建逻辑
DolphinScheduler 集群依赖 ZooKeeper 作为注册中心。仓库的处理策略是(见 zookeeper-main.tf 与各组件zookeeper_connect_string的取值):
- 若
zookeeper_connect_string为空字符串(默认),则自动创建 1 台 Amazon Linux 2022 实例(data.aws_ami.amazon-linux),通过 templates/zookeeper/cloud-init.yaml 安装并启动 Docker,随后用remote-exec执行docker run -it --name zookeeper -d -p 2181:2181 zookeeper:3.5拉起单节点 ZooKeeper; - 各组件 user-data 中的
zookeeper_connect_string采用三元表达式:var.zookeeper_connect_string != "" ? var.zookeeper_connect_string : aws_instance.zookeeper[0].private_ip,即用户提供连接串则优先使用(可对接已有 ZooKeeper 集群),否则自动指向新建实例的内网 IP。
⚠️ 原文档特别提醒:自动创建的单节点 ZooKeeper仅用于演示(demonstration),不要在生产环境使用。
4.5 RDS 数据库与 schema 初始化
数据库层由 rds-main.tf 创建:PostgreSQL 14.5、默认实例类db.t3.micro、分配 5GB 存储、skip_final_snapshot = true、publicly_accessible = true、数据库名dolphinscheduler。db_username默认dolphinscheduler,db_password为必填项。
数据库的初始化(建表与元数据升级)并不由 Terraform 直接执行,而是放在实例启动的 cloud-init 阶段:每个组件实例都会先运行dolphinscheduler-schema.service(一次性服务),执行发行包内tools/bin/upgrade-schema.sh完成 schema 创建,再启动正式的服务单元(详见 4.6)。
4.6 实例初始化:cloud-init 与 systemd(源码级)
每台 DolphinScheduler 组件实例的user_data都来自模板 templates/cloud-init.yaml(Terraform 通过template_file渲染),核心逻辑如下:
- 系统用户:创建用户
ds(sudo 免密、加入ssh_authorized_keys),并把公钥同时写入 root 用户,保证运维可登录; - 两个 systemd 单元:
dolphinscheduler-schema.service(Type=oneshot):以ds用户执行bash -l /opt/dolphinscheduler/tools/bin/upgrade-schema.sh,负责初始化数据库 schema;dolphinscheduler.service:Requires=dolphinscheduler-schema.service(保证建库先完成),执行/opt/dolphinscheduler/<component>/bin/start.sh启动对应组件(<component>由各.tf中的dolphinscheduler_component变量注入,分别为master-server、worker-server、alert-server、api-server、standalone-server),并配置Restart=always实现崩溃自动拉起;
- 环境变量注入:两个单元统一注入数据库与注册中心配置:
DATABASE=postgresql、SPRING_PROFILES_ACTIVE=postgresql(激活 PostgreSQL Profile);SPRING_DATASOURCE_URL=jdbc:postgresql://<db_address>:<db_port>/<db_name>、SPRING_DATASOURCE_USERNAME、SPRING_DATASOURCE_PASSWORD(来自 RDS 实例属性);REGISTRY_ZOOKEEPER_CONNECT_STRING(ZooKeeper 连接串);WORKER_ALERT_LISTEN_HOST(告警服务监听地址,当前模板固定为空串占位);
- S3 资源存储配置:
runcmd中对发行包内所有common.properties执行sed批量替换,将资源存储切到 S3:resource.storage.type=S3resource.aws.access.key.id/resource.aws.secret.access.key(来自 s3-main.tf 中aws_iam_access_key.s3)resource.aws.region(当前 AWS 区域)resource.aws.s3.bucket.name(新建桶名)resource.aws.s3.endpoint(当前为空,走 AWS 默认 endpoint)
- 启动编排:
chown -R ds:ds /opt/dolphinscheduler、为start.sh加执行权限、systemctl enable dolphinscheduler并依次start两个服务。
这套设计保证了:实例从 AMI 启动后无需人工干预,自动完成目录权限修复、资源存储配置、建库、组件拉起,最终对外提供可用服务。
五、访问 DolphinScheduler Web UI
资源创建完成后,执行原文档提供的命令打开 Web 界面:
open http://$(terraform output -json api_server_instance_public_dns | jq -r '.[0]'):12345/dolphinscheduler/ui该命令先通过terraform output -json取出 API 实例的公网 DNS(数组第一个元素,jq -r '.[0]'),再拼上端口12345与路径/dolphinscheduler/ui。该 URL 能访问的前提是:api实例的安全组放行了 12345 端口(默认即如此),且vm_associate_public_ip_address.api = true(默认)。
六、全部输入参数(Inputs)
下表为原文档完整收录的全部输入参数(默认值同时与 dolphinscheduler-variables.tf、network-variables.tf、rds-variables.tf、s3-variables.tf、zookeeper-variables.tf 保持一致):
| 名称 | 描述 | 类型 | 默认值 | 必填 |
|---|---|---|---|---|
aws_access_key | AWS access key | string | n/a | 是 |
aws_region | AWS region | string | "cn-north-1" | 否 |
aws_secret_key | AWS secret key | string | n/a | 是 |
db_instance_class | 数据库实例规格 | string | "db.t3.micro" | 否 |
db_password | 数据库密码 | string | n/a | 是 |
db_username | 数据库用户名 | string | "dolphinscheduler" | 否 |
ds_ami_name | DolphinScheduler AMI 名称 | string | "dolphinscheduler-ami" | 否 |
ds_component_replicas | 各组件副本数 | map(number) | {"alert":1, "api":1, "master":1, "standalone_server":0, "worker":1} | 否 |
ds_version | DolphinScheduler 版本 | string | "3.1.1" | 否 |
name_prefix | 所有资源的名称前缀 | string | "dolphinscheduler" | 否 |
private_subnet_cidr_blocks | 私网子网可用 CIDR | list(string) | ["10.0.101.0/24","10.0.102.0/24","10.0.103.0/24","10.0.104.0/24"] | 否 |
public_subnet_cidr_blocks | 公网子网 CIDR | list(string) | ["10.0.1.0/24","10.0.2.0/24","10.0.3.0/24","10.0.4.0/24"] | 否 |
s3_bucket_prefix | S3 桶名前缀 | string | "dolphinscheduler-test-" | 否 |
subnet_count | 子网数量 | map(number) | {"private":2, "public":1} | 否 |
tags | 应用到所有资源的标签 | map(string) | {"Deployment":"Test"} | 否 |
vm_associate_public_ip_address | 是否给 EC2 分配公网 IP | map(bool) | 五组件均true | 否 |
vm_data_volume_size | EC2 数据卷大小 | map(number) | 五组件均10 | 否 |
vm_data_volume_type | EC2 数据卷类型 | map(string) | 五组件均"gp2" | 否 |
vm_instance_type | EC2 实例规格 | map(string) | {"alert":"t2.micro","api":"t2.small","master":"t2.medium","standalone_server":"t2.small","worker":"t2.medium"} | 否 |
vm_root_volume_size | EC2 根卷大小 | map(number) | 五组件均30 | 否 |
vm_root_volume_type | EC2 根卷类型 | map(string) | 五组件均"gp2" | 否 |
vpc_cidr | VPC CIDR | string | "10.0.0.0/16" | 否 |
zookeeper_connect_string | ZooKeeper 连接串;为空则自动创建单节点 ZooKeeper(仅演示用途,勿用于生产) | string | "" | 否 |
七、全部输出参数(Outputs)
terraform apply成功后,所有实例信息与依赖服务地址都可通过terraform output获取。原文档列出的完整输出如下(实现见 dolphinscheduler-output.tf、rds-output.tf、s3-outputs.tf、zookeeper-output.tf):
| 名称 | 描述 |
|---|---|
alert_server_instance_id | Alert 实例 ID |
alert_server_instance_private_ip | Alert 实例私网 IP |
alert_server_instance_public_dns | Alert 实例公网域名 |
alert_server_instance_public_ip | Alert 实例公网 IP |
api_server_instance_id | API 实例 ID |
api_server_instance_private_ip | API 实例私网 IP |
api_server_instance_public_dns | API 实例公网域名 |
api_server_instance_public_ip | API 实例公网 IP |
db_address | 数据库地址 |
db_name | 数据库名 |
db_port | 数据库端口 |
master_server_instance_id | Master 实例 ID |
master_server_instance_private_ip | Master 实例私网 IP |
master_server_instance_public_dns | Master 实例公网域名 |
master_server_instance_public_ip | Master 实例公网 IP |
s3_access_key | S3 访问密钥(ID) |
s3_address | S3 地址 |
s3_bucket | S3 桶名 |
s3_regional_domain_name | S3 区域域名 |
s3_secret | S3 访问密钥(Secret) |
vm_server_instance_id | Standalone 实例 ID |
vm_server_instance_private_ip | Standalone 实例私网 IP |
vm_server_instance_public_dns | Standalone 实例公网域名 |
vm_server_instance_public_ip | Standalone 实例公网 IP |
worker_server_instance_id | Worker 实例 ID |
worker_server_instance_private_ip | Worker 实例私网 IP |
worker_server_instance_public_dns | Worker 实例公网域名 |
worker_server_instance_public_ip | Worker 实例公网 IP |
zookeeper_server_instance_id | ZooKeeper 实例 ID |
zookeeper_server_instance_private_ip | ZooKeeper 实例私网 IP |
zookeeper_server_instance_public_dns | ZooKeeper 实例公网域名 |
zookeeper_server_instance_public_ip | ZooKeeper 实例公网 IP |
结合这些输出与第 1.2 节的端口表,你可以直接拼出各服务的访问地址,例如用api_server_instance_public_dns:12345访问 Web UI,或用zookeeper_server_instance_private_ip:2181配置外部客户端。
八、常用运维场景与注意事项
8.1 三种典型部署形态的变量组合
| 形态 | ds_component_replicas设置 | 说明 |
|---|---|---|
| 分布式集群 | master=1, worker=1, alert=1, api=1, standalone_server=0 | 默认形态,四组件各一台 EC2 |
| Standalone 单机 | master=0, worker=0, alert=0, api=0, standalone_server=1 | 一体化实例,端口 12345 |
| 混合/扩容 | 任意调整各副本数 | 横向扩容 Worker 只需调大worker副本数后重新 apply |
8.2 关键注意事项
- 镜像名一致性:
ds_ami_name在 Packer 与 Terraform 两个阶段必须一致,否则apply会因找不到 AMI 失败; - ZooKeeper 生产警告:自动创建的单节点 ZooKeeper(Docker 容器)仅为演示用途,生产环境应通过
zookeeper_connect_string指向高可用的外部 ZooKeeper 集群; - 数据库凭据:
db_password为必填项,写入terraform.tfvars后注意文件权限与保密; - 安全组端口:12345、5678、1234、50052-50053、2181、5432 等端口规则已由仓库默认配置好,若自建安全组或修改 CIDR 需保持组件间连通性;
- SSH 登录:密钥对固定命名为
dolphinscheduler,私钥落盘为本地dolphinscheduler.pem(权限0700),可用ssh -i dolphinscheduler.pem ec2-user@<public_ip>登录排障; - 资源清理:仓库未提供 destroy 文档说明,但 Terraform 标准流程
terraform destroy -var-file=terraform.tfvars可回收全部资源(RDS 已设skip_final_snapshot,销毁不留快照)。
九、总结
本方案将 DolphinScheduler 的 AWS 部署沉淀为两层 IaC:Packer 层把发行包(官方版本或本地构建)固化为标准化 AMI,内置 Java 8(Corretto)与可执行脚本,实现镜像的“一次构建、处处复用”;Terraform 层以ds_component_replicas为总开关,一键生成网络、数据库、对象存储、注册中心与五类计算实例,并通过 cloud-init + systemd 在实例首次启动时自动完成建库(upgrade-schema.sh)、S3 资源存储配置与组件拉起。整条链路从零到可访问 Web UI 只需两个变量文件、四条命令,非常适合测试环境搭建、演示环境交付与集群容量演练。所有可运行脚本与模板均可在仓库的 deploy/terraform/aws 目录中找到,你可以按需阅读 packer 模板、cloud-init 模板 及各组件.tf文件,进一步定制自己的部署方案。
【免费下载链接】dolphinschedulerApache DolphinScheduler is the modern data orchestration platform. Agile to create high performance workflow with low-code项目地址: https://gitcode.com/gh_mirrors/do/dolphinscheduler
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考