服务怎么部署(单机、Compose、Kubernetes)、运行镜像怎么选和加固、怎么发布和回退、怎么观测和告警、出了事故怎么处理,以及私有化和断网环境怎么交付、升级和恢复。
每种受支持的部署形态写清支持的操作系统和 CPU 架构、资源下限、依赖和高可用边界;单机部署(含 Compose)不得承诺跨机高可用
怎么检查:评审部署文档或交付清单,逐项核对上述栏目;检查对外材料里单机形态没有「高可用」「故障自动转移」字样
为什么、来源
为什么:Compose 只在一台主机上编排容器,机器坏了服务就停;承诺做不到的可用性,出事时就是事故加违约。
- 常见形态:单机(Compose 或 systemd 加本机包)、集群(Kubernetes)、托管(云厂商或客户已有平台)。
- 每种形态写清:谁负责操作系统、容器运行时、证书、备份、集群控制面;故障域有多大;升级和备份怎么做。
- 单机部署可以是正式生产,前提是业务能接受单机故障期间不可用和维护窗口。
只有需要跨主机故障转移、自动多节点伸缩或多团队工作负载隔离,并且有人能负责集群的升级和排障时,才引入 Kubernetes
怎么检查:引入 Kubernetes 的方案评审里回答四个问题:可用性目标、故障域、扩容方式、谁运维集群
为什么、来源
为什么:Kubernetes 带来网络、存储、准入、升级一整套运维负担;没有对应需求和人手,复杂度只会变成新的故障源。
- 没有「服务数到 N 就上 Kubernetes」的门槛,按真实的可用性目标、维护频率和人员能力判断。
- 客户已有 Kubernetes 或合同要求集群部署时,按客户环境走。
- Kubernetes 不会自动让数据库、对象存储高可用,有状态组件要单独设计(见 17)。
- 上游 Kubernetes 只维护最近三个小版本,每个约 14 个月补丁支持,没有长期支持版;自建集群要排好升级节奏。
云资源和集群配置用基础设施即代码(IaC)声明并入库;控制台上的手工改动不作为最终状态,定期检测漂移
怎么检查:定时跑 tofu plan / terraform plan 或 GitOps 控制器的差异检查,有差异就提工单
为什么、来源
为什么:只靠人手在控制台改,环境就无法重建,出了事也说不清改过什么。
生产部署的镜像引用写到不可变的摘要(@sha256:…),不用 latest 或可移动的标签
怎么检查:CI 扫描 Helm values、渲染后的清单和 Compose 文件,镜像引用不带摘要即失败;集群里可再加准入策略拦截
为什么、来源
为什么:标签可以被移到别的镜像上,摘要不会;用摘要才能确定跑的是哪个版本、能准确回退。
Dockerfile 里 FROM 的固定方式见 15(CFG-028)。
每个发布版本出一份制品清单(各架构镜像摘要、Chart 包、依赖和校验和),安装和升级前先校验
怎么检查:安装脚本第一步按清单校验每个文件的 SHA-256 和镜像摘要,不一致就停止
为什么、来源
为什么:离线拷贝和多次中转容易出现文件缺失或被替换,不校验就无法保证装的是发布的那一版。
同一 CPU 架构下,云上和私有化使用同一个镜像摘要;多架构用多架构清单(manifest list)发布同一版本,配置和外部依赖通过环境注入
怎么检查:对比各环境部署记录里的镜像摘要
为什么、来源
为什么:为私有化单独构建一份,测过的和交付的就不是同一个东西。
同一个镜像不代表有状态组件在两种环境下的可用性相同,可用性承诺要分别写(见 OPS-001)。
运行阶段的基础镜像优先选不含 shell 和包管理器的最小镜像(如 distroless、Docker Hardened Images);排障用 debug 变体或临时调试容器,不把调试工具打进生产镜像
怎么检查:评审时看最终阶段的 FROM;用镜像扫描结果对比包数量和漏洞数
为什么、来源
为什么:镜像里的东西越少,漏洞越少、被利用的工具越少,扫描结果也越好处理。
- Go、Rust 等静态二进制用 distroless 的 static 镜像;Java、Python、Node 用对应语言的 distroless 或加固镜像。
- distroless 的标签带 Debian 大版本后缀(如
-debian13),固定后缀,不依赖不带后缀的默认指向。
- 需要运行时装系统包的,用官方 slim 镜像,并在多阶段构建里把构建工具留在前面的阶段(见 15 CFG-032)。
容器以非 root 运行,禁止提权,去掉全部 Linux capabilities,seccomp 用运行时默认配置;不用 privileged、hostNetwork、hostPath,确需时写明原因和替代限制
怎么检查:Kubernetes 命名空间开启 Pod Security Admission 的 restricted 级别;Compose 文件用 CI 脚本检查 user、cap_drop、security_opt、privileged
为什么、来源
为什么:容器逃逸和横向移动多数靠 root、多余的 capabilities 和宿主机挂载;这些是 Kubernetes 官方 restricted 基线的要求。
- Kubernetes restricted 基线要求:
runAsNonRoot: true、allowPrivilegeEscalation: false、capabilities.drop: [ALL](只允许加回 NET_BIND_SERVICE)、seccomp 为 RuntimeDefault 或 Localhost。
- 只读根文件系统(
readOnlyRootFilesystem: true)不在官方基线里,但建议默认开启,需要写的目录用 emptyDir 或卷挂载。
- 镜像里的非 root 用户怎么设见 15(CFG-029)。
区分 liveness、readiness、startup 探针:liveness 只检查进程本身是否卡死,不检查数据库等下游;readiness 反映能否接流量;启动慢的服务配 startup 探针
怎么检查:评审探针实现;集成测试里停掉下游依赖,确认服务变为未就绪而不是被反复重启
为什么、来源
为什么:liveness 依赖下游时,数据库一抖,所有实例会同时被重启,小故障变成全面故障。
Compose 里依赖其他服务就绪的,给被依赖服务配 healthcheck,并用 depends_on 的 condition service_healthy;应用本身仍要能重试连接
怎么检查:CI 解析 Compose 文件,检查 depends_on 是否用了长格式和健康条件
为什么、来源
为什么:短格式的 depends_on 只保证启动顺序,不保证对方已经能用。
收到 SIGTERM 后先标记未就绪、停止接新请求和新任务,在设定的期限内处理完或交还在途工作,再退出;停机期限不超过平台的强制终止时间
怎么检查:集成测试在长请求、流式连接、队列任务进行中发送 SIGTERM,检查无请求被截断、任务被重新投递
为什么、来源
为什么:发布、缩容、节点维护都会发 SIGTERM;处理不好,每次发布都会丢请求或做一半的任务。
- Kubernetes 默认在 SIGTERM 后等待
terminationGracePeriodSeconds 再强制结束;Compose 用 stop_grace_period。
- 未处理完的任务靠幂等和重试接管,一致性要求见 16、17。
每个容器显式配置 CPU 和内存的请求与上限(或 Compose 的资源限制),数值来自压测或线上观测,不照抄示例
怎么检查:CI 用 kube-linter 或策略引擎检查清单里每个容器都有 requests 和 limits;评审时看数值依据
为什么、来源
为什么:不设上限会互相抢资源、触发 OOM;不设请求,按 CPU 利用率的自动伸缩就没有基准。
发布说明写清能从哪些版本直接升级、是否需要中转版本、不可逆的变更和回退限制
怎么检查:发布评审时核对发布说明里这四项都有
为什么、来源
为什么:私有化客户的版本参差不齐,不写升级路径和不可逆点,客户升级时就会踩坑,坏了也退不回去。
给用户看的变更日志写法见 05;发布流程见 03。
破坏性的数据结构或协议变更按「扩展 → 迁移 → 收缩」分步发布,收缩放在之后的版本;不把回滚镜像当作回滚数据
怎么检查:评审迁移计划时检查分步;CI 跑新旧版本混跑的兼容测试
为什么、来源
为什么:滚动发布期间新旧版本同时在跑;一步到位的破坏性变更会让旧实例出错,而且数据改了就回不去。
数据库迁移原则见 17,接口兼容见 16。数据已不可逆地转换时,只能靠备份恢复或向前修复。
线上发布分批进行;切换前记下关键指标基线,事先写好暂停和回退的条件,并确认回退步骤可用
怎么检查:发布记录里有基线、分批计划、暂停和回退条件;抽查回退是否演练过
为什么、来源
为什么:一次推到全部实例,问题会马上波及所有用户;不事先定条件,出问题时就会犹豫和争论。
- 分批单位可以是实例、流量比例、租户或功能开关。
- 判断条件用用户视角的指标(错误率、延迟、关键业务失败数、错误预算消耗),不只看「部署成功」。
功能开关通过 OpenFeature 这类标准接口读取;开关服务不可达时返回代码里的默认值继续运行,不阻塞启动和请求
怎么检查:集成测试里停掉开关服务,确认应用正常启动、按默认值运行
为什么、来源
为什么:OpenFeature 规范要求求值不抛异常、出错时返回默认值;远程开关服务挂掉或私有化断网时,不能拖垮业务。
每个功能开关登记负责人、用途、默认值和计划删除的时间或版本,到期清理
怎么检查:开关清单入库,CI 列出超期未删的开关
为什么、来源
为什么:不清理的开关会越积越多,组合越来越难测,旧分支代码也一直留着。
写明支持哪些版本同时在维护、是否允许跳版本升级,不无限期兼容历史版本
怎么检查:支持矩阵入库,发布评审时更新
参考值:参考起点:维护当前和上一个小版本(N 和 N-1);无统一标准,按客户合同和发布频率调整。
为什么、来源
为什么:不设边界,兼容代码和测试矩阵会越积越大。
应用日志写到标准输出或标准错误,由平台采集;不把日志只留在容器内的文件里
怎么检查:部署配置检查里没有把日志只写容器内路径的配置;启动后确认采集端能收到日志
为什么、来源
为什么:容器重建后容器内文件就没了,日志也就丢了;写标准输出是容器平台统一采集的前提。
日志格式和必备字段(时间、级别、服务、追踪编号等)见 02(COD-016、COD-017);运维侧再补充版本和环境两项资源信息。
链路追踪和指标用 OpenTelemetry API 与 OTLP 协议上报,经 Collector 转发;业务代码不直接调用某一家后端的专有 SDK
怎么检查:依赖扫描查找业务模块里的厂商专有遥测 SDK
为什么、来源
为什么:绑定一家的 SDK,换后端就得改业务代码;走标准接口和 Collector,后端可以按部署规模更换。
- 三类信号用同一套资源属性(至少
service.name、service.version、deployment.environment),以便互相关联。
- 跨服务调用传播 W3C Trace Context。
采用 OpenTelemetry 前查一下目标语言各信号的稳定级别;日志在该语言未稳定时,用语言自带的成熟日志库输出结构化日志,由 Collector 采集并带上追踪编号
怎么检查:方案评审时附上 OpenTelemetry 状态页的结论
为什么、来源
为什么:各语言 SDK 的成熟度不同,用了未稳定的信号,升级时接口可能变。
- 核实时(2026-11)的状态:链路追踪在多数语言已稳定;指标在 Go、Java、JavaScript、Python、.NET 等已稳定;日志只在少数语言(如 Java、.NET、C++)稳定,Go 为候选版,JavaScript、Python 仍在开发中。
- Profiles(性能剖析)还是 alpha,不要用在关键路径上。
- Collector 各组件稳定级别不一,以每个组件 README 为准。
可观测组件(Collector、日志采集、后端)故障或变慢时不得阻塞业务请求;Collector 配内存限制和批处理,宁可丢遥测也不拖垮业务
怎么检查:测试时停掉或限流可观测后端,确认业务请求的延迟和成功率不受影响
为什么、来源
为什么:为了看清系统而让系统变慢或停掉,是本末倒置;小型私有化环境尤其容易被遥测压垮。
Collector 的 memory_limiter、batch、采样和缓冲按部署规模配置,不照抄示例。
用户编号、请求编号、追踪编号、订单号这类取值无上限的字段,不做指标标签,也不做日志的索引标签
怎么检查:定期用 promtool tsdb analyze 或后端自带的基数统计找出序列数最多的标签;评审新增指标时检查标签
为什么、来源
为什么:每个不同的标签值都会产生一条新的时间序列或日志流,取值无上限时存储和查询都会失控。
这类字段放在日志内容或结构化元数据里,需要时按内容检索。
集中采集日志;按用途(排障、审计、合规)分别写明保留期和存储预算,定期对照实际用量复核
怎么检查:保留策略写进部署文档;每月或每季度看一次存储增长和费用
为什么、来源
为什么:不设保留期,小型私有化环境会先被日志写满磁盘;不分用途,审计日志可能被和排障日志一起删掉。
法定留存期限见 27;链路追踪默认采样,不全量保存。可观测数据的费用记入 22 的成本账本。
区分本地运维遥测和发往厂商的遥测:发往厂商的默认关闭、由客户显式开启;关闭外发不影响本地的健康检查、指标和审计
怎么检查:在断网或出口全拒绝的环境里运行,记录对外连接;检查默认配置里外发开关为关
为什么、来源
为什么:私有化客户普遍禁止数据外发,默认外发会违反合同和法规;把本地运维能力和外发绑在一起关,又会让客户自己无法排障。
关键服务按用户旅程定义 SLI(如下单成功率、关键接口延迟)和 SLO,写明统计窗口、排除范围和负责人
怎么检查:SLO 定义文件入库,CI 校验必填字段;每季度对照实际数据复核
参考值:常见示例为 30 天滚动窗口、成功率 99.9%;只是示例,目标按业务影响定。
为什么、来源
为什么:只看 CPU、内存说不清用户是否受影响;用户视角的目标才能决定什么时候该停下新功能先修稳定性。
SLO 是内部目标,不等于对外合同里的 SLA;流量很小的服务,不要用小样本百分比去呼人。
呼人告警基于用户影响(如错误预算的多窗口燃烧率),不按单机 CPU、内存阈值呼人;资源类告警发工单或通知
怎么检查:评审告警规则,列出级别为呼人的规则逐条看触发条件
为什么、来源
为什么:资源指标高不一定有用户受影响,按它呼人会制造大量无效告警,让值班的人麻木。
Google SRE Workbook 对 99.9% 目标给出的起步阈值:1 小时与 5 分钟两个窗口的燃烧率都超过 14.4 倍、或 6 小时与 30 分钟都超过 6 倍时呼人;更慢的消耗发工单。按自己的目标和流量调整。
每条呼人告警都带负责人、事故等级和运行手册链接;没有运行手册的告警不得设为呼人
怎么检查:CI 检查告警规则的 labels 和 annotations 里有 owner、severity、runbook_url,且链接可访问
为什么、来源
为什么:半夜被叫起来却不知道该做什么、该找谁,告警就只是噪声。
告警路由做分组、抑制和静默,值班有主备和升级链;每月统计告警数量、可处置比例和重复告警,删改无动作的告警
怎么检查:查看告警路由配置和月度告警复盘记录
为什么、来源
为什么:同一故障触发几十条告警会淹没真正的线索;不定期清理,告警只会越来越多。
事故按 SEV1–SEV4 定级;SEV1、SEV2 指定事故指挥,分开处置和对外沟通的人,并维护一份实时更新的事故记录(时间线、影响面、决定)
怎么检查:抽查 SEV1、SEV2 事故记录是否有指挥人、时间线、影响范围和关键决定
为什么、来源
为什么:没人统筹时,多个人同时改系统、没人对外同步,故障会被拖长甚至扩大。
- 等级含义见公共词表:SEV1 核心功能不可用或数据受损、影响大多数用户;SEV2 重要功能受损或部分用户不可用;SEV3 次要功能受损有绕过办法;SEV4 轻微、无明显用户影响。客户有自己的等级时写映射表。
- 事故期间只有处置的人改系统;记录要能多人同时编辑,事后用于复盘。
SEV1、SEV2 事故结束后做复盘:对事不对人,写清触发条件、系统性原因、为什么没有提前发现;行动项有负责人、期限和验证方式,并跟踪到关闭
怎么检查:复盘文档模板固定这些栏目;行动项关联工单,定期列出超期未关的
为什么、来源
为什么:追究个人只会让人隐瞒信息;行动项不落到人和期限,同样的事故会再来。
运行手册入库并版本化,写明适用的告警、前置检查、操作步骤、结果验证、停止条件和回退;每次事故或演练后更新
怎么检查:CI 检查运行手册包含这些小节;告警的 runbook_url 指向存在的文件
为什么、来源
为什么:事故时没人有精力现想步骤;没有停止条件,操作者可能在错误方向上越走越远。
备份作业纳入监控,失败或超时就告警;恢复演练按 17 定的频率在隔离环境执行,恢复后跑业务冒烟,记录实际恢复时间和数据损失
怎么检查:检查备份告警规则存在;查看最近一次演练记录的日期、步骤、冒烟结果和实测 RPO/RTO
为什么、来源
为什么:没人发现的备份失败和没验证过的备份,等到真要恢复时才暴露。
- 备份策略、恢复目标和演练频率只在 17 定(DB-033、DB-036),这里不另定频率。
- 系统级恢复除了数据库,还要覆盖配置、证书、对象存储和密钥恢复材料,并按依赖顺序恢复。
- 集群部署的演练还要覆盖整机丢失和持久卷丢失。
重要发布或预期流量增长前做容量测试,写清负载模型、p95/p99 延迟、瓶颈所在和剩余余量;用了自动伸缩的,用负载试验验证扩缩结果,不只检查配置存在
怎么检查:保留压测报告(含自动伸缩在稳态、突增、回落三个阶段的副本数和延迟),发布评审时引用
为什么、来源
为什么:不压测就只能凭感觉配资源,要么浪费,要么在高峰时被打垮;伸缩依赖指标采集和资源请求,配错了平时看不出来。
私有化离线版必须在完全断开公网出口的环境里验收安装、升级、回退和业务冒烟,并确认没有对外连接
怎么检查:在出口全拒绝的网络里跑安装和升级流水线,记录 DNS 查询和出站连接,非零即失败
为什么、来源
为什么:很多外联点藏在默认配置里(更新检查、使用统计、时间同步、插件下载),只在有网的环境测试发现不了。
GitLab 官方离线安装指南逐项列出了要处置的默认外联点,可作为检查清单的参考。
离线安装包自带全部所需内容:各架构镜像(OCI 归档或内网仓库同步包)、Chart 和依赖、迁移脚本、校验和、安装升级回退恢复手册、预检和冒烟脚本;安装和运行时不下载包外资源
怎么检查:扫描安装脚本和配置里的外部 URL;断网验收(见 OPS-035)
为什么、来源
为什么:少一个镜像或插件,现场就装不上,而断网环境里补发一次往往要几天。
镜像推到客户内网的镜像仓库后,部署配置只从内网仓库拉取。许可证和 NOTICE 文件随包交付(见 27)。
私有化安装前运行预检,检查 CPU、内存、磁盘、端口、DNS、时间同步、证书链、CPU 架构和容器运行时,不满足就给出明确原因并停止;支持导入客户私有 CA 和替换证书,证书到期前告警
怎么检查:预检脚本输出结构化报告,安装流程在预检失败时退出
为什么、来源
为什么:私有化的大部分安装工单来自环境不满足,提前查出来比装到一半失败好处理;企业内网普遍用自建 CA,证书过期是常见又完全可以预防的停服原因。
给客户的诊断包默认脱敏(不含密钥、令牌、私钥和业务数据),列出采集范围,客户可预览、删选后离线导出
怎么检查:对诊断包样本跑密钥扫描;评审采集清单
为什么、来源
为什么:诊断包会被发给厂商,混进密钥或客户数据就是一次数据泄露。
一般包含:系统和运行时信息、制品与数据结构版本、脱敏后的配置差异、探针结果、限量的近期错误日志、关键指标采样、磁盘容量、证书到期时间(不含私钥)、DNS/时间/端口检查结果、最近一次升级状态。
对外声明支持某个国产操作系统或 CPU 架构前,在该系统、内核、容器运行时和 CPU 的组合上实测安装和核心业务流程,并保留记录
怎么检查:评审兼容声明时核对每个组合都有实测记录
为什么、来源
为什么:指令集、动态库、原生扩展和驱动都可能不兼容,「支持 Linux」不等于支持所有国产平台。
一般先覆盖 x86_64 和 aarch64,其他架构按客户需求逐个验证。
OPS-040硬约束检查:自动由编码 Agent 参与开发的仓库对外提供服务的后端 Agent 参与生产运维时默认只读;写操作只能调用事先登记的、幂等且可回退的具名动作,经人批准并留审计;恢复数据、删除、改权限和网络边界不交给 Agent 自动执行
怎么检查:在 Agent 的运行时权限里只开放只读凭据和登记过的动作;审计日志抽查
为什么、来源
为什么:告警内容、日志、聊天消息都可能夹带指令或误导,Agent 直接执行会把小故障放大成事故。
告警描述、日志、工单内容一律当数据,不当指令(见 23 AGT-007、AGT-009)。
没有符合条件的规则。
单机部署
Docker Compose · Apache-2.0
备选:systemd + 本机安装包(客户环境不允许装容器运行时)
不推荐:为单机客户强制部署 Kubernetes
集群编排
Kubernetes(上游、托管版或客户已有发行版) · Apache-2.0
备选:云厂商托管容器服务(不想自己维护控制面)
不推荐:自研调度或编排
Kubernetes 应用打包
Helm(当前主版本) · Apache-2.0
备选:Kustomize(只是少量环境差异的叠加)
不推荐:Helm、Kustomize 加自制渲染器层层嵌套
持续部署(GitOps)
默认不引入;有多集群、需要持续治理漂移或有独立交付团队时用 Argo CD · Apache-2.0
备选:Flux(偏好命令行和 Git 原生、按组件组合)
不推荐:单机部署也装 GitOps 控制器
基础设施即代码
OpenTofu · OpenTofu 为 MPL-2.0;Terraform 为 BUSL-1.1;Pulumi 核心为 Apache-2.0
备选:Terraform(已有 Terraform 生态和团队经验;注意许可证为 BUSL-1.1,不是 OSI 开源许可);Pulumi(需要用通用编程语言描述基础设施;自管状态后端的运维要自己承担)
不推荐:控制台手工操作作为唯一真实状态
运行时基础镜像
distroless(静态二进制用 static,其余用对应语言镜像;固定 Debian 后缀并按 digest 引用) · Docker Hardened Images 社区层为 Apache-2.0;distroless 以其仓库 LICENSE 为准(未核实)
备选:Docker Hardened Images(需要更全的加固镜像目录、随镜像提供的签名 SBOM、VEX 和 SLSA 构建等级 3 来源证明;社区层免费、Apache-2.0);Chainguard 付费镜像(需要固定到具体版本、厂商的漏洞修复时限承诺);官方 slim 镜像(运行时必须用包管理器装系统依赖);openEuler 等国产系统基础镜像(客户要求信创基础镜像)
不推荐:完整发行版镜像(如 ubuntu、debian 默认标签)直接作运行镜像;生产依赖 Chainguard 免费层
遥测接口与转发
OpenTelemetry API/SDK + OTLP + OpenTelemetry Collector · Apache-2.0
备选:Prometheus 客户端库直接暴露指标(只有指标、单个服务、不需要链路)
不推荐:业务代码直接用某家后端的专有 SDK
指标存储与告警规则
Prometheus + Alertmanager · Apache-2.0
备选:VictoriaMetrics(需要更长保留期或更大基数,且做过容量评测;企业版功能另计);Grafana Alerting(已统一用 Grafana 管理告警)
不推荐:没评估容量就上分布式指标存储
仪表盘
Grafana · AGPL-3.0-only(部分目录有例外,以仓库 LICENSING.md 为准)
备选:一体化平台自带界面(SigNoz、OpenObserve)(已选用一体化方案)
不推荐:为几张图自建看板或告警系统
日志存储
小规模用本机轮转 + 集中收集;规模上来后用 Loki · Loki 为 AGPL-3.0-only,客户端等部分目录为 Apache-2.0
备选:OpenObserve(想要日志、指标、链路一体化且接受 AGPL)
不推荐:日志永久留在容器或本机磁盘;高基数字段做索引标签
链路追踪后端
已用 Grafana 时选 Tempo · AGPL-3.0-only
备选:SigNoz 或 OpenObserve(选了一体化方案)
不推荐:没有跨服务需求也必装追踪集群
一体化可观测平台
SigNoz · SigNoz 核心为 MIT,ee/ 目录另有商业条款;OpenObserve 社区版为 AGPL-3.0
备选:OpenObserve(更看重存储成本;社区版为 AGPL)
不推荐:只看演示就承诺大规模生产
错误追踪
GlitchTip · GlitchTip 为 MIT;Sentry 服务端为 FSL-1.1-Apache-2.0,SDK 许可不同
备选:Sentry 自托管版(需要更完整的功能,能承担较多的依赖服务)
不推荐:只为收集异常就部署整套 Sentry
功能开关
OpenFeature SDK + flagd(从本地文件或内网 HTTP/gRPC 读取开关) · Apache-2.0
备选:已有开关平台(组织已采购或自建;通过 OpenFeature 的提供者接入)
不推荐:私有化环境依赖远程 SaaS 开关服务;在代码里散落自制的 if 开关
灰度发布
入口按流量或实例分批 + 功能开关
备选:Argo Rollouts(Kubernetes 上需要按指标自动推进或回退);服务网格的流量拆分(已经在用服务网格)
不推荐:为灰度强制引入服务网格
事故与值班
事故记录模板 + 可检索的事故库 + 轮值表,告警经 Alertmanager 路由到组织现有的通知渠道
备选:企业已有的事件管理平台(组织已在用)
不推荐:只在群里吆喝、没有指挥人和记录;自研排班和告警静默引擎
✕ 错误做法:认为「生产就必须上 Kubernetes」
✓ 应该:按可用性目标、故障域和人手选部署形态(OPS-002)
✕ 错误做法:认为「Compose 不能用于任何生产」
✓ 应该:只承诺单机能做到的可用性,写清边界
✕ 错误做法:image: latest,安装时再从公网拉
✓ 应该:按摘要引用,离线包自带全部镜像并校验
✕ 错误做法:只在有网的云环境测试私有化安装包
✓ 应该:在出口全拒绝的环境验收,统计对外连接
✕ 错误做法:liveness 探针检查数据库连通性
✓ 应该:liveness 只看进程本身,下游问题让 readiness 失败
✕ 错误做法:把用户编号、追踪编号做成指标或日志索引标签
✓ 应该:标签保持低基数,这类字段放日志内容
✕ 错误做法:CPU 超过 80% 就呼人
✓ 应该:按用户 SLI 的燃烧率呼人,资源告警发工单
✕ 错误做法:用 docker compose down && up 旧版本当作数据回滚
✓ 应该:写清回退限制,数据变更按扩展、迁移、收缩分步
✕ 错误做法:新版本一上线就删旧字段
✓ 应该:收缩放到之后的版本,确认没有旧实例和旧客户端在用
✕ 错误做法:备份文件和数据放在同一块盘上,从没恢复过
✓ 应该:备份放到另一个故障域,按 17 的频率做恢复演练
✕ 错误做法:小规模部署同时铺好几套全栈可观测平台
✓ 应该:统一走 OpenTelemetry,后端按规模选一套
✕ 错误做法:Agent 直接执行告警里建议的命令
✓ 应该:只读排查,写操作走登记过的动作和人工审批
✕ 错误做法:「支持国产化」只是验证了 Docker 能启动
✓ 应该:在每个系统、内核、CPU 组合上跑核心业务流程