首页 / it.itcdj.com / 正文

踩过三年生产坑才摸透的Kubernetes

上周跟一个做政务云的老伙计吃饭,他说刚把去年砸了几百万上的Kubernetes集群砍了一半节点,现在每月光云成本就省了四十多万。我问他为啥当初要上那么多,他挠头说,当时厂商吹得天花乱坠,说容器化是趋势,上了就能降本增效,谁知道光给集群做版本升级就折腾了小半年,业务方还天天投诉Pod调度延迟。

真的。我跑过差不多二十多个不同行业的生产Kubernetes集群,从几十节点的小集群到上千节点的大集群都见过,这里面的坑,真不是看几篇官方教程就能避开的。

别被厂商的”降本神话”骗了

很多刚接触Kubernetes的团队,第一反应就是上了容器化,就能把原来浪费的资源给挤出来,把服务器利用率从百分之十几提到百分之五六十。听着确实诱人。

但麻烦就麻烦在这。Kubernetes从来不是适合所有业务的万能药。

我见过太多团队,上来就把所有存量业务往集群里塞,不管原来的服务是不是适合容器化。比如那种跑了十年的老单体应用,依赖一堆本地磁盘的固定路径文件,还有跟宿主机内核强绑定的老旧模块,硬塞进容器里,最后光是做持久化存储的适配就耗了运维团队三个月的时间。

之前有个做内部OA的团队,为了跟风上Kubernetes,把原来跑在三台物理机上的OA系统迁上去,最后光是处理NFS存储的权限问题就出了十几起线上事故。算下来的账更可笑——原来三台物理机一年的成本才两万,现在Kubernetes集群光控制平面的成本一年就要六万,还搭进去两个运维的全部精力,天天要处理集群的各种小故障。

Kubernetes生产集群控制平面架构实拍图


说白了,那些被宣传册吹得神乎其神的资源利用率提升,本质上是建立在你的业务真的能接受容器的隔离逻辑,真的能做到无状态部署的前提上的。如果你跑的业务根本达不到这个要求,硬上Kubernetes,不仅降不了本,反而会把原来简单的部署流程给搞复杂。

调度逻辑的坑,踩过才知道疼

很多人刚用Kubernetes的时候,觉得调度器是个自动干活的黑盒。给每个Pod标好CPU和内存的request值,就等着它自动把负载均匀分到各个节点上,省心省力。

太天真了。

默认调度器的判断逻辑,只看你显式声明的request值,不会真的去探知节点上进程的实际资源占用。

之前有个做视频转码的团队,为了能在单节点上跑更多转码任务,给所有转码Pod设置的内存request是512M,limit是4G。结果高峰期的时候,节点上的内存被实际跑的转码进程吃满,调度器还在不断把新的Pod往这个节点上塞,根本不管实际的内存余量。最后内核触发OOM Killer,把节点上的核心转码进程给杀了,积压的转码任务直接卡了好几个小时。

还有更离谱的。有的团队为了让Pod跨可用区分布,硬加了多层反亲和规则,结果某个可用区的节点资源提前耗尽,符合规则的Pod直接卡在Pending状态,等了半小时都没调度上去,业务方追着运维组骂了整整一下午。

Kubernetes Pod调度Pending状态监控面板截图
Kubernetes Pod调度Pending状态监控面板截图


这事没那么玄。调度器从来不会猜你的业务需要多少资源,它只认你写在配置里的数字。你要是一开始就把request设得跟实际需求差十万八千里,后面出问题是迟早的事。

版本升级的隐形成本

版本升级的隐形成本
版本升级的隐形成本
很多人对Kubernetes升级的认知,还停留在敲一行kubeadm upgrade的命令,等个十几分钟就完事的程度。

太想当然了。

生产环境的Kubernetes集群,每一次版本升级的代价,从来都不是升级脚本执行的那十分钟。

我见过最夸张的一个电商团队,大促前一周想赶个新版本的Kubernetes,用上新的Ingress转发特性。结果升级完才发现,之前写的一堆基于旧API的自定义CRD全部失效,老版本的Ingress配置根本没法被新的控制器识别,高峰期的流量直接乱转发,打挂了三个核心服务。最后临时回滚花了四个小时,算下来损失的订单额,够付三年的集群运维成本。

而且这个代价是持续性的。Kubernetes的版本迭代节奏很快,每三个月就会出一个新版本,每个版本都会弃用一批旧的API。你要是跟得慢,隔个两三年再想升级,就得把这两三年里所有被弃用的API全部适配一遍,写的那些自定义脚本、监控采集规则、运维流程,全部要重写一遍。

之前跟一个做金融系统的团队聊,他们现在的Kubernetes集群已经卡在1.20版本快两年了。不是不想升级,是真的升不动——光对接的存储插件、网络插件、自定义安全规则,就花了团队五个工程师半年的时间梳理,要全部适配到新版本,少说还要再搭进去三四个月的精力。

现在很多团队跟我聊起Kubernetes,第一反应就是累。天天要处理各种奇奇怪怪的集群问题,今天etcd又触发了快照超时,明天CoreDNS又解析异常,后天节点的kubelet进程又卡死了。

但你要真让他们把集群撤了,回到原来的虚拟机部署模式,他们又舍不得。毕竟真到了业务需要快速迭代的时候,容器镜像的一致性,还有一键回滚的能力,确实比原来手动配环境快太多了。

没有银弹。

很多人说Kubernetes复杂,其实复杂的根本不是Kubernetes本身。是你为了适配它而不得不做的所有配套工作——要做存储就得对接CSI,要做网络就得搞CNI,要做监控就得接Prometheus,要做日志就得配EFK。这些东西加起来,才是整个Kubernetes体系真正的门槛。

别听人吹什么学了Kubernetes就能涨多少薪,真等你在生产集群里踩过几次OOM、网络不通、调度卡住的坑,就会明白,这东西从来没有什么捷径。无非是你花的每一分精力,最后都会变成集群稳定运行的底气而已。