第一次正经管 Kubernetes 的一些坑
今年公司的基础设施从自建机房迁到了云上的 K8s,运维的活儿有相当一部分落到我们组头上。作为一个写了十年代码没怎么管过机器的人,这半年补了很多课,挑几个印象深的记下来。 资源 requests/limits 别乱填。 上线前凭感觉给服务配了 limits:内存 4G、CPU 2 核。结果高峰期 CPU 被 throttle,接口 P99 从 80ms 涨到 400ms,监控上还看不到任何异常——throttle 不报错,就是慢。后来用 Grafana 盯着 CPU throttling 指标重新校准了所有服务的配额。教训:limits 配小了比不配还危险,因为故障形态是"变慢"而不是"报错",最难排查。 滚动更新的 maxSurge 和 readiness 探针是一对。 我们有个服务启动时要预热本地缓存,要 40 秒。没配 readiness 的时候,新 pod 起来就被接入流量,一堆请求打到没预热完的实例上。配上探针之后,又发现 terminationGracePeriodSeconds 太短,滚动更新时旧 pod 还没处理完存量请求就被杀了。这两个参数要配对一起看,单看哪个都不对。 HPA 不能只看 CPU。 推送网关那种长连接服务,CPU 很低但连接数高,按 CPU 扩缩容等于没有。最后接了自定义指标(连接数)做 HPA,才算了结。 最花时间的一次事故:某个周四凌晨所有 pod 同时重启。查下来是节点镜像_gc 策略配置问题,kubelet 把正在用的镜像清了,拉镜像又赶上镜像仓库限流。运维同学说这叫"基础组件的雪崩",我理解了为什么老运维对"全部 egg 放一个篮子"这么警惕。 总的来说,K8s 把"部署"这个动作的门槛降低了,但把"理解系统为什么这样运行"的门槛提高了。前者是工具问题,后者是知识问题,知识没法速成。我的学习路径就一条:出了事故就去把对应的原理文档读了,比先读完文档再上手记得牢。