Kubernetes 网络故障排查实战指南
一、概述
Kubernetes 网络是容器化架构中最复杂也最容易出问题的部分。本文档基于实际运维经验,总结常见网络故障现象、排查方法和解决方案。
1.1 K8s 网络模型要求
- 所有 Pod 可以在不 NAT 的情况下相互通信
- 所有节点可以在不 NAT 的情况下与所有 Pod 通信
- Pod 看到的自身 IP 与实际通信 IP 一致
1.2 常见 CNI 插件对比
| CNI |
特点 |
适用场景 |
| Calico |
BGP 路由,性能好,支持 NetworkPolicy |
生产环境首选 |
| Flannel |
简单,VXLAN Overlay |
测试/小规模 |
| Cilium |
eBPF 高性能,可观测性强 |
高级用户 |
| Weave |
加密通信,简单易用 |
多集群互联 |
二、故障分类与排查流程
2.1 排查流程图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| 故障现象 │ ▼ ┌───────────────────┐ │ Pod 内网络是否正常?│ └─────────┬─────────┘ │ ┌─────┴─────┐ │ │ 是 否 │ │ ▼ ▼ ┌─────────┐ ┌─────────────┐ │Pod 间通信 │ │ CNI/节点网络 │ └────┬────┘ └──────┬──────┘ │ │ ▼ ▼ ┌─────────┐ ┌───────────┐ │Service │ │ 修复节点 │ │通信问题 │ │ 网络配置 │ └────┬────┘ └───────────┘ │ ▼ ┌─────────┐ │外部访问 │ │问题排查 │ └─────────┘
|
三、Pod 内部网络故障
3.1 故障现象
1 2 3 4 5 6 7 8 9 10 11
| kubectl exec -it <pod-name> -- bash
ping 127.0.0.1
nslookup kubernetes.default
curl -I https://www.baidu.com
|
3.2 常见原因与解决
问题 1:DNS 解析失败
1 2 3 4 5 6 7 8 9 10 11
| kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns
kubectl exec -it <pod> -- nslookup kubernetes.default
kubectl get configmap coredns -n kube-system -o yaml
|
解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| apiVersion: v1 kind: Pod metadata: name: dns-test spec: containers: - name: test image: busybox command: ["sleep", "3600"] dnsConfig: nameservers: - 8.8.8.8 - 114.114.114.114
|
问题 2:无法访问外网
1 2 3 4 5 6 7 8
| iptables -t nat -L POSTROUTING -n -v
cat /etc/cni/net.d/*.conf
kubectl exec -it <pod> -- ip route
|
常见原因:
- 节点防火墙阻止出站流量
- CNI 插件配置错误
- 网络策略(NetworkPolicy)限制
3.3 诊断工具 Pod
1 2 3 4 5 6 7 8 9 10 11 12 13
| apiVersion: v1 kind: Pod metadata: name: net-debug namespace: default spec: containers: - name: debug image: nicolaka/netshoot command: ["sleep", "3600"] securityContext: capabilities: add: ["NET_ADMIN"]
|
1 2 3 4 5 6 7 8 9 10
| kubectl apply -f net-debug.yaml
kubectl exec -it net-debug -- bash
tcpdump -i any -n port 80 curl -v http://<service-ip> mtr <pod-ip>
|
四、Pod 间通信故障
4.1 故障现象
- Pod A 无法 ping 通 Pod B
- 跨节点 Pod 通信失败
- 延迟高或丢包严重
4.2 排查步骤
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| kubectl get pods -o wide
kubectl exec -it <pod-A> -- ping <pod-B-IP>
kubectl exec -it <pod-A> -- ping <pod-C-IP>
kubectl get pods -n kube-system | grep -E "calico|flannel|cilium"
kubectl logs -n kube-system <cni-pod-name>
|
4.3 Calico 故障排查
1 2 3 4 5 6 7 8 9 10 11
| kubectl exec -it <calico-node> -n kube-system -- calicoctl node status
kubectl exec -it <calico-node> -n kube-system -- ip route
kubectl get felixconfigurations default -o yaml
kubectl rollout restart daemonset calico-node -n kube-system
|
4.4 Flannel 故障排查
1 2 3 4 5 6 7 8 9 10 11
| kubectl get configmap kube-flannel-cfg -n kube-system -o yaml
ip -d link show flannel.1
cat /run/flannel/subnet.env
kubectl rollout restart daemonset kube-flannel-ds -n kube-system
|
4.5 常见解决方案
方案 1:重置 CNI 配置
1 2 3 4 5 6 7 8 9
| kubectl delete pod -n kube-system -l k8s-app=calico-node
rm -rf /var/lib/cni/* rm -rf /var/lib/calico/*
systemctl restart kubelet
|
方案 2:检查 MTU 设置
1 2 3 4 5 6 7
| ip link show | grep mtu
kubectl patch felixconfigurations default \ --type='merge' \ -p '{"spec": {"mtu": 1450}}'
|
五、Service 通信故障
5.1 Service 类型回顾
| 类型 |
说明 |
使用场景 |
| ClusterIP |
集群内访问 |
内部服务 |
| NodePort |
节点端口暴露 |
测试/简单场景 |
| LoadBalancer |
云负载均衡 |
生产对外服务 |
| ExternalName |
DNS 别名 |
外部服务代理 |
5.2 ClusterIP 故障排查
1 2 3 4 5 6 7 8 9 10 11 12
| kubectl get svc <service-name> -o yaml
kubectl get endpoints <service-name>
kubectl get endpointslices -l kubernetes.io/service-name=<service-name>
kubectl get pods --show-labels kubectl get svc <service-name> -o jsonpath='{.spec.selector}'
|
问题:Endpoints 为空
1 2 3 4 5 6 7 8
|
kubectl get svc my-service -o jsonpath='{.spec.selector}'
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels}{"\n"}{end}'
|
问题:Service 无法访问
1 2 3 4 5 6 7 8 9 10 11
| curl <service-cluster-ip>:<port>
kubectl get pods -n kube-system -l k8s-app=kube-proxy
iptables-save | grep <service-ip>
kubectl logs -n kube-system <kube-proxy-pod>
|
5.3 NodePort 故障排查
1 2 3 4 5 6 7 8 9 10
| kubectl get svc
curl <node-ip>:<nodeport>
iptables -L INPUT -n -v | grep <nodeport>
|
5.4 LoadBalancer 故障排查
1 2 3 4 5 6 7 8 9 10
| kubectl get svc <service-name>
kubectl describe svc <service-name>
|
六、Ingress 故障排查
6.1 常见 Ingress 控制器
| 控制器 |
特点 |
| Nginx Ingress |
最常用,功能丰富 |
| Traefik |
配置简单,支持热更新 |
| HAProxy Ingress |
高性能 |
| Kong |
API 网关功能 |
6.2 排查流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| kubectl get pods -n ingress-nginx
kubectl get ingress <ingress-name> -o yaml
kubectl get svc <backend-service>
kubectl describe ingress <ingress-name>
nslookup <ingress-domain>
curl -H "Host: <domain>" <controller-ip>
|
6.3 常见问题
问题 1:404 Not Found
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
kubectl describe ingress <name>
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example spec: rules: - host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: my-service port: number: 80
|
问题 2:502 Bad Gateway
1 2 3 4 5 6 7
|
kubectl get endpoints <service-name> kubectl get pods -l app=<app-label>
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
|
问题 3:SSL/TLS 证书问题
1 2 3 4 5 6 7 8
| kubectl get secret <tls-secret> -o yaml
kubectl get secret <tls-secret> -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -text
kubectl create secret tls <secret-name> --cert=tls.crt --key=tls.key
|
七、NetworkPolicy 故障排查
7.1 检查策略
1 2 3 4 5 6 7 8
| kubectl get networkpolicies --all-namespaces
kubectl get networkpolicy <policy-name> -n <namespace> -o yaml
kubectl describe networkpolicy <policy-name> -n <namespace>
|
7.2 调试工具
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all namespace: default spec: podSelector: {} policyTypes: - Ingress - Egress ingress: - {} egress: - {}
|
1 2 3 4 5
| kubectl apply -f allow-all.yaml
|
7.3 策略调试技巧
1 2 3 4 5 6 7 8
| kubectl debug -it <pod> --image=nicolaka/netshoot
nc -zv <target-pod-ip> <port>
tcpdump -i any host <target-ip>
|
八、核心组件网络故障
8.1 API Server 无法访问
1 2 3 4 5 6 7 8 9 10 11
| kubectl get pods -n kube-system -l component=kube-apiserver
kubectl logs -n kube-system -l component=kube-apiserver
kubectl exec -it <etcd-pod> -n kube-system -- etcdctl endpoint health
kubectl get secret kubernetes -n default -o yaml
|
8.2 Kubelet 通信故障
1 2 3 4 5 6 7 8 9 10 11 12
| systemctl status kubelet
journalctl -u kubelet -f
ls -la /var/lib/kubelet/pki/
kubectl get nodes kubectl describe node <node-name>
|
8.3 CoreDNS 故障
1 2 3 4 5 6 7 8 9 10 11
| kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl get configmap coredns -n kube-system -o yaml
kubectl run -it --rm dns-test --image=busybox --restart=Never -- nslookup kubernetes.default
kubectl scale deployment coredns -n kube-system --replicas=3
|
九、性能问题排查
9.1 网络延迟高
1 2 3 4 5 6 7 8 9 10 11
| kubectl exec -it <pod-a> -- ping -c 10 <pod-b-ip>
kubectl exec -it <pod-a> -- mtr <pod-c-ip>
kubectl get networkpolicies --all-namespaces
kubectl top pods -n kube-system | grep -E "calico|cilium"
|
9.2 带宽不足
1 2 3 4 5 6 7 8
| kubectl exec -it <pod> -- iperf3 -c <target-ip>
ethtool <interface>
kubectl exec -it <calico-node> -n kube-system -- calicoctl node status
|
9.3 连接数限制
1 2 3 4 5 6 7 8 9
| cat /proc/sys/net/netfilter/nf_conntrack_count cat /proc/sys/net/netfilter/nf_conntrack_max
sysctl -w net.netfilter.nf_conntrack_max=1000000
echo "net.netfilter.nf_conntrack_max=1000000" >> /etc/sysctl.conf
|
十、自动化诊断脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| #!/bin/bash
NAMESPACE=${1:-default} POD_NAME=$2
echo "=== K8s 网络诊断报告 ===" echo "命名空间:$NAMESPACE" echo "目标 Pod: $POD_NAME" echo ""
echo "【1】Pod 基本信息" kubectl get pod $POD_NAME -n $NAMESPACE -o wide echo ""
echo "【2】NetworkPolicy" kubectl get networkpolicy -n $NAMESPACE echo ""
echo "【3】相关 Service" kubectl get svc -n $NAMESPACE echo ""
echo "【4】Endpoints" kubectl get endpoints -n $NAMESPACE echo ""
echo "【5】CNI 组件状态" kubectl get pods -n kube-system | grep -E "calico|flannel|cilium|kube-proxy" echo ""
echo "【6】DNS 测试" kubectl run dns-test-$RANDOM --rm -it --image=busybox --restart=Never \ -n $NAMESPACE -- nslookup kubernetes.default 2>/dev/null || echo "DNS 测试失败" echo ""
echo "【7】节点网络状态" kubectl get nodes -o wide echo ""
echo "=== 诊断完成 ==="
|
十一、最佳实践
11.1 预防性措施
监控网络指标
定期健康检查
1 2
| 0 */6 * * * /opt/scripts/k8s-network-check.sh
|
文档化网络拓扑
- 记录 CNI 配置
- 记录 NetworkPolicy 规则
- 记录 Service 依赖关系
11.2 故障响应流程
- 确认故障范围(单 Pod/单节点/全集群)
- 检查 CNI 组件状态
- 验证基础网络连通性
- 检查配置变更历史
- 查看相关日志
- 执行修复并验证
11.3 工具推荐
| 工具 |
用途 |
| kubectl-netshoot |
网络诊断容器 |
| netpol-analyzer |
NetworkPolicy 分析 |
| cilium-cli |
Cilium 诊断 |
| ksniff |
Pod 抓包 |
十二、参考资源
文档版本:1.0
最后更新:2026-03-11