- 云原生
- DevOps
- 运维
【免费下载链接】devtron
The only Kubernetes dashboard you need
本文以 Devtron 官方文档 GoLang-migrate 插件指南 为主体,完整覆盖该预设插件(GoLang-migrate)的适用前提、在流水线中的配置步骤、全部输入变量说明与注意事项,并结合 Devtron 仓库中注册该插件的数据库迁移脚本(scripts/sql/259_migration_plugin.up.sql)、插件框架源码(pkg/plugin/repository/GlobalPluginRepository.go)以及 Devtron 自身使用同一套变量模型执行数据库迁移的 Job 清单(manifests/yamls/migrator.yaml),深入解析插件内置脚本的真实执行逻辑、支持的数据类型连接串格式,以及输出变量如何在任务链中传递。读完后,你可以把基于 golang-migrate 格式 SQL 脚本的数据库版本升级,安全地编排进 Devtron 的 Pre/Post-Build 或 Deploy 阶段。
一、插件定位与适用前提
GoLang-migrate 是 Devtron 内置的一个PRESET(预设)插件,其官方描述为:“This plugin provides a seamless way to manage and execute database migrations, ensuring your database schema evolves safely and predictably with your application code.” 插件的核心行为来自 golang-migrate 工具:Migrate 从源文件中读取迁移脚本(migrations),并以正确的顺序将其应用到数据库。
使用前提(原文档明确要求):
- 你的仓库中必须已有符合 golang-migrate 工具格式的 SQL 文件(即带版本号前缀的 up/down 迁移文件,存放在 Git 仓库某个目录下);
- 插件支持的目标数据库类型为
postgres、mongodb、mongodb+srv、mysql、sqlserver,其余类型需要通过POST_COMMAND自行拼接命令(见后文“注意事项”)。
从仓库源码看,该插件是在数据库迁移脚本 scripts/sql/259_migration_plugin.up.sql 中注册进系统的:
- 向
plugin_metadata表插入名为GoLang-migrate的记录,type字段为PRESET; - 向
plugin_stage_mapping表写入该插件的阶段映射,决定它能在哪些流水线阶段被选用(插件阶段类型常量定义见 GlobalPluginRepository.go 中的CI = 1、CD = 2、CI_CD = 3、SCANNER = 4); - 向
plugin_pipeline_script表写入一段SHELL类型的内置脚本——这就是插件真正执行迁移的逻辑载体(第三节详解); - 向
plugin_step_variable表批量插入DB_TYPE、DB_HOST等全部输入/输出变量定义。插件类型(SHARED/PRESET)的合法性校验位于 pkg/plugin/bean/bean.go 的validate:"oneof=SHARED PRESET"约束中。对应的回滚脚本 scripts/sql/259_migration_plugin.down.sql 会按相同规则清理这些记录。插件在界面中的图标由迁移脚本 scripts/sql/30602400_plugin_icons_update.up.sql 更新,对应仓库内的 assets/plugin-icons/ic-plugin-golang-migrate.png。
关于 Devtron CI 流水线中 Pre-Build / Post-Build 阶段与预设插件的整体机制,可参阅 预构建与后构建阶段指南;该插件在预设插件总览中的入口见 Preset Plugins 列表。
二、在流水线中添加 GoLang-migrate 任务
原文档给出的操作流程如下,可完整复现:
- 进入Edit build pipeline(编辑构建流水线)页面,选择Pre-Build Stage(或 Post-Build Stage);
- 点击+ Add task;
- 在PRESET PLUGINS中选择GoLang-migrate。
随后完成以下字段配置:
- 在
Task name字段输入相关名称(必填); - 在
Description字段输入任务的描述信息(可选); - 为输入变量提供取值。注意:变量的值可以来自前一个构建阶段的输出变量、全局变量,或自定义值;
- 配置
Trigger/Skip Condition(触发/跳过条件):这是一个决定任务执行或跳过的条件语句,可选择Set trigger conditions(满足条件才执行)或Set skip conditions(满足条件则跳过); - 点击Update Pipeline保存。
三、输入变量完整参考
原文档给出的变量表如下,本文在此基础上结合注册脚本 scripts/sql/259_migration_plugin.up.sql 中plugin_step_variable的定义,补充了默认值、是否允许为空等实操信息:
| 变量 | 类型 | 说明 |
|---|---|---|
| DB_TYPE | String | 当前插件支持 postgres、mongodb、mongodb+srv、mysql、sqlserver。 |
| DB_HOST | String | 数据库服务器的主机名、服务端点或 IP 地址。 |
| DB_PORT | String | 数据库服务器监听端口号。 |
| DB_NAME | String | 要连接的目标数据库实例名称。 |
| DB_USER | String | 连接数据库所需用户名。 |
| DB_PASSWORD | String | 连接数据库所需密码。 |
| SCRIPT_LOCATION | String | 需要在目标数据库上执行的 SQL 文件位置(仓库内相对路径,允许为空,见下文)。 |
| MIGRATE_IMAGE | String | golang-migrate 的 Docker 镜像,默认值:migrate/migrate(允许为空时回落到默认值)。 |
| MIGRATE_TO_VERSION | String | 迁移到哪个版本的 SQL 脚本(默认值:0,表示执行目录内所有文件)。 |
| PARAM | String | 随数据库查询一起执行的额外连接参数(允许为空),通常以键值对形式给出,例如sslmode=disable。 |
| POST_COMMAND | String | 脚本末尾执行的后置命令(允许为空)。 |
此外,注册脚本中还定义了一个输出变量POST_MIGRATION_VERION(variable_type为OUTPUT),描述为 “migration version after running the SQL files”(执行 SQL 文件后的迁移版本),它会被导出为后续任务可用的环境变量(细节见下节)。
其中DB_HOST、DB_NAME、DB_USER、DB_PASSWORD、MIGRATE_TO_VERSION在注册脚本中allow_empty_value为f(不允许为空)或带有默认值,SCRIPT_LOCATION、MIGRATE_IMAGE、PARAM、POST_COMMAND允许为空。
四、内置脚本执行原理:源码级解析
插件注册时写入的 SHELL 脚本(即 scripts/sql/259_migration_plugin.up.sql 中plugin_pipeline_script的$$...$$内容)完整揭示了变量是如何被消费的,其执行逻辑可以归纳为以下五步:
前置校验与上下文打印:脚本开启
set -e与set -o pipefail;若DB_HOST或DB_NAME为空则打印 “Please enter DB_HOST / DB_NAME” 并以非零码退出;同时通过git rev-parse打印当前分支与提交,用于审计这次迁移对应的代码版本。若SCRIPT_LOCATION为空,则回落到当前目录.并打印 “we are running migration on current location”。构造连接串:仅当
DB_USER非空时拼接DB_CRED="$DB_USER:$DB_PASSWORD@"。随后按DB_TYPE分支构造不同数据库的 DSN:postgres→postgres://$DB_CRED$DB_HOST:$DB_PORT/$DB_NAME?"$PARAM"mongodb/mongodb+srv→ 对应mongodb:///mongodb+srv://前缀,同样携带DB_HOST、DB_PORT、DB_NAME与PARAM;mysql→mysql://$DB_CRED$DB/$DB_NAME?"$PARAM",其中DB被显式定义为tcp($DB_HOST:$DB_PORT)(mysql DSN 的 tcp 地址格式);sqlserver→sqlserver://$DB_CRED$DB_HOST:$DB_PORT?"$PARAM"(该格式不带库名路径)。
选择迁移目标版本:若
MIGRATE_TO_VERSION等于0,执行up(应用全部迁移);否则执行goto $MIGRATE_TO_VERSION(迁移到指定版本)。对应的docker run命令形如:docker run -v $PWD:$PWD $MIGRATE_IMAGE \ -path $PWD/$SCRIPT_LOCATION \ -database <按DB_TYPE拼接的连接串> up即把当前工作目录挂载进容器(
-v $PWD:$PWD),并指向仓库内的 SQL 脚本目录-path $PWD/$SCRIPT_LOCATION——这就是为什么迁移文件必须放在 CI 检出的 Git 仓库里,由SCRIPT_LOCATION指定。执行后置命令并导出结果版本:所有分支执行完迁移后都会运行
$POST_COMMAND,然后通过再次调用migrate version子命令把当前数据库版本写入migration-golang-current-version.txt,并导出POST_MIGRATION_VERION环境变量(为空时回落到"0"),最后打印 “migration completed”。这一输出变量即可被流水线中下一个任务作为输入变量引用,用于把“迁移后的数据库版本”传递给后续步骤(例如部署阶段做校验)。兜底分支:若
DB_TYPE不在五种支持类型内,仅打印 “no database matched”——此时应按原文档 Notes 的建议改用POST_COMMAND手动执行(见第五节)。
五、注意事项与安全建议(原文档 Notes 全量继承)
原文档 Notes 部分给出三条重要建议,均与源码行为相互印证:
数据库在 Devtron 集群内不可达时:在
pre-deploy或post-deploy阶段使用in-cluster/ Execute tasks in application environment(在应用环境中执行任务)特性。因为 Pre/Post-Build 阶段的插件任务默认在 CI 构建环境中运行,若目标数据库位于业务应用所在的集群、且从 Devtron 集群网络不可访问,就应改用部署阶段的应用环境执行迁移。DB_TYPE不受支持时:内置脚本会落入 “no database matched” 分支而不做任何迁移,此时应通过POST_COMMAND手动运行 golang-migrate 命令,原文档给出的模板为:POST_COMMAND: docker run -v $PWD:$PWD $MIGRATE_IMAGE -path $PWD/$SCRIPT_LOCATION -database <myDB-connection-string>" goto $MIGRATE_TO_VERSION;即把
<myDB-connection-string>替换为你自己的完整 DSN,其余变量语义与内置分支保持一致。密码安全:建议配合
scope-variable(范围变量)特性管理DB_PASSWORD,避免明文密码直接写死在流水线变量中。
六、同一套变量模型的实证:Devtron 自身的迁移 Job
除了作为插件存在,golang-migrate 也是 Devtron 自身数据库升级的基础。仓库中 manifests/yamls/migrator.yaml(以及集成测试镜像的 tests/integrationTesting/migrator.yaml)定义了一系列postgresql-migrate-*Job,其容器环境采用了与插件几乎一致的变量模型:DB_TYPE=postgres、DB_HOST、DB_PORT、DB_NAME、MIGRATE_TO_VERSION=0、SCRIPT_LOCATION=scripts/sql/,再通过envFrom.secretRef注入密码。可以推断,插件设计的这套环境变量抽象,与 Devtron 内部升级工具链(quay.io/devtron/migrator镜像)是同一思路:统一用DB_*变量描述目标库,用SCRIPT_LOCATION指向仓库内 golang-migrate 格式的 SQL 目录,用MIGRATE_TO_VERSION=0表示“跑到最新”。仓库内的 scripts/sql/ 目录(700+ 个.sql文件)就是这些 Job 迁移的实际脚本来源。
一个值得注意的格式约束来自迁移脚本 scripts/sql/36304600_add_ci_artifact_query_indexes.up.sql 的注释:“CREATE INDEX CONCURRENTLY cannot run inside a transaction (golang-migrate wraps each migration in a transaction).” 这说明golang-migrate 会把每个迁移文件包裹在一个事务中执行,因此编写迁移 SQL 时不能使用必须在事务外执行的语句(如CREATE INDEX CONCURRENTLY),该脚本改用幂等的CREATE INDEX IF NOT EXISTS规避了此限制。这一点对你在 CI 中使用本插件编写迁移文件同样适用。
七、小结
- GoLang-migrate 是 Devtron 的 PRESET 插件,把 golang-migrate 的“按序应用 SQL 迁移文件”能力封装为流水线任务,支持 postgres、mongodb、mongodb+srv、mysql、sqlserver 五种
DB_TYPE; - 配置路径为:Edit build pipeline → Pre/Post-Build Stage(或部署阶段)→ + Add task → PRESET PLUGINS → GoLang-migrate,随后填写
DB_*、SCRIPT_LOCATION、MIGRATE_IMAGE(默认migrate/migrate)、MIGRATE_TO_VERSION(默认0全量)、PARAM、POST_COMMAND,并设置 Trigger/Skip Condition; - 源码层面,插件通过 scripts/sql/259_migration_plugin.up.sql 注册,其内置 SHELL 脚本负责校验必填变量、按
DB_TYPE拼接 DSN、以up/goto执行迁移、执行POST_COMMAND并导出POST_MIGRATION_VERION供下游任务消费; - 若数据库网络不可达请在部署阶段使用 in-cluster 执行;若
DB_TYPE不受支持请用POST_COMMAND手动拼接命令;DB_PASSWORD建议使用 scope-variable 管理。
- 云原生
- DevOps
- 运维
【免费下载链接】devtron
The only Kubernetes dashboard you need
相关推荐
.NET Core 多平台安装全攻略:Windows、Linux、macOS 一次装明白
.NET Core 多平台安装全攻略:Windows、Linux、macOS 一次装明白 想在 Windows、Linux 或 macOS 上搭好开发环境,又不
文档Doctrine Migrations测试策略:如何在CI/CD流水线中安全运行数据库迁移
Doctrine Migrations测试策略:如何在CI/CD流水线中安全运行数据库迁移 在现代软件开发中,数据库迁移是确保应用平稳升级的关键环节。Doctr
数据库开发工具如何用PandasAI实现零代码数据分析:5分钟完成智能数据探索
如何用PandasAI实现零代码数据分析:5分钟完成智能数据探索 还在为复杂的Python代码和SQL查询而烦恼吗?PandasAI让你能用自然语言对话的方式完
人工智能大模型RAG数据分析数据可视化
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考