一、用途 本技能用于构建、打包并部署编译后的 Airflow Go SDK 捆绑包(bundle),使 ExecutableCoordinator 能够运行它们。一次 Go SDK 部署只有一个产物:一个捆绑包,即一个自包含的原生可执行文件,内部同时携带嵌入的源码和一份清单,采用 AFBNDL01 格式,其原则是"可执行文件即捆绑包"。你用 go 构建并打包它,把它放到 Airflow 的 ExecutableCoordinator 扫描的位置,Python 任务运行器会为每个任务实例 fork 它一次。该技能平台中立:先展示构建过程,再展示协调器接线,最后说明如何把捆绑包送到 worker 上。
注意:实验性。Go SDK 正在活跃开发中,尚未达到生产可用状态。所有内容都基于单一模块 github.com/apache/airflow/go-sdk(Go 1.24+)解析。
操作顺序:编写任务(authoring-go-sdk-tasks)→ 构建并打包捆绑包(本技能)→ 将其放到 executables_root 下并配置协调器 → 部署匹配的 Python stub DAG。
二、构建并打包捆绑包 协调器只识别已打包的捆绑包:它扫描 AFBNDL01 trailer,并静默跳过任何缺少该标记的文件,因此单纯的 go build 二进制文件本身不可部署。使用打包器,它以 Go 1.24 工具指令的形式随 go.mod 提供(无需全局安装,版本按项目固定):
go tool airflow-go-pack ./example/bundle # 一步构建 + 打包
go tool airflow-go-pack --goos linux --goarch amd64 ./example/bundle -- -trimpath # 交叉编译;-- 之后的标志会传给 go build
go tool airflow-go-pack --executable ./bin/sample-dag-bundle --source main.go --airflow-metadata <airflow-metadata.yaml> # 打包已有二进制
go tool airflow-go-pack inspect ./bin/sample-dag-bundle # 检查已打包的捆绑包
打包器会构建二进制文件,以 --airflow-metadata 执行它以从 RegisterDags 捕获清单,然后追加源码 + 清单 + 一个 64 字节 trailer。结果是一个可运行文件。
针对 worker 的 OS/arch 构建:捆绑包是原生可执行文件,不可移植;需用 --goos/--goarch 交叉编译。不匹配的二进制文件会在 worker 上以 exec format error 失败。
二进制文件任何变更后都要重新打包:重新 strip、重新签名或换入调试构建会使 trailer 的 binary_sha256 失效,捆绑包随后会被拒绝。
三、接线协调器 Python 的 ExecutableCoordinator 会扫描 executables_root,将传入的 dag_id 与每个捆绑包的内嵌清单匹配,校验其完整哈希,然后 fork 捆绑包。宿主机上不运行任何 Go 进程。
将打包后的可执行文件放到被扫描的目录下:
cp ./bundle /opt/airflow/executable-bundles/ # 通过 AFBNDL01 trailer 识别,而非文件名
注册 ExecutableCoordinator 并将队列路由到它(参见 configuring-airflow-language-sdks):
[sdk] coordinators = {"go": {"classpath": "airflow.sdk.coordinators.executable.ExecutableCoordinator", "kwargs": {"executables_root": ["/opt/airflow/executable-bundles"]}}} queue_to_coordinator = {"golang": "go"}
部署匹配的 Python stub DAG;其 queue= 必须等于 queue_to_coordinator 的键(此处为 golang),其 dag_id/task_ids 必须与捆绑包注册的内容匹配。
四、部署路径 该 SDK 可运行在任何带 Task SDK 的 Airflow 上;不要求使用 Astronomer 工具链。
Docker / Kubernetes:针对镜像的平台交叉编译捆绑包并烘焙进去。镜像中不需要 Go 运行时或 worker 进程;Python 任务运行器会 fork 捆绑包。
FROM apache/airflow:3.3.0 # 语言 SDK 面向 Airflow 3.3+ COPY ./executable-bundles/ /opt/airflow/executable-bundles/
将 AIRFLOW__SDK__COORDINATORS 和 AIRFLOW__SDK__QUEUE_TO_COORDINATOR 设为环境变量
在 Helm chart 上,像上面那样将捆绑包烘焙进自定义镜像,或通过共享卷挂载它,并通过 worker/scheduler 上的环境变量设置 [sdk] 配置。更广泛的 Docker Compose 和 Helm 工作流参见 deploying-airflow。
上面的 apache/airflow:3.3.0 标签是示例性的:语言 SDK 需要 Airflow 3.3 或更新版本。请固定你实际运行的当前 3.x 版本,而不要凭记忆复制此标签;请阅读基础镜像的当前标签或文档。
Astro(一种选项,非必需):构建/打包捆绑包,然后在项目中暂存:mkdir -p include/executable-bundles && cp ../go-bundle/<packed-bundle> include/executable-bundles/.。在项目 Dockerfile 中,将捆绑包复制到协调器的目录:COPY include/executable-bundles/ /opt/airflow/executable-bundles/。将协调器配置放入项目 .env(会自动加载):AIRFLOW__SDK__* JSON 值(参见 configuring-airflow-language-sdks)。运行 astro dev start(变更后运行 astro dev restart);使用 astro deploy 部署。不要凭记忆固定 Astro Runtime / Airflow 版本;请阅读生成的 Dockerfile 或当前文档。当 Go SDK 处于预览阶段时,可能需要 beta/dev 镜像。
五、版本管理与预览安装 go-sdk/ 是单个 Go 模块,因此其发布标签采用 monorepo 子目录形式 go-sdk/vX.Y.Z(不要创建按 cmd 区分的标签)。你的捆绑包模块依赖 github.com/apache/airflow/go-sdk;固定该版本也就固定了 airflow-go-pack,它是同一模块中通过 tool 指令引用的包。针对发布标签固定:
go get github.com/apache/airflow/go-sdk@v1.0.0
若要针对未发布的提交或分支构建(例如提前试用下一个标签之前的修复),直接依赖它,Go 会生成伪版本:
go get github.com/apache/airflow/go-sdk@<commit-or-branch>
六、部署清单
- 捆绑包已构建并打包(go tool airflow-go-pack);注册的 dag_id/task_id 与 Python stub 匹配。
- 已针对 worker 的 OS/arch 构建(例如 --goos linux --goarch amd64)。
- 已打包的 AFBNDL01 捆绑包放在 executables_root 下的某个目录中。
- 已配置 ExecutableCoordinator + queue_to_coordinator(configuring-airflow-language-sdks)。
- 已部署 Python stub DAG,其 queue= 路由到 Go 协调器。
- 在任何重新构建/strip/sign 之后已重新打包(保持 binary_sha256)。
七、相关技能 authoring-go-sdk-tasks:编写 Go 任务代码及匹配的 Python stub。 configuring-airflow-language-sdks:注册 ExecutableCoordinator 并路由队列。 deploying-airflow:通用 Airflow 部署(Astro、Docker Compose、Kubernetes)。 setting-up-astro-project:初始化并配置 Astro 项目。
八、限制 Go SDK 处于实验/活跃开发阶段,尚未达到生产可用状态。捆绑包是原生可执行文件,不可移植,必须按 worker 的 OS/arch 构建。协调器只识别带有 AFBNDL01 trailer 的已打包捆绑包。二进制文件任何变更后需重新打包。语言 SDK 需要 Airflow 3.3 或更新版本;预览期间可能需要 beta/dev 镜像。