🏗️ 不用 Operator,也能做好 PaaS

面向企业内部上云的平台工程与云成本运营 · 新人入职教程

一个不以 Operator 为控制面、需同时纳管容器与虚机、并要求成本可分摊的企业级 PaaS 该怎么设计?这份教程按 5 模块 / 20 篇展开,每篇都是"真实场景 → 概念澄清 → 方案对比(含被否决的方案)→ 落地要点 → 什么情况下不该这么做 → 一句话结论"。这不是文档,是有观点、有取舍、有踩坑记录的技术随笔。

🧭 平台即产品 ⚙️ 外部控制面 🖥️ 容器 + 虚机统一纳管 💰 FinOps 成本分摊 🇨🇳 央企信创语境

📌 新人怎么用这份教程

· 只有半天:直接读三篇旗舰 第5篇(为何不用 CRD)第6篇(外部控制面一致性)第18篇(公摊分摊)——覆盖本项目最难、最有观点、最少人写清楚的部分。

· 入组第一周:带着附录 D 的三个问题去找导师对答案:应用模型的 schema 长什么样?控制面靠什么保证最终一致?公摊成本的分摊口径谁定的?

· 阅读约定:每篇的红色「戒律」行是精华——它逼你记住"什么时候该用某个技术",比记住"某技术多好"更值钱。

模块一

为什么是平台工程 —— 认知地基

动手写控制面之前,先把三件事想清楚:我们在为谁抽象"应用"、平台团队真正该被考核什么、以及平台的边界到底在哪。地基歪了,后面的技术再漂亮也是危房。

1

上云不是搬机器,是重新定义"一个应用"

场景
业务方发来一句"帮我上云",附件是一张表:3 台 8C16G + 一个 MySQL。他脑子里的"应用"是几台机器;平台眼里的"应用"却是一个需要被持续运营的实体。这两个东西不是同一个概念,绝大多数上云项目的痛苦都源于这里没对齐。
概念
从"我要 3 台 8C16G"到"我要一个能跑的应用"是一次抽象跃迁。平台视角下:
  • 应用 = 工作负载 + 配置 + 中间件依赖 + 环境 + 版本 + 归属团队 + 成本中心
  • 后三项(归属、版本、成本中心)恰恰是业务方不会主动说、却决定平台能否运营的关键元数据
对比
「IaaS 思维」交付的是资源,用户拿到机器后一切自理,平台没有应用视图、无法统一治理;「应用思维」交付的是一个可描述、可版本化、可归集成本的对象。
✗ 被否决:"全托管黑盒"路线——为了"降低门槛"把工作负载、网络、中间件全藏起来。结果用户排障时看不到任何东西,抽象泄漏(leaky abstraction)反噬:藏得越多,出事时用户越恨你,最后变成一个没人敢用的黑盒。
落地
  • Golden Path:为 80% 的常见应用铺一条铺装好的默认路径,而不是给 100% 的场景做配置项
  • Thinnest Viable Platform:先做能让第一个应用跑起来的最薄一层,别一上来就建大平台
  • 平台即产品:把内部研发当客户,有用户调研、有采纳曲线、有反馈闭环
戒律
当团队只有个位数应用、且都是一次性交付时,不要急着定义统一应用模型——这时手工 + IaaS 反而更快。应用模型是为"规模化运营"付的税,没到规模别提前交税。
结论
上云的第一产物不是机器,是一个各方都认可的"应用"定义——它决定了后面所有系统能不能对上话。
2

平台团队的真正 KPI 不是上线率,是认知负荷

场景
领导给平台团队定的 KPI 是"季度上云应用数 200"。团队为了冲数,把一堆半吊子应用塞上去,然后被无穷的工单淹没——每个"上云成功"的应用背后是一个学不会平台、天天来问的研发团队。上线率很好看,认知负荷爆表。
概念
引入 Team Topologies 的认知负荷(cognitive load):研发的脑容量是有限的,花在"搞懂平台"上的每一分,都是从"搞懂业务"里抢来的。平台的存在价值,是把研发的外在认知负荷降到最低,而不是把上线数量做到最高。
对比
「强制上云」(政策驱动)和「自服务平台」(产品驱动)是两种驱动力,混在一起会互相伤害:强制会让用户带着抵触情绪来用一个还不好用的平台,把产品口碑透支掉。
✗ 被否决:用"上线率"单一指标考核平台。它会诱导团队制造黑盒、隐藏复杂度、突击冲量,与降低认知负荷的目标直接对立
央企/大型集团语境:政策要求"应上尽上",所以平台必须同时"强制"和"兜底"——强制来的用户没得选,平台就更有义务把体验和排障能力做扎实,否则怨气会积累成政治问题。
落地
度量从结果指标扩展到过程指标:
  • DORA 四指标(部署频率、变更前置时间、变更失败率、恢复时间)衡量交付健康度
  • 平台采纳率:主动选择用平台的比例(区分"被强制"和"真愿意")
  • Time to First Deploy:新应用从零到第一次成功部署的耗时——认知负荷最直接的代理指标
