36.6 将控制固化到平台
平台化不是把所有决定自动化,而是让安全默认、身份、证据、审批和复位在每次操作中 一致出现。自动化适合执行已解析的意图;当 target、authority 或 evidence 仍有歧义时, 平台应停下来,而不是更快执行。
36.6.1 配置模板、验证脚本与策略即代码
控制从机器可读合同开始
desired state
inventory / parameter / role / service / backup policy
precondition
exact identity / version / topology / authority / headroom
plan
rendered change / affected objects / lock and restart / traffic impact
gate
risk / approval / rollback / evidence completeness
execution
bounded target / idempotency / audit
postcondition
native state + platform state + business invariant模板只消除重复,不应隐藏高风险选择。默认填入:
- stable service/cluster naming 与 environment/data class;
- least-privilege role 与明确 HBA 来源;
- timeout、pool、backup、monitoring、安全和容量基线;
- version pin 与 extension compatibility;
- safeguard、exact target 和 destructive approval;
- owner、SLO/RPO/RTO 与验证 revision。
把业务密码、private key 或 raw token 从 inventory Git 中分离;模板引用受控 secret source,并验证存在性/权限,不输出值。
Pigsty inventory 是 desired state,不是全部事实
Pigsty 以声明式配置表达 node、cluster、instance、service、database、user 与参数, playbook 将其物化。推荐流程:
inventory PR
-> schema/policy lint
-> render and semantic diff
-> sandbox/canary
-> exact -l scope
-> staged rollout
-> SQL + Patroni/DCS + proxy/pool + monitoring verification--check --diff 可帮助预览部分 Ansible 变化,但不能模拟所有 handler、运行时决策、
数据库锁、外部 repository 或 failover。preview 是证据之一,不是执行结果。
删除、重建和 PITR 等流程必须额外读取当前 identity 与 authority。Pigsty 的
pg_safeguard 可阻止危险 PGSQL 删除路径,但不能替代 exact inventory、备份验证、
流量排空和审批。安全控制应多层、互相独立。
原生证据复核平台结论
| 平台声称 | 回到原生/组件证据 |
|---|---|
| primary/replica 正常 | Patroni/DCS role、PostgreSQL recovery/timeline/replication |
| service route 正确 | HAProxy backend + endpoint 实际连接 identity |
| pool 正常 | PgBouncer pool/client/server state + PostgreSQL sessions |
| backup 正常 | pgBackRest info/check + 隔离 restore/business manifest |
| 参数生效 | pg_settings source/pending_restart + process/runtime |
| 监控覆盖 | collector target、query result、rule test、notification |
平台 UI 的绿色状态不能成为唯一证据;否则平台控制面故障时,团队失去验证路径。
策略即代码也要可解释
规则输出:
decision: deny
policy_revision: ...
target_identity: ...
failed_predicates:
- required backup restore evidence expired
- production destructive approval absent
evidence_links: [...]
exception_path: ...不可解释的 deny 会诱使人绕过控制;不可审计的 allow 会隐藏风险。policy 变更本身需要 review、测试、版本和回退,并覆盖 allow/deny/unknown 三类 fixture。
36.6.2 备份、切换、容量和维护的周期演练
建 capability calendar
按风险与变更频率决定周期,而不是所有项目“一年一次”:
| 能力 | 建议触发 |
|---|---|
| backup check | 连续运行;失败立即路由 |
| isolated restore | 固定周期 + backup/repository/version 大变更 |
| planned switchover | 维护周期 + topology/Patroni 变更 |
| unplanned failover tabletop/drill | 固定周期 + DCS/fencing 变更 |
| capacity benchmark | workload/hardware/major config 变化 |
| vacuum/freeze review | 持续趋势 + 数据增长/事务模式变化 |
| integrity check | 风险分层周期 + storage/ICU/major version 变化 |
| security access review | 固定周期 + owner/role/network 变化 |
| migration/upgrade rehearsal | 每次 candidate revision |
周期只是上限;invalidation event 应提前触发。
调度演练而不调度事故
exercise:
capability: ...
environment: isolated
source_snapshot_or_fixture: ...
hidden_scenario_seed: ...
allowed_mutations: [...]
forbidden_targets: [...]
guards: [...]
expected_evidence: [...]
cleanup_and_preservation: ...
production_claims_forbidden: [...]故障注入限定 disposable clone 或明确无数据、无流量 sandbox。production chaos 需要 另一套组织授权,不能由“周期演练”四个字自动许可。
Pigsty 能承载的周期任务
- 通过监控栈持续观察 PostgreSQL、host、Patroni、PgBouncer、HAProxy、backup;
- 用 pgBackRest policy 与 exporter 观察 backup/archive,再在隔离目标实际 restore;
- 用 Patroni/Pigsty 服务模型演练计划切换和受控故障切换;
- 从 version-controlled inventory 重建 node/cluster,并验证 drift;
- 用 playbook tag/limit 管理作用域;
- 把 exporter query、alert rule、dashboard 与 runbook revision 共同发布。
具体 playbook、参数和输出会随 Pigsty 版本变化。运行前以已固定 release 的官方文档和 本地 source 为准;破坏性 playbook 不从书中复制到生产。
统一 evidence envelope
不同演练使用同一外壳:
contract + source hashes
environment identity
before / during / after
decision log
raw restricted evidence + redacted projection
business manifest
cleanup / retained artifacts
negative cases
review and production-claim boundary统一 envelope 让平台能跨演练统计:哪些 control 过期、哪些 action 没有 evidence、 哪些版本从未恢复、哪些团队只跑 happy path。
演练失败不是坏成绩
演练在不伤害生产的前提下暴露:
backup不可读
权限不足
runbook过期
candidate选错
业务不变量缺失
cleanup不完整
值班升级路径断裂这正是它的产出。禁止为了完成率修改 pass condition 或隐藏失败;修复后从同一合同 重新验证,并保留前次失败证据。
36.6.3 从单个补丁升级为默认护栏
从 incident-specific 修复抽象不变量
单点补丁:
给 pg-prod-7 的某个脚本加一行 if默认护栏:
任何 destructive workflow:
必须解析 environment + cluster + system identity
必须有 current backup/recovery evidence
必须声明 data/traffic/authority
必须有 exact scope、preview、rollback、approval
缺失或冲突 -> deny/stop抽象层次以共同机制为准,不是越通用越好。一个巨大“万能安全框架”若无法描述 PostgreSQL timeline、replication slot、PITR target 或 collation dependency,反而 会隐藏领域事实。
safer default 的五个性质
- 自动采用:新 service 默认获得,不靠记忆 opt-in;
- 显式例外:绕过需要 owner、理由、补偿控制和到期;
- 可观察:知道 guard 是否执行、何时失效;
- 可版本化:配置、policy、runbook、dashboard 共同 revision;
- 可验证/可退出:有反例、回退和 retirement path。
例如:
new PostgreSQL service
default backup/archive policy
default service endpoints and pool limits
default SLI + PostgreSQL/host dashboards
default safeguard and least privilege
default restore/failover exercise registration业务仍要填 owner、data class、RPO/RTO、good event 与不变量;模板不能替它猜。
推广前做 blast-radius 管理
平台默认变更影响面大,按:
fixture -> sandbox -> one canary service -> cohort -> default for new
-> migrate existing -> retire exception每阶段比较 compatibility、false positive/negative、延迟与资源成本、operator burden 和 rollback。guard 误拒绝所有紧急恢复也会制造可用性风险;保留受控 break-glass,并 监控使用频率。
建 control registry
control_id: ...
objective: ...
implementation_revision: ...
default_scope: ...
exceptions: [...]
telemetry: ...
owner_role: ...
last_verified:
at: ...
environment: ...
evidence: ...
valid_until: ...
related_incidents: [...]
replacement: ...跨 postmortem 查询重复 theme,而不是逐篇人工回忆。平台 backlog 优先合并能覆盖多个 incident/service 的控制,仍保留每个 incident 的特有 action。
平台完成的定义
一个控制成为默认护栏后,仍要证明:
new service receives it
existing intended scope converged
exception inventory complete
runtime telemetry healthy
negative fixture is blocked
positive fixture is not blocked
break-glass is audited and expires
revalidation is scheduled“已经写进 Pigsty 模板”只完成第一步。最终效果必须在 PostgreSQL、组件、用户路径和 业务不变量上共同可见。
上一节:回写 SLO、SOP 与架构 ADR · 返回本章目录 · 下一节:实战:复盘四类事故并完成全书结业 · 查看全书目录 · 查看索引中心