本文目录导读:

- 第一阶段:确认基础网络连通性
- 第二阶段:检查 DNS 解析(Service 通信)
- 第三阶段:检查网络策略(NetworkPolicy)
- 第四阶段:检查防火墙与安全组(云环境/物理机)
- 第五阶段:检查 CNI 插件(Kubernetes 网络插件)
- 第六阶段:应用层与服务监听
- 第七阶段:特殊场景排查
- 总结快速排查流程图
容器间互通异常是 Kubernetes 及 Docker 环境中非常常见的问题,排查思路通常遵循 “从外到内,逐层剥离” 的原则:先看网络层,再看策略层,最后看应用层。
以下是一套系统化的排查步骤和常用命令:
第一阶段:确认基础网络连通性
确认容器是否在同一个网络栈
-
场景: 两个容器在同一个 Pod 中(共享网络命名空间)。
- 排查: 直接使用
localhost通信,如果不行,检查容器内服务是否监听在0.0.1而非0.0.0。 - 命令:
# 进入 Pod 中的一个容器 kubectl exec -it <pod-name> -c <container-1> -- sh # 尝试访问另一个容器的端口(使用 localhost) curl localhost:<port>
- 排查: 直接使用
-
场景: 两个容器在不同 Pod 中(通过 Service 或 Pod IP 通信)。
- 排查: 确认 Pod IP 是否可达。
- 命令:
# 获取目标 Pod IP kubectl get pod <target-pod> -o wide # 从源 Pod 尝试 ping 目标 Pod IP(很多镜像默认无 ping 命令,可用 telnet 或 curl) kubectl exec -it <source-pod> -- ping <target-pod-ip> kubectl exec -it <source-pod> -- curl -v <target-pod-ip>:<port>
使用 kubectl run 创建一个临时调试 Pod
如果你的业务容器里没有 ping、curl、telnet、nc 等工具(比如基于 scratch 或 distroless 镜像),这是最有效的方法。
# 创建一个网络调试工具 Pod(如 nicolaka/netshoot) kubectl run tmp-shell --rm -it --image nicolaka/netshoot -- /bin/bash # 在调试 Pod 中测试与目标 Pod 的连通性 curl http://<service-name>.<namespace>.svc.cluster.local:<port> ping <target-pod-ip> nslookup <service-name>
第二阶段:检查 DNS 解析(Service 通信)
如果使用 Service 名称(而非 Pod IP)通信,DNS 问题是常见原因。
-
排查点: 域名能否解析?解析出的 Cluster IP 是否正确?
-
命令:
# 在任意 Pod 内 nslookup <service-name>.<namespace>.svc.cluster.local # nslookup 不可用,尝试 host <service-name> cat /etc/resolv.conf # 确认 nameserver 指向正确的 DNS Pod(通常是 kube-dns 的 Cluster IP)
-
可能原因:
- DNS Pod 宕机(
kubectl get pods -n kube-system | grep dns)。 - Pod 的
dnsPolicy设置错误(如Default或None)。 - CoreDNS 配置问题。
- DNS Pod 宕机(
第三阶段:检查网络策略(NetworkPolicy)
这是 Kubernetes 中最容易忽略的“隐形防火墙”。
-
排查点: 是否有 NetworkPolicy 限制了源 Pod 或命名空间访问目标 Pod 的端口。
-
命令:
# 查看目标 Pod 所在命名空间的 NetworkPolicy kubectl get networkpolicy -n <namespace> kubectl describe networkpolicy <policy-name> -n <namespace>
-
快速验证: 如果权限允许,可以尝试临时关闭 NetworkPolicy(创建一个允许所有流量的策略)或在没有 NetworkPolicy 的命名空间中测试。
第四阶段:检查防火墙与安全组(云环境/物理机)
如果是在云平台(AWS、阿里云、GCP)或物理机上部署,外部网络限制可能会影响容器。
- 排查点:
- 节点安全组: 节点之间的安全组规则是否允许节点上的 Pod CIDR 流量互通?某些云平台默认禁止非 VPC 内部流量。
- iptables/ebtables: 节点上的
iptables规则是否被其他工具(如 Docker、Calico、Flannel)错误修改。 - 命令(在 K8s 节点上):
# 查看 iptables 过滤表 iptables -L -n -v # 查看 NAT 表(K8s 通过 iptables 实现 Service 负载均衡) iptables -t nat -L -n -v | grep <service-name> # 如果是 Calico,检查 Felix 规则 calicoctl get policy
第五阶段:检查 CNI 插件(Kubernetes 网络插件)
CNI 负责分配 IP 和设置网络。
-
常见问题:
- IP 冲突: 两个 Pod 被分配了相同的 IP。
- 路由缺失: 节点上的路由表未正确配置。
- Overlay 隧道故障: 如 VXLAN、Geneve 隧道断开。
-
命令(在节点上):
# 检查路由表,确认目标 Pod CIDR 指向正确的网关(通常是 Cilium/Calico 的接口) route -n ip route # 检查 CNI 插件日志(Calico) journalctl -u kubelet -f | grep -i cni # 查看 Calico 的 felix 日志 journalctl -u calico-node
第六阶段:应用层与服务监听
如果网络层面完全通,但业务返回错误(如 502、Connection Refused、超时),问题在应用本身。
-
排查点:
- 服务监听地址: 容器内进程是否监听了
0.0.0或 ?如果只监听0.0.1,外部(包括其他 Pod)无法访问。 - 端口映射: Service 定义的
targetPort是否与容器内进程监听的端口一致? - 健康检查: Pod 是否处于
Running状态且Ready条件为True? - 容器内进程启动时间: 进程启动慢导致端口尚未开放。
- 服务监听地址: 容器内进程是否监听了
-
命令:
# 确认 Pod 就绪 kubectl get pod <target-pod> -w # 查看容器日志 kubectl logs <target-pod> <container-name> # 进入容器,检查端口监听状态(需要进程权限) kubectl exec -it <target-pod> -- netstat -tunlp # 或 kubectl exec -it <target-pod> -- ss -tunlp
第七阶段:特殊场景排查
场景 A:Pod 启动后短暂可通,随后异常
- 原因: 通常是 网络策略 或 istio(服务网格)在 Pod Ready 后动态注入了 Sidecar(如 Envoy),并锁定了网络规则。
- 查看:
kubectl get pod <pod-name> -o yaml,观察是否有istio-proxy等 sidecar 容器以及initContainers的网络设置。
场景 B:跨节点通信不通,同节点通信正常
- 原因: 节点间网络(Node Network)不通,或 CNI 的路由未在所有节点上同步。
- 排查: 在节点上用
ping或traceroute测试另一个节点的 Pod CIDR 网段。
场景 C:不同命名空间通信异常
- 原因: 最可能的是 NetworkPolicy(默认隔离)或 全局策略。
- 验证: 使用
curl时带上完整的 FQDN:<service>.<namespace>.svc.cluster.local。
总结快速排查流程图
[问题:A 无法访问 B]
|
v
1. A 能 ping 通 B 的 Pod IP 吗?
|
(是) <---> (否) --> 检查节点路由表、CNI 插件、安全组、节点间网络
|
v
2. DNS 解析 Service 名正确吗?
|
(是) <---> (否) --> 检查 CoreDNS、resolv.conf、FQDN 拼写
|
v
3. A 尝试 curl B 的端口,连接错误?
|
(Connection Refused) --> B 的服务是否监听在 0.0.0.0? targetPort 是否正确?
|
(Connection Timeout) --> 检查 NetworkPolicy、云安全组、iptables 规则
|
(HTTP 4xx/5xx) --> 业务应用层问题,检查日志和配置
最后建议: 当排查陷入僵局时,最有效的方法是 构造一个最小可复现环境(一个测试命名空间,一个测试 Pod,一个简单的 nginx 镜像),然后逐步还原生产环境的配置(如添加 NetworkPolicy、Istio 注入),看哪一步导致异常。