戒律
在纯政策驱动、用户完全没有退出权的场景,不要幻想靠"产品体验"驱动采纳——这时该务实地先保兜底(SLA、专职护航、绿色通道),体验优化往后放。用错驱动力比不优化更糟。
结论
上线率是虚荣指标,认知负荷才是北极星——研发少想一件事,平台就多值一分钱。
3

一站式的陷阱 —— 平台的边界在哪

场景
需求评审会上,每个团队都想把自己的活塞给平台:"能不能顺便管一下我们的数据库?""能不能把安全扫描也集成进来?""能不能帮财务做个报表?"半年后,平台变成一个什么都做一半、什么都做不好的"万能入口"。
概念
平台的能力有个硬天花板:底座(IaaS)的能力上限,就是 PaaS 的天花板。PaaS 能给用户的网络隔离、身份权限、资源配额,都不可能超过底层 VPC / IAM / Quota 能提供的。搞不清这条线,就会承诺自己兑现不了的能力。
对比
「大一统平台」把中间件、安全、成本、CMDB 全吞进来,接口边界模糊,任何一个上游变更都可能砸到平台;「有边界的平台」明确定义与各方的接口,自己只做"应用生命周期编排"这一层。
✗ 被否决:把业务中间件的运维、安全策略的定义、财务口径的裁定都据为己有。这些要么需要专业深度(平台没有),要么需要裁决权(平台没有),揽下来只会背锅。
落地
画清四条接口:
  • IaaS:消费 VPC / IAM / 配额,不重造
  • 中间件团队:平台负责"申请与编排",实例的专业运维归中间件团队
  • 安全团队:平台负责"执行准入卡点",策略由安全定义
  • 财务团队:平台负责"采集用量与打标",分摊口径由财务裁定(见第18篇)
戒律
当某项能力需要专业裁决权而平台没有(如成本口径、安全策略、合规判定),就该明确说"这个不归我们做"。硬揽只会让平台成为所有争议的背锅侠。
结论
好平台的一半功夫花在"说不"上——边界清晰的窄平台,远比边界模糊的全能平台可靠。
模块二 · 技术核心

控制面设计 —— 本系列的立论所在

先讲清 Operator 好在哪,才有资格说"我们不用它"。这一模块给出本项目最核心的技术主张:放弃的是 Operator 这个实现,保留的是控制器思想;以及在没有 etcd 和 watch 的世界里,最终一致性到底靠什么撑起来。

4

Operator 到底解决了什么问题

场景
团队里有人一提"平台"就条件反射"上 Operator",也有人一听 Operator 就摇头"太重"。两边都没说清它到底解决什么——不先讲清它好在哪,我们后面"不用它"的立论就站不住。
概念
  • 声明式 vs 命令式:用户描述"我要什么"(期望状态),而不是"怎么做"(一步步命令)
  • level-triggered vs edge-triggered:Operator 看的是"当前水位"(状态差),不是"某个瞬间的事件"——所以漏事件也能自愈,天生鲁棒
  • Reconcile loop 的本质:期望状态 → 观测实际状态 → 收敛,循环不止
Reconcile Loop(控制器思想的内核)
期望状态

spec (用户意图)

观测实际

observe cluster

收敛

act to close gap

↺  差多少补多少,永不停歇
对比
CRD 的隐含红利常被低估——一旦把模型写成 CRD,你白嫖了一整套基础设施:etcd 做强一致存储、API Server 做鉴权与准入、watch 做事件分发、版本转换 webhook 做 schema 演进。这套东西自研起来极贵,这才是 Operator 真正的杀伤力。
✗ 常见误解:以为 Operator 的价值是"自动化运维脚本"。不——脚本谁都会写,它的价值是那套免费的声明式基础设施。看不到这层,就既学不会它、也没资格绕开它。
戒律
如果你的纳管对象完全在单个 K8s 集群内、且不需要关系型查询与跨系统审计,那自研控制面——老老实实用 Operator,白嫖那套红利。绕开它只在下一篇的三个理由成立时才划算。
结论
Operator 卖的不是自动化,是一套免费的声明式基础设施——认清这点,才谈得上取舍。
5

我们为什么没有把应用模型写成 CRD

★ 立论篇
场景
架构评审上,最大的分歧是应用模型该不该做成 CRD。支持者说"云原生就该这样";我们最终选择了外部控制面 + 关系型元数据库。这不是反潮流,是三个理由逐条评估后的结论。
概念
逐条评估三类"不写成 CRD"的理由——注意,不是每条都成立,成立与否取决于你的约束
  • ① 纳管范围超出 K8s:要同时管虚机、裸金属、传统中间件、多云多集群。CRD 的世界观是"一切在集群内",一旦对象大量在集群外,CRD 就成了别扭的二等公民。(本项目成立)
  • ② 平台元数据需要关系型能力:成本归集要 JOIN、审计要历史版本、工单流要事务、报表要复杂查询。etcd 是 KV 存储,撑不起这些。(本项目成立)
  • ③ 组织能力与运维成本:CRD 升级、版本演进、与集群生命周期强耦合,需要一支能长期维护 controller 的团队。(视团队而定,别拿它当主要理由)
