第一案:Pod集体自杀
凌晨12点的告警总是格外刺眼。值班群里突然炸出一连串消息:"支付服务全部下线!但Pod日志显示一切正常!"运维组赶到战场时,发现大量Pod像多米诺骨牌般接连消失,监控面板上却全是绿色对勾。
错误排查:
bash
# 查看案发时间线
kubectl get events --sort-by='.lastTimestamp' | grep -i killed
# 查看Pod详细信息
kubectl describe pod ${victim_pod} | grep -A10 'State'
找出问题:
- kubelet的内存压力驱逐就像隐形的刽子手,执行后不留痕迹在Pod日志中
- 某个异常的Deployment控制器像失控的流水线,不断重建相同的缺陷Pod
- 某些Pod悄悄吞噬共享节点的临时存储,触发"隐形"驱逐条件
解决问题:
bash
# 紧急止血:提高驱逐阈值
sudo sed -i 's/memory.available<100Mi/memory.available<50Mi/' /var/lib/kubelet/config.yaml
systemctl restart kubelet
# 错误现场重建
kubectl top pod --containers | sort -k3 -nr
# 给资源上枷锁
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- resources:
limits:
memory: "1.5Gi" # 比实际用量多30%的安全垫
第二案:未做好资源控制导致Pod死亡
之前跟着老师傅维护过一个商城的项目
当秒杀按钮亮起的瞬间,监控面板突然变成血色。订单支付Pod像被猎杀般接连倒下,kubelet的驱逐计数器疯狂跳动,内存曲线直插监控面板的天花板。
灾难时间线还原:
# 查看大屠杀记录
kubectl get pods -A -o json | jq '.items[] | select(.status.reason=="Evicted")'
# 追溯资源凶器
kubectl describe node ${node_name} | grep -C5 'MemoryPressure'
紧急处理方法:
- 给Pod加内存:
bash
# 紧急扩容(内存)
kubectl set resources deployment/order-service --limits=memory=2Gi
# 优先保障VIP
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: flashsale-critical
value: 1000000 # 优先级拉满
2.配置HPA
bash
# 配置HPA自动弹射
kubectl autoscale deployment payment-gateway --cpu-percent=60 --min=5 --max=30
# 扩张Pod
gcloud container clusters update $CLUSTER_NAME \
--enable-autoscaling \
--min-nodes=10 \
--max-nodes=100
灾后重建备忘录:
- 在测试环境用Chaos Mesh模拟内存风暴
- 像布置消防通道一样配置PodDisruptionBudget
第三案:广告投放系统的Pod驱逐危机
背景:广告系统遭遇流量洪峰
某中型互联网广告平台在某次大型营销活动期间,广告投放服务突发大规模Pod驱逐事件,导致广告延迟、投放失败率激增,直接影响广告收入。
故障现象
-
Pod频繁重启
广告投放服务Pod进入
Evicted
状态,每分钟驱逐3-5个Pod。 -
节点资源耗尽
多个Worker节点的内存使用率超过95%,kubelet日志持续输出
MemoryPressure
警告。 -
监控告警
- Prometheus触发
node_memory_available_bytes < 10%
告警。 - Grafana面板显示部分节点的
kubelet_evictions
指标飙升。
- Prometheus触发
-
业务影响
广告延迟从平均200ms上升至1.5秒,广告投放失败率从0.5%上升至10%,直接影响广告收入。
根因分析
-
资源配额设置不合理
广告投放服务Pod未设置内存资源限制,导致Pod内存使用无节制,最终触发kubelet的内存驱逐机制。
-
驱逐策略过于激进
k kubelet的内存驱逐阈值设置过低,导致在内存使用率超过90%时就开始驱逐Pod。
-
监控盲区
未实时监控Pod内存使用情况,导致问题发现滞后。
-
服务依赖雪崩
广告投放服务依赖的缓存服务(Redis)出现性能瓶颈,导致广告投放服务Pod超时重试,进一步加剧内存压力。
解决方案
1. 资源配额优化
# 查看Pod内存使用情况
kubectl top pod --containers | sort -k3 -nr
# 设置内存限制和请求
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: ad投放服务
resources:
limits:
memory: "2Gi" # 实际峰值1.4Gi * 1.4
requests:
memory: "1.2Gi" # 保证调度基础
2. 调整kubelet驱逐策略
# 修改kubelet配置
sudo sed -i 's/memory.available<100Mi/memory.available<500Mi/' /var/lib/kubelet/config.yaml
systemctl restart kubelet
3. 增加监控和告警
# 配置Prometheus告警规则
- alert: HighMemoryUsage
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
annotations:
summary: "节点内存使用率过高 ({{ $labels.node }})"
4. 优化服务依赖
# 配置Redis高可用
spec:
clusterAffinity:
labelSelector:
matchLabels:
component: redis
resources:
requests:
memory: "4Gi"
limits:
memory: "6Gi"
总结
通过以上措施,广告投放服务的Pod驱逐问题得到了有效解决。建议在日常运维中,定期检查Pod资源配额和驱逐策略,确保系统在高负载情况下能够稳定运行。
写在最后
凌晨的机房,咖啡已经凉透。看着逐渐平稳的监控曲线,突然想起前辈的话:"K8s故障就像冰山,你看到的Pod异常只是露出水面的一角。" 下次大促前,或许我们该在资源限制里多留20%的缓冲,就像给代码写注释一样------不是为了当下,而是为了那个在深夜紧急处理故障的,未来的自己。