本节摘要:开发、测试、预发、生产环境应结构一致、配置分离。本节实践 12-Factor 配置外置、Helm values 多环境、Feature Flag 与 GitHub Environment 审批——合并原 3.4 部署策略选型与 3.5 发布审批要点。
阅读完本节,你应当能够:
禁止把数据库密码打进 Docker 镜像。运行时注入:
# k8s deployment 片段 env: - name: DATABASE_URL valueFrom: secretKeyRef: { name: app-secrets, key: db-url } - name: LOG_LEVEL valueFrom: configMapKeyRef: { name: app-config, key: log-level }
同镜像在 dev 读 dev Secret,prod 读 prod Secret——构建一次。
chart/ values.yaml # 默认 values-staging.yaml # staging 覆盖 values-prod.yaml # prod 覆盖
helm upgrade myapp ./chart -f values.yaml -f values-prod.yaml \ --set image.tag=abc123
| 配置项 | dev | staging | prod |
|---|---|---|---|
| replicas | 1 | 2 | 10 |
| LOG_LEVEL | debug | info | warn |
| DB | sqlite | postgres-stg | postgres-prod |
| 策略 | 原理 | 停机 | 回滚 | 适用 |
|---|---|---|---|---|
| 滚动更新 | 逐 pod 替换 | 无 | rollout undo | K8s 默认 |
| 蓝绿 | 两套环境切流量 | 无 | 切回蓝 | 中流量 |
| 金丝雀 | 5%→100% 流量 | 无 | 缩 canary | 高风险 |
| A/B | 两版本比指标 | 无 | 关实验 | 产品实验 |
# K8s 滚动更新 spec: strategy: type: RollingUpdate rollingUpdate: { maxSurge: 1, maxUnavailable: 0 }
Production environment 设置:
main only每次 prod deploy 在 Actions 页留 audit trail:谁 approve、哪 commit、什么时间。
stage('Approve Prod') { input { message "Release ${env.GIT_COMMIT} to PROD?" submitter 'admin,release-managers' submitterParameter 'APPROVER' } steps { echo "Approved by ${env.APPROVER}" sh './deploy-prod.sh' } }
submitterParameter 写入 build 日志——SOX 合规审计。
LaunchDarkly/Unleash 控制功能开关,与部署解耦:
if flags.is_enabled("new-checkout", user_id=user.id): return new_checkout_flow() return legacy_checkout()
先部署代码(flag off),再灰度开 flag——比金丝雀更细粒度。
⚠️ 常见坑:staging 数据量只有 prod 1%——性能测试通过但 prod 慢 10 倍。staging 需按 prod 比例缩配或专门 perf 环境。
💡 关键直觉:环境一致性不是「机器配置一样」,而是拓扑与依赖版本一致——staging 跑 prod 同版 PostgreSQL、同版 Redis。
# inventory/staging/hosts # inventory/prod/hosts - hosts: app_servers vars_files: [vars/staging.yml] roles: [app]
IaC 与配置管理在第5章展开;CD 阶段只需知 playbook 参数化 即可多环境复用。
| 工具 | 强项 | 场景 |
|---|---|---|
| GitHub Actions | 与 Git 一体 | 开源/中小 |
| GitLab CI | 内置 Registry/K8s | 私有部署 |
| Jenkins | 插件生态 | 传统企业 |
| Argo CD | GitOps 同步 | K8s 声明式 |
固定节奏(如每两周周二 14:00 UTC)合并 release branch——非 CDP 团队的折中:batch 变更降低协调成本,但仍比「季度大版本」快。火车前 48h feature freeze,只收 bugfix。
传统 ITIL CAB 每周审变更单——与 CD 冲突。现代化做法:标准变更(pre-approved pipeline template)免 CAB;紧急变更 post-review;仅非标准基础设施变更走 CAB。
Octopus 用 variable templates 区分环境:
| Variable | Dev | Prod |
|---|---|---|
| ConnectionStrings:Main | dev-db | prod-db |
| FeatureFlags:Beta | true | false |
部署时 Octopus 按 environment scope 注入——与 Helm values 同构。
| 工具 | 部署模型 | 强项 |
|---|---|---|
| Spinnaker | 多云 pipeline | 金丝雀分析 |
| Octopus | 进程/Windows/IIS | 传统企业 |
| Argo CD | GitOps K8s | 声明式 sync |
| Flux | GitOps K8s | 轻量 |
选型看运行时:K8s 优先 Argo/Flux;VM + .NET 常见 Octopus;多云 K8s 复杂场景 Spinnaker。
定期 kubectl diff 或 Terraform plan——手工 kubectl edit 的 hotfix 若未回写 Git,下次 deploy 被覆盖或 drift 持续。GitOps 的 selfHeal 自动纠正 drift,但可能误删紧急 hotfix——需流程约定。
第4章进入持续部署:何时去掉 manual gate 全自动上生产。
配置管理的核心是把「差异」集中到一处:镜像里只有代码与依赖,环境差异全部通过 Secret、ConfigMap、values.yaml 注入。实现这一原则后,「构建一次、随处部署」才真正成立。配置本身也要纳入版本控制与评审——Helm values 与 Terraform 变量都属于 IaC,改动应走 PR 流程,prod 配置的变更应比其他环境更严格。
Feature Flag 是配置管理的延伸:它把「部署」与「发布」解耦,让新功能在代码已上线但未对用户开放的情况下运行。使用 flag 的团队要建立清理机制——flag 长期不清理会变成技术债,建议每次迭代结束时审查 flag 生命周期。环境一致性方面,staging 的数据库、中间件版本应尽量对齐 prod,至少 major 版本一致,否则测试结果会失真。