对比
被否决的四条替代路线及原因:
✗ kubebuilder 自研 Operator:回到 CRD 世界观,理由①②未解决,虚机/多集群依旧别扭。
✗ KubeVela(OAM):应用建模优雅,但控制面仍锚在 K8s,元数据的关系型查询与成本归集短板不变,且引入较陡的心智负担。
✗ Crossplane:擅长用 K8s 纳管云资源,但它把 etcd 当事实源,我们恰恰需要一个集群之外的事实源来跨容器/虚机/多云统一。
✗ 纯 GitOps:Git 做事实源,但缺关系型查询、实时状态、细粒度鉴权与成本视图——适合配置,不适合当"平台大脑"。
落地
  • 事实源放关系型数据库(应用/环境/版本/归属/成本中心一张关系图),不是 etcd、不是 Git
  • K8s 退化为众多 Runtime Provider 之一(见第7篇),CRD 只在"确实全在集群内"的子域局部使用
  • 控制器思想完整保留:外部对账循环替代 reconcile loop(见第6篇)
戒律
如果你的三个理由里只有 ③(嫌运维累)成立,那不要走这条路——"团队不想维护 controller"是能力问题,不是架构问题,自研外部控制面的长期维护成本只会更高。这条路的入场券是①和②,不是③。
结论
我们放弃的是 Operator 这个实现,不是控制器思想——当事实源必须活在集群之外,CRD 就不再是答案。
6

外部控制面如何保证最终一致

★ 硬核篇
场景
放弃 CRD 后第一个被追问的问题:"没有 etcd 的强一致、没有 watch 的事件流,你怎么保证用户申请的应用最终真的被创建出来、而且状态不漂移?"这是外部控制面的生死线。
概念
一致性从"K8s 白送"变成"必须自己造"。两条基础路线,各有致命短板:
编排 + 对账 双轮驱动
🔀 工作流引擎驱动

Argo Workflows / Temporal / 自研状态机

强:有序编排、长事务、可视化

弱:漂移检测——事后有人偷改了它不知道

🔁 周期性对账 Job

reconcile job 扫全量比对

强:纠偏、自愈、抹平漂移

弱:时延(几分钟才发现)、惊群(全量扫)

实践答案 = 编排负责"把事做对" + 对账负责"保持做对"
对比
单用工作流:能把创建流程编排得很漂亮,但用户/其他系统绕过平台改了底层,它浑然不觉——缺自愈。单用对账:能抹平任何漂移,但首次创建这种有严格顺序依赖的长流程,硬塞进无状态对账里会很别扭,且时延和惊群难受。所以要双轮:编排 loop 处理意图变更的有序落地,对账 loop 兜底持续纠偏。
落地
没有 etcd 兜底,这四件事必须亲手做对,缺一个就出数据不一致:
  • 幂等:同一操作重放 N 次结果一致(用业务唯一键,不用自增 ID)
  • 重试与退避:指数退避 + 抖动,别把下游打挂
  • 超时与补偿:长动作要有超时和反向补偿(Saga),不能悬挂
  • 并发冲突:乐观锁 / 版本号,拒绝"后写覆盖先写"
⚠️ 状态机设计的第一原则:绝不要把"用户意图"(desired)和"系统实际状态"(observed)存在同一张表/同一个字段。混在一起,你就永远分不清"用户改了"还是"系统还没收敛"——这是外部控制面最常见、最致命的建模错误。
戒律
如果你的对象生命周期极短、或对最终一致的时延要求是秒级实时,不要用"周期对账"这套——它天生有分钟级时延。那种场景该回到事件驱动(甚至就该用 K8s watch),别硬套外部对账。
结论
外部控制面的一致性不是某个中间件送的,是"编排 + 对账 + 幂等四件套 + 意图与实际分离"这套纪律挣来的。
7

多运行时纳管 —— 容器、虚机与中间件的统一模型

场景
同一个业务系统,Web 层想上容器,有状态的计算模块只能跑虚机,还依赖一个传统的商业中间件。用户不想为"上云"把架构推倒重来,他要的是"这一整个应用被平台管起来",不管底下是什么形态。
概念
抽象出 Runtime Provider 接口:定义统一的"部署/伸缩/下线/查状态"契约,K8s 只是实现这个接口的其中一个 provider,虚机编排、中间件申请各是另一个 provider。应用描述与运行时解耦。
一份应用描述 → 编译到多种运行时
📄 统一应用描述(事实源里的一条记录)
↓  Runtime Provider 编译  ↓
K8s Provider

→ Deployment/Svc

VM Provider

→ 虚机编排/云API

中间件 Provider

→ 实例申请工单

对比
「K8s-only 平台」逼所有负载容器化,虚机型和传统中间件负载被排除在治理外,成了游离的影子资源;「Provider 抽象」承认异构现实,用统一模型纳管。代价是抽象层要吃掉各 provider 的能力差异。
✗ 被否决:为每种运行时做一个独立子平台。短期快,长期是数据孤岛——应用视图、成本视图各裂成三份,第18篇的成本分摊直接做不下去。
落地
  • 环境 vs 集群映射:把逻辑概念(dev/test/prod)与物理概念(region/AZ/集群)显式解耦成一张映射表,别硬编码
  • 多架构现实:x86 与国产化 ARM(鲲鹏/海光/飞腾)并存,镜像要多架构、调度要按架构亲和,应用描述里得能表达"我要跑在什么架构上"
