【背景】 做了 8 年 K8s 运维,过去两年被问最多的一句话是:"这个服务能不能也容器化?" 我们团队去年推了 40+ 个服务的容器化改造,其中大概 6 个是"勉强塞进去"的——有状态老 Java 应用、依赖本地 NVMe 的离线计算、调过 vm.max_map_count / net.core.somaxconn 的内核敏感服务、依赖 /dev/xxx 设备直通的采集器。塞进去之后,我半夜被叫起来处理过 3 次:本地盘被节点驱逐后数据不一致、内核参数在 DaemonSet 和 init 容器之间打架、依赖宿主机的监控 agent 直接失效。
【常见分歧 / 几种做法】
- 全容器化派:能跑起来就是胜利。有状态用 StatefulSet + PVC,宿主机依赖用 privileged + 挂载宿主路径,"先跑起来再说,问题后面再修"。
- 边界派:无状态业务容器化,有状态 / 中间件(MySQL、Redis、Kafka、ES)留在 VM 或云托管服务,K8s 只做编排和调度。
- 混合派:K8s 为主,但有状态服务用 Operator + 本地盘(etcd、CockroachDB 那套),宿主机能力通过 sidecar / DaemonSet 提供。
- 务实派:看团队规模——10 人以下团队,全 VM + Ansible 更省命,引入 K8s 的运维成本大于收益。
【我的倾向与理由】 我倾向 2) + 4) 的组合:
- 无状态业务服务:容器化,没争议;
- 有状态中间件:能上云托管就托管,上不了就 VM 自建,不建议自己用 K8s 跑 MySQL(除非你有专职 DBA 团队 + 完善的备份 / 高可用 / 慢 SQL 分析 / 主从切换演练体系);
- 依赖宿主机能力的服务(本地盘、内核参数、设备直通):老实 VM,或者用 Fargate / EKS Hybrid / 自建节点池混合方案,别硬塞进普通 K8s 节点池;
- 团队规模 < 10 人:先别急着 K8s,VM + 脚本 + 简单的编排(哪怕 systemd + cron)更省命。
理由就一句话:K8s 的抽象建立在"无状态、可替换、可水平扩展"之上。你越往有状态和宿主机依赖方向塞,这层抽象就越薄——最后你维护的不是 K8s,是一堆"披着 K8s 外衣的 VM"。更糟的是,出问题时 K8s 的自动调度 / 自愈 / 驱逐反而会放大故障:一个有状态 Pod 被驱逐到另一台节点,本地盘数据就丢了;一个 privileged 容器跑起来后,节点故障域和业务故障域就绑死了。
【想听大家在什么场景下怎么选】
- 你们团队里"勉强塞进 K8s"的服务有哪些?后来怎么处理的(改架构 / 回退 VM / 加了 Operator / 加了 DaemonSet)?
- 有状态服务(MySQL / Redis / Kafka / ES / MongoDB)你们是上云托管、VM 自建、还是 K8s Operator?为什么这么选?踩过什么坑?
- 依赖宿主机能力(本地盘 / 内核参数 / 设备直通 / 特定文件系统)的服务,你们怎么做的?privileged + 挂载宿主路径这条路你们走没走过,翻过车吗?
- 团队规模 < 10 人、服务数 < 20 个的,你们真的需要 K8s 吗?还是 VM + 脚本更省命?什么信号出现时你们才决定上 K8s?
先说结论,再讲场景和踩过的坑,比"我觉得 K8s 很好"或"我觉得 K8s 很坑"都更有价值。
0赞
0收藏
0楼层