Kubernetes Pod 资源争用排查实战

最近遇到一个线上问题:部署在 K8s 集群里的几个微服务,每到流量高峰期就出现偶发性超时,但监控面板上的 CPU 和内存指标都在正常范围内。排查了一圈,发现问题出在 Pod 之间的资源争用上。这篇文章记录一下完整的排查过程和思路。

 

## 症状

 

现象很诡异:Pod A 和 Pod B 调度在同一台 Node 上,A 是 CPU 密集型(数据处理),B 是 IO 密集型(网关转发)。高峰期 B 的 P99 延迟从 50ms 飙升到 2s,但 B 的 CPU 使用率只有 30%。单独看每个 Pod 的指标都很健康。

 

## 排查步骤

 

### 1. 确认 Pod 分布

 

先看这些 Pod 跑在哪里:

 

```bash

kubectl get pods -n production -o wide | grep -E "service-a|gateway-b"

```

 

发现 A 和 B 确实在同一台 Node 上。初步怀疑是"吵闹邻居"问题。

 

### 2. 查看 Node 层面指标

 

Pod 级别的 metrics 正常不代表 Node 级别没问题:

 

```bash

kubectl top node worker-node-3

```

 

Node CPU 到了 85%,但还没触发驱逐阈值。关键是看 CPU throttling:

 

```bash

kubectl top pod --containers -n production | grep gateway-b

```

 

果然,B 的容器虽然在 requests/limits 范围内,但 /sys/fs/cgroup/cpu.stat 里的 nr_throttled 计数器在快速增长。这说明容器被 Linux CFS 频繁限流了。

 

### 3. 检查 CPU 限流详情

 

用 cadvisor 暴露的 metrics 或者直接进 Node 查看 cgroup:

 

```bash

cat /sys/fs/cgroup/cpu/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod<uid>.slice/cpu.stat

```

 

也可以用 Prometheus 查:

 

```promql

rate(container_cpu_cfs_throttled_seconds_total{pod=~"gateway-b.*"}[5m])

```

 

### 4. 根因分析

 

问题链条是这样的:

 

- Pod A 配置了 CPU limit = 2 核,但实际是批处理任务,CPU 使用总是顶着 2 核跑

- Node 有 8 核,总共 7 个 Pod,sum(limits) 接近 8 核

- Linux CFS 给每个 cgroup 分配的时间片是按比例分配的,当核心被多个 cgroup 竞争时,IO 密集型的 B 即使 CPU 需求很小,也会因为 CFS 的公平调度而得不到及时响应

- B 的请求需要快速处理,但如果恰好在 A 抢占 CPU 的时间窗口内到达,B 的线程就得排队等调度

 

### 5. 解决方案

 

短期——打散 Pod 分布,加反亲和:

 

```yaml

affinity:

  podAntiAffinity:

    preferredDuringSchedulingIgnoredDuringExecution:

    - weight: 100

      podAffinityTerm:

        labelSelector:

          matchLabels:

            app: service-a

        topologyKey: kubernetes.io/hostname

```

 

中长期——合理设置 requests 和 limits:

 

```yaml

resources:

  requests:

    cpu: "500m"

    memory: "512Mi"

  limits:

    cpu: "1000m"

    memory: "1Gi"

```

 

关键点:requests 用于调度决策,limits 用于 CFS 限流。IO 密集型服务不要设太低 requests。

 

### 6. 效果验证

 

```bash

echo "GET http://gateway-b/api/health" | vegeta attack -duration=30s -rate=100 | vegeta report

```

 

修复前 P99 2340ms → 修复后 P99 78ms。

 

## 总结

 

- 不要只看 Pod 层面的指标,Node 层的 CPU throttling 同样重要

- CPU limits 对 IO 密集型服务可能适得其反

- 请求用 request 做软规划,用 limit 做硬限制

- 监控里加 container_cpu_cfs_throttled_seconds_tota

posted @ 2026-06-09 21:05  fitch_liu  阅读(3)  评论(0)    收藏  举报