戒律
当各运行时的能力差异大到无法用一个抽象表达(比如中间件的专有运维语义),硬抽象成统一接口——那会做出一个"最小公约数"接口,谁都不好用。这时该退让:统一"元数据与成本归集",但放开"运维操作"给各自的专用面板。
结论
K8s 不是平台的全部,只是 Runtime Provider 之一——承认异构,才能把容器和虚机纳进同一本账。
8

应用模型 Schema 的演进与兼容

场景
两年前有人在应用模型里加了个 env: string 字段图省事,现在有一万个应用依赖它,想改成结构化对象——发现三年都拆不掉。一个字段加错,成了永久的技术债。
概念
应用模型的 schema 是平台的"宪法",改动成本随存量应用数指数上升。核心纪律:加字段容易,删字段和改语义几乎不可能——所以每个字段都要当"要用十年"来设计。
对比
「无版本裸奔」:改 schema 就地生效,老应用随时可能被打挂;「版本化 + 兼容策略」:显式版本号、新字段带默认值、只做向后兼容的变更、破坏性变更走灰度迁移。
✗ 被否决:"一把梭大重构"——停服务、全量迁移到新 schema。存量上万应用时,这等于一次全平台停机赌博,没人敢按下按钮。
落地
  • 版本化:schema 带版本,控制面同时理解 N 个版本,转换在读取时惰性完成
  • 默认值优先:新字段必须可缺省,老数据不填也能正常工作
  • 灰度迁移:破坏性变更 = 新字段并存 → 双写 → 逐步切读 → 下线旧字段,全程可回退
  • 参考 OAM(关注点分离:开发者/运维/平台各管一段)与 Score(工作负载描述与环境解耦)的建模思路
戒律
OAM/Score 的建模思路可借鉴,实现不可照搬——它们默认锚定 K8s 运行时,直接搬进我们的多运行时外部控制面会水土不服。学它的关注点分离,别学它的落地假设。
结论
Schema 是会长十年的宪法,不是可以随手改的配置——每个字段都要经得起"三年后想删它"的拷问。
模块三

交付链路 —— 从代码到运行

控制面把"应用是什么"定义好之后,交付链路负责把它真正跑起来:构建镜像、声明式配置的事实源之争、发布即风险管理、以及配置与密钥的边界。这一模块最忌讳"技术全都夸一遍"。

9

从代码到镜像 —— Buildpacks 还是 Dockerfile

场景
安全团队要求所有镜像统一基础镜像、统一扫描;业务团队却各写各的 Dockerfile,五花八门。核心矛盾不是工具,是Dockerfile 该归谁拥有
概念
谁拥有 Dockerfile 决定了治理模式:业务拥有 = 灵活但失控;平台拥有 = 可控但可能不够灵活。Buildpacks 的本质是"把 Dockerfile 从业务手里收归平台",用检测 + 约定生成镜像。
对比
方案适用代价
传统 Dockerfile需要极致定制、特殊系统依赖治理难、基础镜像难统一
Kaniko无 Docker daemon 的集群内构建仍是 Dockerfile,治理问题没解决
Buildpacks标准技术栈、想统一治理非标应用会卡住,逃生舱口要留好
✗ 被否决:强制全员 Buildpacks、禁止 Dockerfile。总有 5% 的应用有特殊依赖,一刀切会把它们逼到平台外自建,反而扩大了治理盲区。
落地
  • 基础镜像治理:平台维护少量经过安全基线的基础镜像,Buildpacks 默认引用
  • 制品库 Harbor + 镜像扫描准入:高危漏洞不让进生产
  • 多架构构建的现实成本:x86 + ARM 双架构 = 构建时间/资源翻倍,得算进流水线预算,别假装免费
戒律
遇到有特殊系统依赖、需要精细控制层的应用,不要硬套 Buildpacks——给它保留 Dockerfile 逃生舱口 + 强制基础镜像。堵死逃生舱口,用户就逃到平台外去了。
结论
选 Buildpacks 还是 Dockerfile,本质是选"谁拥有构建"——治理默认走 Buildpacks,但永远留一个受控的 Dockerfile 后门。
10

GitOps 与外部控制面的共存

场景
团队里 GitOps 的信徒说"一切声明式配置都该在 Git",可我们的事实源是关系型数据库。两个"事实源"打架时,用户改了 Git 又改了平台 UI,到底听谁的?
概念
source of truth 必须唯一——这个问题没有"看情况"的答案,必须有且只有一个赢家。声明式配置放平台数据库还是 Git,取决于谁是那个唯一事实源。
对比
「Git 为事实源」:审计、版本、评审天然,但缺实时状态、关系查询、细粒度鉴权与成本视图;「平台 DB 为事实源」:查询/成本/鉴权强,但要自己补齐版本与评审能力。
✗ 被否决:Git 和平台 DB 双事实源。看似灵活,实则埋雷——两边必然漂移,最后没人说得清系统的真实期望态是什么。
落地
  • 本项目定:平台 DB 是唯一事实源,Git 作为"配置代码的载体",由平台从 DB 单向渲染/导出到 Git,绝不反向以 Git 为准
  • Argo CD / Flux 仍有位置:把它们当作"从渲染产物到集群"的最后一公里投递工具,而非事实源本身
  • 环境提升(promotion)与配置代码分离:提升是元数据操作(改一条 DB 记录的目标环境),不是 copy-paste YAML
