第11章:Kubernetes 网络·存储·大文件排查专项手册
(生产环境疑难问题处理全指南)
章节目标
- 掌握 网络排查的系统路径与命令组合
- 掌握 存储性能与I/O异常诊断思路
- 掌握 大文件定位、清理与磁盘占用分析技巧
- 理解如何从 Linux层 → K8s层 → 容器层 → 应用层 一步步定位问题
- 给出实战模板与常用脚本,让你上线后遇到任何"莫名其妙慢、写不动、网络挂"的问题都能从容处理
生产排障三大方向导图
Kubernetes生产排障三大方向
├── 网络问题:CNI / DNS / Service / MTU
│ └── ping/nslookup/tcpdump/iptables
├── 存储问题:PVC/PV/StorageClass/OverlayFS
│ └── iostat/fio/lsof/mount
├── 磁盘问题:du/find/inode/journalctl
│ └── docker system prune / truncate
└── 自动化:脚本 + 监控 + 调优
└── Prometheus + 告警 + 自动修复
第一节:网络问题排查专项
一、典型问题场景
| 问题 | 常见现象 |
|---|---|
| Pod 无法访问外网 | 镜像拉取失败、curl 超时 |
| Pod 间通信失败 | Service 无响应、DNS 解析异常 |
| 请求延迟高 | TCP 重传多、丢包 |
| 端口冲突 | NodePort 无法绑定 |
| 跨节点不通 | overlay/VXLAN MTU 不匹配 |
二、排查路径
1️⃣ 从外到内分层检查
客户端 → Ingress → Service → Pod → 容器网络 → 宿主机网卡 → 物理网络
2️⃣ 关键命令体系
| 层级 | 命令 | 用途 |
|---|---|---|
| 容器 | kubectl exec -it pod -- ping 8.8.8.8 | 检查连通性 |
| Pod DNS | kubectl exec -it pod -- nslookup kubernetes.default | DNS 解析 |
| Service | kubectl get svc -o wide | 查看 ClusterIP |
| 节点网络 | ip a, ip route, ip link | 查看网卡与路由 |
| CNI | kubectl get pods -n kube-system -l k8s-app=calico-node | CNI 状态 |
| TCP | ss -tnlp、netstat -s | TCP连接与统计 |
| 丢包分析 | mtr, ping -M do -s 1472 | 延迟与MTU |
| 抓包 | tcpdump -i eth0 port 80 -w dump.pcap | 包级分析 |
3️⃣ 常见根因与解决
| 症状 | 可能原因 | 解决方式 |
|---|---|---|
| ping 8.8.8.8 不通 | node 没网 / CNI 坏 | 重启 CNI DaemonSet |
| nslookup 失败 | CoreDNS 挂了 | kubectl get pods -n kube-system |
| 同 node 不通 | iptables/nftables 拦截 | iptables -L -n |
| 跨 node 不通 | VXLAN MTU 问题 | 调整 MTU=1450 |
| 外部访问超时 | NodePort 未暴露 | 检查防火墙与 kubectl get svc |
| 内网访问慢 | TCP 重传多 | 调整 net.ipv4.tcp_tw_reuse=1 |
4️⃣ 网络延迟快速定位模板
# 延迟曲线
ping -c 10 10.0.0.8
# 丢包追踪
mtr 10.0.0.8
# 抓包看三次握手
tcpdump -i eth0 tcp port 80 -w /tmp/handshake.pcap
# 分析握手延迟
wireshark -> Statistics -> TCP Stream Graph
5️⃣ CNI 内部机制深度排查
Calico 排查:
# 查看 BGP 状态
calicoctl node status
# 查看路由表
calicoctl get bgpPeer
# 检查 BPF 程序
bpftool map show | grep calico
# 查看 VXLAN 接口
ip link show type vxlan
Flannel 排查:
# 查看 VXLAN 接口
ip link show flannel.1
# 检查路由表
ip route show | grep flannel
# 查看 flannel 配置
cat /etc/cni/net.d/10-flannel.conflist
6️⃣ DNS 延迟/缓存分析
# 查看 CoreDNS 日志
kubectl -n kube-system logs -f coredns --tail 50
# 详细 DNS 解析追踪
kubectl exec -it <pod> -- dig +trace kubernetes.default.svc.cluster.local
# 检查 DNS 缓存
kubectl exec -it <pod> -- nslookup kubernetes.default
# 分析 DNS 延迟
time kubectl exec -it <pod> -- nslookup kubernetes.default
7️⃣ Service 负载分布验证
# 查看 Endpoints 分布
kubectl get endpoints <service-name>
# 检查 iptables 规则
iptables-save | grep <service-name>
# 验证负载均衡
for i in {1..10}; do kubectl exec -it <pod> -- curl <service-ip>; done
8️⃣ 网络瓶颈压测
# 带宽测试
iperf3 -c <target-pod-ip> -t 30
# HTTP 压测
wrk -t8 -c200 -d30s http://<service-ip>
# 延迟测试
ping -c 100 <target-ip> | grep "time=" | awk '{print $7}' | cut -d= -f2 | sort -n
第二节:存储问题排查专项
一、常见现象
| 类型 | 表现 |
|---|---|
| PVC Pending | 无可用 PV 或 StorageClass |
| Pod 卡在 ContainerCreating | 挂载失败 |
| 文件系统只读 | NFS 权限问题 |
| 读写慢 | 后端 I/O 瓶颈 |
| 数据丢失 | Pod 重建未挂载 PVC |
二、排查路径
Pod → PVC → PV → StorageClass → 节点 → 存储后端
1️⃣ PVC 状态
kubectl get pvc
kubectl describe pvc <name>
2️⃣ 检查 PV 绑定
kubectl get pv
kubectl describe pv <pv-name>
3️⃣ 节点挂载状态
mount | grep nfs
df -h
lsblk
4️⃣ 后端 I/O 检查
iostat -x 1
pidstat -d 1
fio --rw=randwrite --bs=4k --size=1G --numjobs=4 --name=bench
三、典型故障与解决
| 问题 | 原因 | 解决方式 |
|---|---|---|
| PVC 一直 Pending | StorageClass 不存在 | 检查 storageClassName |
| Pod ContainerCreating 卡死 | nfs mount 无响应 | 重启 kubelet |
| 写入速度慢 | IOPS 不足 | 升级盘型 / 调整存储 QoS |
| 文件只读 | NFS 权限 755 | 挂载参数 nolock,rw |
| 数据丢失 | Pod 未使用 PVC | 改用持久卷挂载 |
四、性能排查技巧
1️⃣ I/O 类型识别
iostat -x 1
看 await > 50ms 表示磁盘延迟大。
随机写多时优化:
fio --rw=randwrite --bs=4k --iodepth=32 --name=test --runtime=30
2️⃣ 文件系统层分析
df -h
du -sh /var/lib/containerd/*
lsof | grep deleted
👉 检查"被删除但仍占空间"的文件(logrotate 常见)。
五、存储调优方向
| 优化项 | 建议 |
|---|---|
| IOPS 提升 | SSD / NVMe 优先 |
| 网络挂载 | NFS → Ceph |
| 写放大 | 调整块大小 |
| overlayfs | 避免大量小文件写入 |
| PV 策略 | reclaimPolicy: Retain 防止误删 |
六、Kubelet 挂载路径排查
# 查看 kubelet 日志
journalctl -u kubelet -f
# 检查挂载点
mount | grep kubelet
# 查看 Pod 挂载详情
kubectl describe pod <pod-name> | grep -A 10 "Mounts:"
七、CSI 插件问题定位
# 查看 CSI 驱动状态
kubectl get pods -n kube-system -l app=csi-*
# 检查 CSI 驱动日志
kubectl logs -n kube-system <csi-driver-pod>
# 查看 CSI 存储类
kubectl get storageclass -o yaml
# 检查 CSI 卷状态
kubectl get csinode
八、容器 overlayfs 性能诊断与优化
overlayfs 写入路径分析:
# 查看 overlay 层信息
cat /proc/mounts | grep overlay
# 检查 overlay 性能
fio --directory=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs --name=overlay-test --rw=randwrite --bs=4k --size=100M --numjobs=4
# 对比裸机性能
fio --directory=/tmp --name=bare-test --rw=randwrite --bs=4k --size=100M --numjobs=4
overlayfs 优化配置:
# 调整 overlay 参数
echo 'overlay.override_kernel_check=1' >> /etc/modprobe.d/overlay.conf
# 检查 CoW 影响
dmesg | grep -i overlay
九、文件系统一致性检查
# 检查文件系统错误
dmesg | grep -i "ext4\|xfs\|error"
# 强制文件系统检查
fsck -f /dev/sda1
# 检查 inode 使用率
df -i
第三节:大文件与磁盘占用排查专项
一、问题特征
| 症状 | 表现 |
|---|---|
| 磁盘满 | Pod 写日志失败、服务挂 |
| overlay 占满 | containerd 无法启动 |
| tmpfs 爆掉 | "no space left on device" |
| 日志暴涨 | 应用无限打印 debug |
二、排查命令体系
1️⃣ 查最大文件目录
du -sh /* | sort -hr | head -20
2️⃣ 查找特定类型
find / -type f -size +500M
3️⃣ 查看 overlayfs
du -sh /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/*
4️⃣ 删除"已删但仍占空间"的文件
lsof | grep deleted
kill -9 <pid>
5️⃣ 日志分析
journalctl --disk-usage
truncate -s 0 /var/log/messages
三、磁盘占用自动分析脚本
#!/bin/bash
echo "Top 15 biggest directories:"
du -h --max-depth=2 / | sort -hr | head -15
echo "Deleted but occupied files:"
lsof | grep deleted
echo "Containerd size:"
du -sh /var/lib/containerd
四、容器层快速释放空间方案
| 类型 | 操作 |
|---|---|
| 镜像层 | docker system prune -af |
| 日志层 | find /var/lib/docker/containers -name '*.log' -exec truncate -s 0 {} \; |
| OverlayFS | 清理 /var/lib/containerd/tmp |
| Pod 临时数据 | 删除 /var/lib/kubelet/pods/<uuid>/volumes/ |
五、inode 爆满排查
# 检查 inode 使用率
df -i
# 查找 inode 使用最多的目录
find / -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -n
# 清理小文件(谨慎操作)
find /tmp -type f -size 0 -delete
六、journalctl 无法清理处理
# 停止 journald 服务
systemctl stop systemd-journald
# 删除 journal 日志
rm -rf /var/log/journal/*
# 重启 journald
systemctl start systemd-journald
# 设置日志大小限制
echo "SystemMaxUse=1G" >> /etc/systemd/journald.conf
七、容器日志暴涨处理
Docker 日志轮转配置:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}
containerd 日志轮转:
# /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options.cgroup]
SystemdCgroup = true
第四节:专项实战案例
案例1:Pod 网络延迟高
现象:Pod 到外部 API 超时。
排查:
mtr检查丢包 → 发现中间路由 MTU 1460- Pod MTU 1500 → 调整为 1450
- 重启 calico → 延迟从 400ms 降到 60ms
案例2:PVC 写入异常慢
现象:数据库写入 TPS 下降 80%。
排查:
iostat -x→ await 高达 800ms- 检查发现 NFS over TCP
- 改为 NFS over RDMA
- I/O 延迟降至 40ms
案例3:磁盘满导致容器起不来
排查:
du -sh /var/lib/containerd/*
lsof | grep deleted
定位 /var/log/containers/app.log 仍被进程占用,执行:
kill -9 PID
后自动释放 18G 空间。
第五节:系统调优模板
一、内核参数调优
| 类别 | 参数 | 推荐值 | 说明 |
|---|---|---|---|
| 文件句柄 | ulimit -n | ≥ 1048576 | 防止"too many open files" |
| 网络 | net.core.somaxconn | 65535 | 提升连接队列 |
| TCP | net.ipv4.tcp_tw_reuse | 1 | 减少 TIME_WAIT |
| 磁盘调度 | /sys/block/sda/queue/scheduler | none | 禁用调度提高延迟 |
| IO queue | vm.dirty_ratio | 10 | 控制脏页比例 |
一键调优脚本:
#!/bin/bash
# 系统调优脚本
# 文件句柄
echo "* soft nofile 1048576" >> /etc/security/limits.conf
echo "* hard nofile 1048576" >> /etc/security/limits.conf
# 网络参数
cat >> /etc/sysctl.conf << EOF
net.core.somaxconn = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 10
net.core.netdev_max_backlog = 4096
net.ipv4.tcp_max_syn_backlog = 16384
EOF
# 磁盘调度
echo none > /sys/block/sda/queue/scheduler
# 应用配置
sysctl -p
二、容器日志轮转配置
Docker 全局配置:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=1"
]
}
Kubernetes 日志轮转:
apiVersion: v1
kind: ConfigMap
metadata:
name: kubelet-config
data:
kubelet: |
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
containerLogMaxSize: 100Mi
containerLogMaxFiles: 3
第六节:诊断自动化与监控
一、自动化诊断脚本
增强版诊断脚本:
#!/bin/bash
# k8s-diagnose-advanced.sh
LOG_DIR="/var/log/k8s-diagnose"
mkdir -p $LOG_DIR
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
LOG_FILE="$LOG_DIR/diagnose-$TIMESTAMP.log"
exec > >(tee -a $LOG_FILE)
exec 2>&1
echo "====[ Kubernetes 集群诊断报告 - $TIMESTAMP ]===="
# 1. 集群基本信息
echo "====[ Cluster Info ]===="
kubectl cluster-info
kubectl get nodes -o wide
kubectl get pods -A --field-selector=status.phase!=Running
# 2. 网络诊断
echo "====[ Network Diagnosis ]===="
# CNI 状态
kubectl get pods -n kube-system -l k8s-app=calico-node
kubectl get pods -n kube-system -l k8s-app=flannel
# DNS 测试
kubectl run test-dns --image=busybox --rm -it --restart=Never -- nslookup kubernetes.default
# 3. 存储诊断
echo "====[ Storage Diagnosis ]===="
kubectl get pv,pvc,sc
df -h
iostat -x 1 3
# 4. 资源使用
echo "====[ Resource Usage ]===="
kubectl top nodes
kubectl top pods -A
# 5. 事件分析
echo "====[ Recent Events ]===="
kubectl get events --sort-by=.lastTimestamp | tail -20
# 6. 系统状态
echo "====[ System Status ]===="
uptime
free -h
df -h
ss -tuln | wc -l
echo "诊断完成,日志保存在: $LOG_FILE"
二、Prometheus 告警规则
网络告警:
groups:
- name: kubernetes.network
rules:
- alert: NetworkLatencyHigh
expr: histogram_quantile(0.95, rate(container_network_receive_bytes_total[5m])) > 1000000
for: 5m
labels:
severity: warning
annotations:
summary: "Network latency high on {{ $labels.instance }}"
- alert: DNSResolutionSlow
expr: histogram_quantile(0.95, coredns_dns_request_duration_seconds) > 1
for: 5m
labels:
severity: critical
annotations:
summary: "DNS resolution slow: {{ $value }}s"
存储告警:
groups:
- name: kubernetes.storage
rules:
- alert: DiskIOLatencyHigh
expr: node_disk_io_time_seconds_total > 0.9
for: 5m
labels:
severity: critical
annotations:
summary: "Node I/O utilization high (>90%) on {{ $labels.instance }}"
- alert: PVCNotBound
expr: kubelet_volume_stats_available_bytes == 0
for: 10m
labels:
severity: warning
annotations:
summary: "PVC not bound: {{ $labels.persistentvolumeclaim }}"
三、自动修复脚本
磁盘空间自动清理:
#!/bin/bash
# auto-cleanup.sh
THRESHOLD=85
CURRENT_USAGE=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $CURRENT_USAGE -gt $THRESHOLD ]; then
echo "磁盘使用率超过 $THRESHOLD%,开始清理..."
# 清理容器日志
find /var/lib/docker/containers -name "*.log" -exec truncate -s 0 {} \;
# 清理 overlay 层
docker system prune -af
# 清理 journal 日志
journalctl --vacuum-time=3d
echo "清理完成"
fi
第七节:总结与思维导图
问题排查全景
Kubernetes生产排障全景
├── 网络问题
│ ├── 基础连通性
│ │ ├── ping/nslookup/mtr/tcpdump
│ │ └── DNS/Service/Pod链路
│ ├── CNI深度排查
│ │ ├── Calico BGP/BPF 状态
│ │ ├── Flannel VXLAN 配置
│ │ └── Cilium eBPF 程序
│ └── 性能压测
│ ├── iperf3 带宽测试
│ ├── wrk HTTP 压测
│ └── 延迟分析
├── 存储问题
│ ├── 基础存储
│ │ ├── PVC/PV/StorageClass
│ │ ├── CSI 驱动状态
│ │ └── Kubelet 挂载日志
│ ├── 性能分析
│ │ ├── iostat/fio 测试
│ │ ├── overlayfs 性能对比
│ │ └── 文件系统一致性
│ └── 故障处理
│ ├── 挂载失败排查
│ ├── I/O 延迟分析
│ └── 数据一致性检查
├── 磁盘问题
│ ├── 空间占用
│ │ ├── du/find/lsof 分析
│ │ ├── inode 使用率检查
│ │ └── 大文件定位
│ ├── 日志管理
│ │ ├── journalctl 清理
│ │ ├── 容器日志轮转
│ │ └── 系统日志配置
│ └── 自动清理
│ ├── 定时清理脚本
│ ├── 阈值告警
│ └── 预防性维护
└── 自动化运维
├── 诊断脚本
│ ├── 一键诊断工具
│ ├── 日志收集分析
│ └── 报告生成
├── 监控告警
│ ├── Prometheus 指标
│ ├── Grafana 可视化
│ └── AlertManager 告警
└── 自动修复
├── 磁盘空间清理
├── 服务自动重启
└── 配置自动优化
到这里你掌握了
基础排查能力:
- 网络全链路排查方法(CNI / MTU / Service / Pod)
- 存储性能诊断(I/O / PVC / overlayfs)
- 磁盘爆满与大文件处理
- 容器清理与恢复策略
深度技术能力:
- CNI 内部机制(Calico BGP、Flannel VXLAN、Cilium eBPF)
- CSI 驱动生命周期管理
- overlayfs 性能优化与 CoW 机制
- 内核参数调优与系统性能优化
生产运维能力:
- 自动化诊断脚本编写
- Prometheus 监控告警配置
- 自动修复与预防性维护
- 企业级故障处理流程
专家级技能:
- 从表象到根因的系统性分析
- 多层级(应用→容器→节点→集群)问题定位
- 性能瓶颈的量化分析与优化
- 生产环境稳定性保障策略
进阶方向
掌握了基础排查能力后,可以进一步学习:
第12章:Kubernetes + AI 工作负载优化
- GPU 调度与共享机制
- Pod GPU 分配策略
- AI 训练 I/O 加速(RDMA + NVLink)
- 大规模推理集群优化
监控体系:Prometheus + Grafana + AlertManager
自动化运维:Ansible + Terraform + GitOps
安全加固:NetworkPolicy + PodSecurityPolicy + RBAC
本章节内容基于生产环境真实案例整理,建议结合实际环境进行实践验证。