14.3 配置管理与漂移检测

一句话

配置管理的目标不是 “有个地方存配置”,而是 “声明的配置 = 实际运行的配置”;两者一旦分叉就是漂移——漂移不会自己消失,只会在下次发布时把线上改回旧值,或把手工修复悄悄抹掉。

配置的三种形态

形态 例子 风险
代码内配置 常量、feature flag 默认值 改配置要发版
配置中心 etcd/Nacos/Apollo 需权限与审计,否则谁都能改
环境变量/挂载文件 K8s ConfigMap/Secret 与代码版本不同步,易漂移

原则:配置要版本化、可审计、可回滚;密钥不进配置(见 13.4 密钥与凭证管理)。

实测:漂移检测的最小实现

对 “期望配置” 与 “实际配置” 做规范化后比对(哈希/逐字段):

检查 结果
期望哈希 vs 实际哈希 不一致 → 漂移
差异字段 如 replicas: 3 → 5、image: v1.2 → v1.3
漂移数量 本次 2 个字段,其中 1 个是 “手工扩容”
# 声明式对比:期望(Git)vs 实际(集群)
kubectl diff -f deploy/            # 直接给出将发生的变更(含漂移)
# 只看漂移(不含本次要发布的变更):先 apply --dry-run,再 diff
terraform plan -detailed-exitcode  # 0=无变化 1=有错误 2=有差异

判据:plan/diff 长期不为空 = 有漂移,必须查明来源(手工改?其他工具?云厂商默认值?)。

漂移的三种来源与对策

来源 例子 对策
手工改控制台 紧急扩容、改安全组 变更回写 IaC;或明确 “临时变更需登记 + 到期回收”
其他工具/脚本 运维脚本改了配置 收敛到单一入口(IaC 或配置中心)
云侧默认值/自动行为 托管服务自动升级、默认参数 显式声明,不依赖默认值

反模式

反模式 后果
配置只存在控制台 无法版本化、无法回滚、无法审计
漂移不告警 下次 apply 把手工修复抹掉
配置与代码分开发布 版本不匹配,出现 “只有旧代码能跑”
密钥写进 ConfigMap 明文泄露(见 13.4 密钥与凭证管理)
不记录 “谁改了什么” 出事无法追责/回滚
环境间复制配置文件 一处改动扩散到所有环境

三条铁律

🔑 配置必须有唯一来源(Git 或配置中心),不能 “两处都能改”。

🔑 漂移即告警;plan/diff 长期不为空就是问题。

🔑 密钥与配置分离,配置可公开评审,密钥不可。

自检

Q1 为什么 “手工改控制台” 会造成漂移事故?

▸ 答案:因为 IaC 的 “期望状态” 没变:下次 apply 会把手改改回去。如果手改是应急修复,就会被静默抹掉,表现为 “修好的问题又回来了”。正确流程是 “改代码 → 再 apply”,临时变更要登记并限期回收。

Q2 terraform plan -detailed-exitcode 的退出码怎么用?

▸ 答案:0 表示无变化、1 表示出错、2 表示有差异。CI 里可以 “定期跑 plan,退出码为 2 就告警”,从而把 漂移检测自动化;发布流水线里则用它确认 “本次变更与预期一致”。

Q3 配置中心与 IaC 的分工是什么?

▸ 答案:IaC 管 “基础设施与部署形态”(网络、副本数、资源规格),配置中心管 “运行期可变参数”(开关、阈值、名单)。两者都要版本化与审计,但变更频率与审批级别不同;不要用配置中心去改 “本该 IaC 管” 的东西。

Q4 为什么 “配置与代码分开发布” 容易出事?

▸ 答案:因为会出现版本不匹配:新配置配旧代码(字段不认)、旧配置配新代码(缺默认值)。解法是 “配置随制品版本化”(同一 commit 生成配置与镜像),或让代码对缺失配置有安全默认。

Q5 漂移检测会不会产生大量噪音?

▸ 答案:会,如果没做规范化:云厂商默认值、自动生成的字段、时间戳都会造成 “假漂移”。先把 “可忽略字段” 排除(如 status、creationTimestamp),再比对;否则团队会很快忽略告警。

Q6 多环境配置怎么避免 “复制粘贴”?

▸ 答案:用同一份模板 + 环境 values(如 Helm values / Terraform tfvars),模板里不写死环境差异;差异只允许出现在 values 文件里,并进代码评审。复制整份配置会在某次改动后 “三套环境不一致”。

Q7 怎么证明 “配置管理真的有效”?

▸ 答案:三条:plan/diff 长期为空(无漂移)、任何一次线上变更都能追溯到 Git/配置中心的记录、回滚能在分钟级完成。三者都成立,才算 “配置被管理”,而不是 “配置有个地方存着”。

关联