戒律
如果你的平台还没有一个可信的关系型事实源,不要为了"用上 Argo CD" 就让 Git 当事实源又让平台也写状态——先把唯一事实源定下来,再决定 GitOps 工具摆在链路哪一段。
结论
GitOps 工具可以留,但"谁是事实源"必须唯一——本项目里 Git 是投递管道,不是大脑。
11

发布不是上线,是风险管理

场景
领导要求"上金丝雀",团队配了金丝雀策略,但生产上其实是"发 5% → 人肉盯 dashboard → 觉得没事就全量"。这不是金丝雀,是披着金丝雀皮的手工滚动
概念
发布的本质是控制变更风险,不是"把新版本弄上去"。真正的金丝雀 = 小流量 + 自动化判据 + 自动回滚,缺了自动判据就退化成手工发布。
对比
策略适用场景不适用
滚动无状态、向后兼容不兼容变更会新旧混跑出错
蓝绿要瞬时切换、可承担双份资源有状态/数据库迁移场景
金丝雀有可信 SLO 指标可做判据没指标时是"假金丝雀"
落地
  • 流量切分依赖 Ingress / Gateway API / 服务网格——没有流量治理能力,金丝雀无从谈起
  • 自动回滚判据:绑定指标 / SLO / 错误预算,超阈值自动回退,别靠人盯
✗ 为什么企业内部金丝雀多是假的:缺乏可信的实时 SLO 指标做判据,于是"金丝雀"只能靠人肉观察——没有自动判据的金丝雀,只是慢一点的全量发布。
戒律
当应用还没有可信的 SLO 指标时,不要假装做金丝雀——老实用滚动 + 快速回滚更诚实。先把可观测性(模块四)补上,再谈金丝雀,否则是自我安慰。
结论
没有自动判据的金丝雀是假的——发布策略的含金量,取决于你的可观测性能不能撑起自动回滚。
12

配置与密钥

场景
半夜有人改了个 ConfigMap 里的超时参数,没走任何发布流程,第二天大面积超时。事后复盘争论:"改配置算不算一次发布?"——这个问题必须有明确答案。
概念
配置变更是不是一次发布?是。配置和代码一样能改变系统行为、一样能引发故障,就该享受同等的评审、灰度、回滚与审计待遇。
对比
「ConfigMap/Secret 直接管一切」:简单,但明文 Secret 只是 base64、无版本、无轮转、无细粒度审计;「外部配置中心 + Vault」:动态配置、密钥轮转、访问审计齐全,代价是接入复杂度。
✗ 被否决:把长期密钥塞进 Secret 甚至镜像里图省事。它没有轮转、没有审计,一旦泄露就是长期敞口。
落地
  • ConfigMap/Secret 管集群内的静态、非敏感配置,认清它的能力边界
  • 外部配置中心接动态配置;Vault 接密钥,做轮转与最小权限下发
  • 配置变更纳入发布流程:走同样的评审/灰度/回滚/审计
戒律
别为了"零信任、全上 Vault"把每个无关紧要的静态配置也搞成密钥动态拉取——过度工程会拖慢启动、增加故障点。区分敏感与非敏感,把重武器用在真需要的地方。
结论
改配置就是发布——不给配置变更上流程,等于给系统留了一条绕过所有安全网的暗门。
模块四

运营与可观测性 —— 让系统可被理解

平台上线只是开始,运营才是长跑。可观测性不是装三个开源组件,SLO 不是拍脑袋定的数字,而第 15 篇的调度参数是通往模块五成本的桥梁——你怎么配 requests,直接决定你花多少钱。

13

可观测性不是装三个开源组件

场景
"我们有可观测性"——追问下去,是装了 Prometheus + Loki + Jaeger 三个组件,然后没人看、告警全静音、日志存储费月月超支。装了三个组件 ≠ 有可观测性。
概念
指标 / 日志 / 链路三支柱,成本量级差三个数量级:指标最便宜(聚合数),日志最贵(全量文本),链路居中且采样敏感。可观测性设计首先是成本设计
对比
Prometheus vs VictoriaMetrics 的选型分水岭:单集群中小规模,Prometheus 足够;一旦要长期存储、多集群聚合、高基数指标,VictoriaMetrics 的存储效率和水平扩展成为分水岭。
✗ 被否决:无脑全量日志 + 无限保留。日志是最贵的一支柱,不做采样/分级/TTL,可观测性预算会先于业务把你压垮。
落地
  • OpenTelemetry 的收敛价值:统一采集与语义,避免被单一后端锁定,未来换后端不用改埋点
  • 多租隔离与查询限流:租户间数据隔离 + 查询配额,防止一个租户的大查询拖垮整个监控系统
  • 按支柱分别定预算与保留策略:指标长留、日志分级 TTL、链路采样
