3. 多环境模型设计
多环境模型是持续交付平台能否稳定运行的基础。它要回答三个问题:代码从哪来、在哪个环境验证、什么条件下允许进入下一环境。如果环境边界模糊,最常见的结果是“测试通过但上线失败”,或者开发人员直接改生产配置导致事故。本节围绕环境定义、隔离策略、配置差异和晋升规则四件事展开,并给出可直接参考的落地方式。
一、环境定义:每个环境承担不同的验证职责
环境不是简单的“多套机器”,而是按验证目标划分的责任区。典型四环境模型如下:
- 开发环境(dev):面向开发者自测,允许频繁部署、数据可重置,不要求高可用。用于验证功能是否可运行、单元与接口是否连通。
- 测试环境(test):面向集成测试与回归测试,要求版本相对稳定,数据接近真实但可脱敏。用于验证多服务协同、接口契约、业务流程是否正确。
- 预发环境(staging):面向发布前验收,配置、拓扑、依赖版本尽量与生产一致,只允许通过测试的候选版本进入。用于验证部署脚本、配置项、数据库变更和回滚路径。
- 生产环境(prod):面向真实用户,变更必须可审计、可回滚、可灰度。用于承载真实流量和真实数据。
四类环境的核心差异不在机器数量,而在“验证目标”和“变更容忍度”。开发环境可以随时重建,生产环境必须保证变更可控。因此,环境定义应写成可执行的约束,例如:dev 允许每日多次部署,test 每日构建一次,staging 只接受通过 test 的候选版本,prod 只接受通过 staging 验收并完成审批的版本。
二、环境隔离策略:从网络、数据、配置到权限
隔离不足会导致环境互相污染。建议从四个层面做隔离:
- 网络隔离:每个环境使用独立命名空间或独立 VPC/子网,环境间默认不互通。只有 CI/CD 流水线通过受控入口访问目标环境。
- 数据隔离:每个环境独立数据库实例或独立 schema,禁止跨环境直连。生产数据不得直接复制到测试环境,必须脱敏后使用。
- 配置隔离:配置按环境存放,代码中不写死环境相关值。推荐使用“基础配置 + 环境覆盖”的方式,例如 GitLab CI 中通过
environment和变量作用域区分。 - 权限隔离:开发人员对 dev/test 有部署权限,对 staging 只读或需审批,对 prod 无直接部署权限,只能通过流水线触发。
隔离的目标不是把环境变成孤岛,而是让变更只能沿既定路径流动。例如,staging 可以访问与生产同版本的依赖服务,但不能访问生产数据库;prod 的密钥只存在于 prod 的 CI/CD 变量中,其他环境不可见。
三、配置差异:用“同一制品 + 环境覆盖”管理
配置差异是多环境模型中最容易出错的部分。推荐原则是:一次构建,多环境部署。即同一个制品(如 jar、镜像、前端包)在 dev、test、staging、prod 中复用,差异只通过环境变量、配置中心或部署参数注入。
以 GitLab CI 为例,可以按环境定义变量作用域:
stages:
- build
- deploy
build:
stage: build
script:
- mvn package -DskipTests
artifacts:
paths:
- target/app.jar
.deploy_template: &deploy
stage: deploy
script:
- ./deploy.sh --env $ENV_NAME --jar target/app.jar
deploy_dev:
<<: *deploy
variables:
ENV_NAME: dev
DB_URL: jdbc:mysql://dev-db:3306/app
FEATURE_FLAG: "true"
environment:
name: dev
deploy_test:
<<: *deploy
variables:
ENV_NAME: test
DB_URL: jdbc:mysql://test-db:3306/app
FEATURE_FLAG: "false"
environment:
name: test
这里的关键是:制品相同,只有 DB_URL、FEATURE_FLAG 等环境变量不同。对于敏感配置,应使用 GitLab CI/CD Variables 的 protected 和 masked 选项,并限定作用环境。例如生产数据库密码只允许在 prod 环境使用,且只有 maintainer 可查看。
配置差异还应包括资源规格和副本数。例如 dev 使用 1 副本、512Mi 内存;test 使用 2 副本、1Gi 内存;staging 与 prod 使用 3 副本、2Gi 内存。这些差异应写入部署模板,而不是手工修改。
四、晋升规则:用质量门禁控制环境流动
晋升规则决定一个版本能否从 dev 进入 test、从 test 进入 staging、从 staging 进入 prod。建议把晋升条件写成流水线中的质量门禁,而不是靠人工记忆。
一个可参考的晋升规则如下:
| 晋升路径 | 触发条件 | 质量门禁 | 审批 |
|---|---|---|---|
| dev → test | 开发分支合并到 test 分支 | 单元测试通过、构建成功 | 无需审批 |
| test → staging | test 环境验证通过 | 集成测试通过、接口契约检查通过、无高危漏洞 | 测试负责人确认 |
| staging → prod | staging 验收通过 | 冒烟测试通过、数据库变更脚本演练通过、回滚脚本可用 | 发布负责人审批 |
晋升规则要可执行、可追溯。每次晋升都应记录:制品版本、提交 SHA、触发人、审批人、门禁结果。GitLab 中可以通过 environment 的部署记录和 when: manual 实现人工审批,通过 rules 控制哪些分支可以触发哪些环境。
五、多环境模型整体关系
下图展示四环境之间的制品流动、配置注入和晋升门禁关系。同一制品从 dev 构建后,依次经过 test、staging、prod,每个环境注入自己的配置,并在进入下一环境前经过质量门禁和审批。
图中可以看到,制品只构建一次,四个环境共享同一版本;每个环境通过变量注入自己的数据库地址、功能开关和资源规格;晋升路径上设置三道门禁,分别对应单元测试、集成测试与发布前验收。这样既保证了环境隔离,又避免了“每个环境重新构建”带来的版本漂移。
落地时建议先固定环境清单和负责人,再把配置差异收敛到变量和模板中,最后把晋升条件写成流水线规则。环境模型稳定后,后续的灰度发布、回滚和审计才有可靠的基础。