7.12 何时不该用 K8s

一句话

K8s 卖的是 “编排能力”,收的是 “认知税 + 运维税”:服务数 < 10、团队 < 5 人、发布频率 < 每周一次时,这笔税通常不划算——不是 K8s 不好,是它解决的问题你还没有。

先算账:K8s 的固定成本清单

成本项 内容 量级
控制面 托管控制面费用,或自建 3 台控制面节点 托管约每月 70–150 美元量级;自建 3 台机器 + etcd 备份
节点与系统组件 CNI、CoreDNS、Ingress Controller、metrics-server、日志/监控 agent 每节点 5%–10% 的 CPU/内存开销
存储 CSI 驱动、存储类、快照与备份 与业务存储同量级,另加管理成本
人 平台/运维投入(升级、排障、RBAC、配额、网络) 0.5–1 FTE(团队 < 10 人时往往没人专职)
学习曲线 对象模型、网络模型、调度、排障 熟练 6–12 个月

把这些摊到 “3 个服务、2 个环境、每两周发一次” 的团队上,等于用一台挖掘机挖花盆。

判断表:你的情况该用什么

你的情况 建议 理由
1–3 个服务,单团队,日发布 < 1 次 单机 + systemd + 反向代理,或 docker compose 运维成本最低,故障面最小
5–15 个服务,需要多环境与灰度 托管容器服务(ECS / Cloud Run / App Runner 类) 拿到弹性与隔离,不必自己管控制面
需要按事件计费、极低频 Serverless(FaaS) 零闲置成本,冷启动可接受时最优
20+ 服务、多团队、要独立发布节奏 用 K8s(优先托管) 这正是它设计要解决的问题
有专职平台团队、需要统一调度与配额 用 K8s 平台能力能摊薄到多团队
强合规要求多租户隔离 K8s + 强隔离运行时(见 6.5 容器运行时 (containerd / runc)) 隔离能力可分层实现
批处理/离线任务为主 队列 + worker 池(或 K8s Job) 调度需求简单,不必上整套编排

判据可以压缩成三个问句:服务数够多吗?发布节奏够快吗?有人专职维护吗? 三问有两个 “否”,就别上。

三种常见替代方案

方案 给什么 代价
单机 + systemd 进程守护、开机自启、日志 无横向扩展、无滚动更新,机器挂了就挂了
托管容器服务 容器运行 + 负载均衡 + 自动扩缩 平台锁定、可定制性弱(但比自建 K8s 省一个量级的人力)
Serverless / FaaS 按调用计费、零闲置 冷启动、无长连接、状态受限

很多 “必须上 K8s” 的需求,真实答案是 “托管容器服务 + 一个网关”:它给你 80% 的编排收益,收 20% 的税。

K8s 真正不可替代的场景

场景 为什么别的方案不行
多团队共享集群,需要命名空间级配额与隔离 资源配额、RBAC、NetworkPolicy 的组合能力
需要统一调度异构负载(在线 + 离线 + GPU) 调度器与优先级/抢占
需要 Operator 生态管理中间件 CRD + 控制器(见 7.10 Operator 与 CRD)
需要 “声明式 + 自愈 + 滚动更新” 的标准答案 控制器模式(见 7.1 声明式 API 与控制器模式)
跨云/混合云的可移植性 统一 API,避免绑死某家运行时

注意最后一条常被高估:可移植性只在 “应用本身没有深度绑定” 时成立。用了云厂商的专有存储、专有 LB、专有 IAM,迁移成本照样高(见 5.7 云厂商锁定与迁移)。

迁出的信号

信号 含义
集群里长期只有 3–5 个工作负载 收益远小于固定成本
没人能解释一次 Pending 的原因 平台能力缺位,K8s 变成 “黑盒”
发布靠手改 YAML / 控制台点击 声明式的价值没被用上
每年升级一次 K8s 版本都像渡劫 缺少平台团队与升级预案
80% 的告警来自平台组件 你在维护 K8s,而不是在用它

代码:用一份“最小决策脚本”代替拍脑袋