戒律
在中小规模、单集群场景,不要一上来就上 VictoriaMetrics + OTel Collector 全家桶——Prometheus 单实例够用时,全套重型方案只是徒增运维面。可观测性的复杂度要匹配规模。
结论
可观测性是一道成本题——先算清三支柱各花多少钱、谁真的会看,再决定装什么组件。
14

SLO 与错误预算在内部平台的落地

场景
平台承诺"高可用",但没人说得清是几个 9。出故障后业务问"你们不是高可用吗",平台哑口——没有量化的 SLO,"高可用"就是一句可被随意解释的空话。
概念
SLO 是量化的可靠性目标,错误预算 = 1 − SLO,是允许出错的额度。它把"要不要冒险发布"从吵架变成算账:预算还有就能发,烧光了就冻结。
对比
业务应用的 SLO 该由平台代管吗?——「平台代管业务 SLO」:统一但平台背了不该背的锅(业务代码烂也算平台失败);「平台只管平台自身 SLO」:边界清晰,业务 SLO 由业务自己负责,平台提供工具。本项目倾向后者。
✗ 被否决:平台大包大揽所有业务的 SLO。业务可靠性受其自身代码质量支配,平台无法控制却要担责,纯背锅。
落地
  • 平台自身 SLO 先定清楚(控制面可用性、部署成功率、API 时延),这是平台的信用
  • 告警降噪:从"能告"到"敢看"——基于 SLO/错误预算烧尽速率告警,而非单指标阈值刷屏。告警多到没人看,等于没有告警
戒律
别给一个还没有稳定流量基线的新应用硬定 SLO——数字会是拍脑袋的,错误预算也就成了摆设。先观测出真实基线,再定 SLO。
结论
SLO 把可靠性从口水仗变成算账——先管好平台自己的几个 9,别急着替业务背它的锅。
15

容量、变更与故障 —— 通往成本的桥梁

场景
一个应用申请 requests: 8C16G,实际常年用 1C2G。它没做错什么——但这条 requests,直接决定了它在成本账单上被算多少钱(见第18/19篇)。调度参数是技术,也是钱。
概念
调度参数不只是稳定性旋钮,更是成本旋钮
  • requests/limits:requests 决定调度占位与(多数计价下的)成本,limits 决定被限流/OOM 的边界
  • QoS(Guaranteed/Burstable/BestEffort):决定资源紧张时谁先被驱逐
  • 亲和性 / 污点 / 驱逐:决定装箱密度,进而决定整体资源利用率
对比
「requests 拍大数图省事」:稳,但资源被大量占而不用,装箱率低、成本高;「requests 贴近真实 + 弹性兜底」:利用率高、成本低,但需要可观测数据支撑和一定的驱逐容忍。
✗ 被否决:为了"绝对稳"让所有应用 requests=limits 且都拉满。这是把成本浪费当保险买,第19篇会算出这里藏着 60% 的浪费。
落地
  • 变更管理 + 灰度:调度参数变更也是变更,要灰度、可回退
  • 故障演练:主动注入驱逐/节点故障,验证 QoS 和亲和性配置真的有效
  • 把调度参数的合理性接入成本反馈:这是模块四与模块五的接缝
戒律
延迟极敏感的核心交易应用不要为省成本而激进压 requests / 上混部——这类应用的抖动代价远超那点资源费。省钱要挑对象,别在关键路径上抠。
结论
你怎么填 requests,就是在给自己开账单——调度参数是可观测性和 FinOps 之间的那座桥。
模块五 · 差异化重点

FinOps 与成本分摊 —— 把云费用变成工程决策

多数平台博客写到模块四就停了。这一模块是本教程的差异化所在:从 Tag 治理起步,到公摊成本怎么分才服众(最硬的一篇),到揪出 60% 的浪费,最后落到单位经济。记住——成本口径是财务问题,不是技术问题。

16

FinOps 不是省钱,是把成本变成工程决策的输入

场景
财务甩来一句"云费用涨太快,砍 30%"。工程团队一脸茫然:砍谁?砍了会不会出事?——因为成本从来没进过工程决策,砍成本就成了盲砍。
概念
FinOps 三阶段 Inform → Optimize → Operate:先让成本可见(谁花的、花在哪),再优化,最后把成本意识固化进日常运营。核心不是省钱,是让"这个架构决策要花多少钱"成为设计时就能看到的输入。
对比
Showback vs Chargeback —— 组织成熟度的分水岭
Showback(示账)

只让你看到账单,不动你钱包

易推行、阻力小

无痛感、难驱动真正的优化

Chargeback(扣账)

真从你的预算里扣钱

有痛感、真驱动行为改变

要求口径无争议、组织成熟

✗ 被否决:组织还没准备好就硬上 Chargeback。口径一旦有争议,扣错一分钱就是跨部门战争,会把整个 FinOps 计划打回原形。
落地
  • 先做扎实的 Showback 建立信任与口径共识,再择机演进到 Chargeback
  • 为什么技术团队普遍在这块是短板:它是技术 × 财务 × 组织的交叉学科,纯技术视角看不全
戒律
口径未达成共识前,不要上 Chargeback——没有服众的分摊口径(第18篇),扣账只会制造矛盾而非节约。先 Showback。
结论
FinOps 的目标不是砍账单,是让成本在你做架构决策的那一刻就可见——Showback 铺路,Chargeback 收官。
17

