
🌟 一次让我蜕变的K8s故障排查实录:从“线程泄漏”到全局PID耗尽 🌟
作为一名SRE,最深刻的成长往往源于“踩坑”后的反思。今天分享一次让我在面试中收获最多、成长最快的K8s故障复盘经历——一次由全局PID耗尽引发的Calico网络崩溃事件。
面试官抛出一个经典问题:“遇到过哪些K8s集群的‘玄学’故障?”我立刻回想起那次线下环境的“连环暴雷”场景:
Readiness/Liveness Probe Failed,报错Resource temporarily unavailable。runtime: failed to create new OS thread,并建议调整ulimit -u。面试官追问:“第一反应是什么排查方向?”我回答:“资源限制——线程、进程数、内核参数,但需要数据支撑。”
container_threads指标发现,故障节点的容器总线程数飙升至46k,远超日常基线。ulimit -u显示单用户限制为204k,看似安全,但忽略了一个关键参数——全局PID上限(/proc/sys/kernel/pid_max)仅49k!而46k容器线程+其他系统进程已突破此阈值。pid_max耗尽时,任何新建进程(包括探针)均会失败,这正是Calico探针报错的根源。面试官点头:“很多人会误以为是ulimit问题,但忽略了全局限制。你是如何想到PID的?”我答:“日志中的fatal error: newosproc提示了进程创建失败,而Prometheus线程监控锁定了泄漏源头。”
sysctl -w kernel.pid_max=262144,缓解进程创建阻塞。--collector.processes,监控node_processes_threads并设置阈值告警(如>80%触发)。kubelet --pod-max-pids),避免单Pod耗尽资源。pid_max和threads-max,避免硬编码默认值。这次故障教会我几个关键原则:
面试官最终评价:“故障不可怕,可怕的是重复踩坑。你的复盘逻辑和预防措施,体现了SRE的核心价值。”
kubectl describe/journalctl/PromQL三件套,熟练分析日志和指标。# 下期预告 《从一次502告警到内核参数调优:高并发场景下的TCP连接池泄漏实战》