# 判据不是“想不想用”,而是四条硬指标:服务数、发布频率、团队规模、隔离需求
need = dict(services=3, releases_per_week=1, platform_engineers=0, compliance_isolation=False)
score = 0
score += 2 if need["services"] >= 10 else 0
score += 2 if need["releases_per_week"] >= 10 else 0
score += 2 if need["platform_engineers"] >= 2 else 0
score += 2 if need["compliance_isolation"] else 0
print("K8s 优先级:", "高" if score >= 6 else "中" if score >= 4 else "低(先用托管 PaaS/单机编排)")
# 已经上了 K8s 的团队,用这两条自查“是否过度”
kubectl get deploy -A | wc -l        # 服务数 < 10 却维护一套集群?
kubectl top nodes | tail -n +2 | awk '{print $3}'   # 节点 CPU 长期 < 20% = 资源浪费

反模式

反模式 后果
为了简历 / 招聘上 K8s 长期背着没人会用的平台
把 K8s 当 PaaS 用(期望它自带发布、灰度、密钥管理) 需要再搭 5 个组件,复杂度翻倍
用小团队自建 K8s 控制面 升级、备份、证书轮换全是坑
用 K8s 弥补架构问题(单体拆不动就上编排) 分布式单体 + 平台复杂度,双重负担
没有配额与 LimitRange 就多团队共用 一个团队吃满集群,其他人 Pending
上 K8s 却不做可观测性 故障时只能 kubectl describe,排障以小时计

三条铁律

🔑 先问 “我要解决什么问题”;K8s 解决的是 “多服务多团队的编排”,不是 “部署方便”。

🔑 能用托管就不自建控制面;控制面的升级与证书轮换是纯负担,不产生业务价值。

🔑 没有专职维护者就别上;平台能力的缺口会以 “每次发布都出事” 的形式偿还。

自检

Q1 一个 4 人团队、6 个服务、每周发一次版,想自建 K8s。你会建议什么?

▸ 答案:托管容器服务或单机 + 容器运行时。理由:K8s 的固定成本(控制面、CNI、Ingress、监控、0.5–1 FTE)摊到 6 个服务上,人均负担很重;而他们真正的需求(部署、重启、简单扩缩)托管容器服务已经覆盖。若将来服务数到 20+、团队到 3 个以上、需要独立发布节奏,再迁。

Q2 为什么 “我们用 K8s,所以不会被云厂商锁定” 只对一半?

▸ 答案:因为 K8s API 可移植,但周边都是厂商专有的:负载均衡实现、存储类与 CSI 驱动、IAM/IRSA、私有网络、镜像仓库、日志与监控。应用只要用了这些,迁移成本依然很高。真正的可移植性来自 “应用只依赖标准接口 + 数据可导出 + 退出演练”,而不是 “跑在 K8s 上”(见 5.7 云厂商锁定与迁移)。

Q3 团队说 “上 K8s 之后发布变快了”。这句话要怎么验证?

▸ 答案:看三个数:从合并到上线的时长、发布失败率、回滚耗时。如果发布变快是因为 “一次发布包含更多变更”,那不是变快而是批量更大(风险也更大)。真正的提速来自:镜像构建缓存、自动化流水线、滚动更新与回滚能力——这些在托管容器服务上同样能拿到。

Q4 什么情况下 “自建 K8s 控制面” 是合理的?

▸ 答案:三种:① 合规要求控制面必须在自己机房(数据主权);② 规模大到托管成本不可接受(数百节点、多集群统一治理);③ 需要深度定制调度器/准入链(平台团队有相应能力)。三者都要配 “专职团队 + 升级预案 + etcd 备份演练”,否则省下的钱会被事故吃掉。

Q5 如果已经上了 K8s 但只用 3 个 Deployment,怎么判断该不该迁出?

▸ 答案:算两笔账:固定成本(控制面 + 平台人力 + 监控组件)与 替代成本(托管容器服务的费用 + 迁移工时)。若固定成本每年高出替代方案 30% 以上,且没有 “多团队/多环境/弹性” 的近期需求,就该迁。迁出不必一次完成:先把无状态服务搬到托管容器,保留 K8s 给需要调度的部分,是常见的过渡形态。

跨篇相关:容器与虚拟机的边界见 6.1 容器与虚拟机的本质差异;声明式与自愈的能力从哪来见 7.1 声明式 API 与控制器模式;托管与自建的取舍方法见 5.5 托管服务与自建的取舍;部署形态的对比见 33.1 单体部署、33.3 Serverless / FaaS;团队规模与架构的关系见 27.1 单体架构的适用性;锁定与迁移成本见 5.7 云厂商锁定与迁移。