一切从 Tag 治理开始

场景
想出一张"各团队云成本"报表,结果 40% 的资源查不到主人——没打标签,或标签乱写。后面所有的成本分摊,在这一步就地基崩塌。
概念
没有标签规范,后面全是玄学。成本归集的前提是每一份资源都能追溯到"应用 / 团队 / 环境 / 成本中心"。Tag 治理是 FinOps 的第 0 步,不是可选项。
对比
「事后补标签」:靠人肉给存量资源猜主人,永远补不全、准不了;「准入时强制」:没打齐标签的资源根本创建不出来,从源头保证 100% 覆盖。
✗ 被否决:只发规范文档、靠自觉打标签。自觉在成本这件事上从不生效——三个月后覆盖率依旧惨不忍睹。
落地
  • 强制 Label/Tag 最小集:应用、团队、环境、成本中心——四个,不多不少
  • 准入拦截:控制面 + K8s 准入 webhook 双卡点,没打标签不让上
  • 存量补标签工程:这是一次性的历史债清偿,靠自动推断 + 人工确认,别指望一步到位
戒律
别把标签最小集设计得过于庞大(十几个必填)——填不动的规范等于没有规范,用户会想办法糊弄。宁可四个强制、都填对,也不要十五个字段、个个是垃圾数据。
结论
Tag 治理是 FinOps 的地基——用准入卡点强制四个核心标签,胜过一百页无人遵守的规范。
18

公摊成本怎么分才服众

★ 最硬一篇
场景
账单里 30% 是"公摊"——控制面、网关、监控这些没法直接归给某个应用的成本。一摊到各团队,立刻炸锅:"凭什么我们大团队要替小团队分摊这么多?"公摊分摊,是 FinOps 里最容易引发战争的一环。
概念
谁是公摊:控制面、网关、监控、日志、镜像库、跨 AZ 流量——这些是平台为所有人提供的共享设施,无法直接归属单一应用,必须找一个分摊规则摊下去。
对比
三种分摊算法,每种都有政治后果,选算法本质是选"让谁不爽":
算法怎么算政治后果
均摊N 个团队平均分简单,但大户占便宜、小户吃亏,用得多的没多付
按用量比例按实际 usage 占比最公平,但"用量口径"要先定义清楚,且用量会波动
按 requests 比例按申请的 requests 占比可预测、账单稳定,还反向激励用户缩小 requests(正好呼应第19篇治浪费)
✗ 被否决:技术团队自己拍板选"均摊"因为最好实现。均摊让大户占便宜,一旦大户是话语权强的团队,这套分摊迟早被推翻——省的是代码,赔的是信任。
落地
  • 本项目倾向按 requests 比例:账单可预测,且激励用户主动降配,一箭双雕
  • 算法要可解释、可复算:任何团队都能自己把账单算一遍对上,才服众
  • 把公摊项明细列出,别塞进一个黑盒"其它费用"
戒律
口径由谁定:这是财务问题,不是技术问题。平台绝不要擅自裁定分摊口径——你没有这个裁决权,定了也没人认。平台的职责是忠实采集用量、透明执行财务定好的口径,把"谁该多付"这个政治决定还给有权做它的人。
结论
公摊分摊的技术只占一成,九成是口径的政治——平台负责把账算得透明可复算,把"怎么分"的决定权交还财务。
19

Requests 与实际使用率之间,藏着你 60% 的浪费

场景
集群资源"用满了",申请扩容。一拉利用率曲线——真实 CPU 使用率长期在 15%。所谓"用满",是 requests 占满了,不是资源真被用了。60% 的钱花在了没人用的预留上。
概念
requests 是"申请",usage 是"实际用",两者的鸿沟就是浪费池。关键杠杆:
  • 装箱率 / 超卖比:能不能安全地让 requests 之和 > 物理资源
  • 混部:在线 + 离线错峰共享
  • 闲置回收:长期零负载的资源自动回收
对比
计价模型的激励差异是关键设计
计价方式激励
按 requests 计费逼用户主动降 requests——申请多少付多少,浪费自负
按 usage 计费用户没动力降 requests——反正按实际用量付,占着茅坑不花钱
本项目多按 requests 计费,正是为了用账单驱动降配。
✗ 被否决:只发一张"资源利用率报表"就指望团队自己优化。报表不可执行,看完该浪费还浪费——要给的是"把 requests 从 8C 降到 2C"这种可一键执行的建议。
落地
  • 包年包月 / 按量 / 预留实例的摊销要正确处理,别把预留的沉没成本乱摊
  • 拆解 OpenCost / Kubecost 的计价模型,理解它怎么把集群成本还原到工作负载
  • 推荐引擎:基于历史 usage 给出可执行的降配建议(具体到新 requests 值 + 一键应用),而不是又一张只读报表
戒律
别对有明显尖峰或突发流量的应用激进降 requests——它的低平均利用率背后可能是关键的峰值容量。降配要看 P95/P99,不能只看均值,否则省了钱赔了故障。
结论
最大的一笔云浪费不在账单上,在 requests 和 usage 的缝里——用按-requests 计费 + 可执行降配建议把它挤出来。
20

单位经济与平台的终局

场景
CFO 问"这个月云花了多少",你答得出来。但他真正想知道的是"每笔交易的云成本是多少、赚不赚钱"——这个问题,绝大多数平台答不上来。这才是 FinOps 的终点。
概念
单位经济(Unit Economics):从"这个月花了多少"(总量)跃迁到"每笔交易 / 每个用户 / 每个请求的云成本是多少"(单位)。只有到了单位成本,成本才真正变成能指导业务与架构的决策变量。
对比
「总量视角」:只能回答"贵不贵",无法回答"值不值";「单位视角」:能回答"这个功能每次调用花 3 分钱,值不值得做缓存"。
✗ 被否决:把平台的终极价值定义为"把云的复杂度全藏起来"。藏起来的代价是成本也不可见——用户做不出成本感知的架构决策,反而更浪费。
落地
  • 把成本数据关联到业务指标(交易数/活跃用户/请求量),算出单位成本
  • 成本可见性反向影响架构决策:看到单位成本,团队才会主动做缓存、降配、选更省的方案
戒律
在成本可见性(Showback / Tag / 分摊)还没打通前,空谈单位经济——没有底层的归集数据,单位成本只是一个算不出来的漂亮概念。它是终局,不是起点。
结论
平台工程的价值不是把云藏起来,是让正确的选择变成默认选项——终局是让每个工程师都看得见自己每笔交易花了多少钱。
附录 · 番外

术语 · 选型速查 · 央企语境 · 入组三问

📖 A. 术语对照表

Golden Path
平台为最常见场景铺好的"铺装道路"——默认选择正确、阻力最小的那条路,不是唯一的路。
Thinnest Viable Platform
能让第一个应用跑起来的最薄平台。反对一上来就建大而全的平台。
Cognitive Load
认知负荷。Team Topologies 概念,平台的核心目标是降低研发的外在认知负荷。
Reconcile Loop
对账循环。期望状态 → 观测实际 → 收敛,控制器思想的内核,外部控制面用对账 Job 复刻它。
Level / Edge-triggered
看"当前水位差"(鲁棒)vs 看"瞬时事件"(漏了就丢)。控制器偏好 level-triggered。
Runtime Provider
运行时提供者接口。K8s、虚机、中间件各是一个 provider,应用描述编译到多种运行时。
Showback / Chargeback
示账(只给你看)/ 扣账(真扣你预算)。组织成本成熟度的分水岭。
Unit Cost
单位成本。每笔交易/用户/请求的云成本,FinOps 的终极视角。
Error Budget
错误预算 = 1 − SLO。允许出错的额度,把"要不要冒险发布"变成算账。
Leaky Abstraction
抽象泄漏。藏得太多,用户排障时底层细节漏出来反噬体验。

🧭 B. 控制面选型速查(适用象限)

自研 Operator(kubebuilder)

纳管全在单集群内 + 需要 CRD 那套免费基础设施 + 有团队长期维护 controller。

KubeVela(OAM)

想要优雅应用建模、且能接受控制面锚定 K8s、元数据关系型需求不强。

Crossplane

想用 K8s 声明式纳管云资源、且愿意以 etcd 为事实源。

自研外部控制面(本项目)

纳管超出 K8s(虚机/多云)+ 元数据需关系型查询/审计/成本归集。入场券是这两条,不是"嫌 Operator 累"。

🇨🇳 C. 央企语境专题(对平台设计的硬约束)

  • 信创国产化:x86 与国产 ARM(鲲鹏/海光/飞腾)并存 → 多架构镜像、按架构调度是刚需,不是选配。
  • 等保合规:等级保护要求落到网络隔离、审计留痕、准入卡点——平台的准入 webhook 和审计能力是合规载体。
  • 数据分级:不同密级数据的存储/流转边界,约束了多租隔离与跨环境提升的设计。
  • 同城双活 / 异地容灾:环境↔集群映射必须显式表达 region/AZ,发布与流量切分要感知容灾拓扑。
  • 政策驱动的"应上尽上":平台必须同时"强制"和"兜底"(见第2篇)——强制来的用户,平台更有义务把体验和 SLA 做扎实。

🔑 D. 新人入组第一周的三个问题

带着这三个问题去找导师对答案,你就摸到了这个平台的骨架:

  • 应用模型的 schema 长什么样?(对应第 8 篇——这是平台的宪法)
  • 控制面靠什么保证最终一致?(对应第 6 篇——编排+对账,还是别的?)
  • 公摊成本的分摊口径谁定的?(对应第 18 篇——答案如果是"平台定的",那是个危险信号)

🚀 E. 发布节奏建议(给内容运营)

阶段内容定位
第 1 波第 5、6 篇立论,最有传播力,先发
第 2 波模块五(16–19)差异化,多数博客不写
第 3 波模块一、二剩余补齐地基
第 4 波模块三、四常规内容,可压缩合并
💡 只写三篇的话:第 5 篇(为什么不用 CRD)、第 6 篇(外部控制面一致性)、第 18 篇(公摊分摊)——覆盖了本项目最难、最有观点、也最少人写清楚的部分。