容器网络先分段再排查
容器里不通,先分清是哪一段:容器到外部、宿主机到容器、还是容器之间。容器使用独立的网络命名空间,宿主机上的 ss 与 ip 结果不能代表容器内的状态,因此验证必须在正确的命名空间里做。Docker 默认的 bridge 网络路径是「容器 veth → docker0 网桥 → 宿主机路由与 NAT → 目标」,K8s 则在中间多了一层 CNI 与 Service 转发规则。
基本信息
| 四段路径 | 容器 veth → 网桥或 overlay → 宿主机路由/NAT → 目标网络 |
|---|---|
| 常用命令 | docker network inspect、ip -br a、iptables -t nat -L、nsenter -t <PID> -n |
| K8s 加查 | Service、Endpoints、kube-proxy 规则、CoreDNS |
| 权限要求 | 查看网桥与 NAT 规则需 root;操作容器需 docker 或 kubectl 权限 |
| 适用平台 | Docker 与 Kubernetes(容器运行时为 containerd 时思路相同) |
典型使用场景
- 容器内访问公网失败但宿主机正常:查 SNAT 与 ip_forward 是否生效
- 容器内域名解析失败但 IP 直连成功:查容器内 resolv.conf 与 DNS 服务
- 宿主机访问容器端口不通:确认端口映射与容器监听地址是否绑定 0.0.0.0
- K8s 集群内 Service 访问不通:先看 Endpoints 是否为空,再看 kube-proxy 规则
- 容器间互通异常:确认是否在同一网络,以及网桥上的防火墙规则
Docker 侧逐段验证
Docker 侧逐段验证
docker network ls && docker network inspect bridge | head -40 # 网络与网桥地址段
docker exec -it <容器> ping -c2 223.5.5.5 # 容器到公网,验证 SNAT
docker exec -it <容器> cat /etc/resolv.conf # 容器内 DNS 配置(常见坑)
ip -br a | grep -E 'docker|veth' # 宿主机侧网桥与 veth
sudo iptables -t nat -L POSTROUTING -n -v | head # MASQUERADE 是否命中
sudo nsenter -t $(docker inspect -f '{{.State.Pid}}' <容器>) -n ip -br a # 进入容器命名空间看网卡K8s 服务不通快速打点
K8s 服务不通快速打点
kubectl get pods -o wide # 看 Pod IP 与所在节点
kubectl get endpoints <svc> # Endpoints 为空 → 选择器或就绪探针问题
kubectl exec -it <pod> -- nslookup <svc>.<ns>.svc.cluster.local
kubectl exec -it <pod> -- nc -zv <svc> <port> # 直接验证端口连通性
kubectl describe svc <svc> | head -20 # 核对端口与 TargetPort 映射现象与指向对照
| 现象 | 指向 | 下一步 |
|---|---|---|
| 容器内 IP 直连成功、域名失败 | 容器 DNS 配置或 CoreDNS | 查 resolv.conf 与 DNS Service 的 Endpoints |
| 容器出公网失败、宿主机正常 | SNAT 规则或 ip_forward | 核对 iptables -t nat 命中计数与转发开关 |
| 宿主机访问映射端口不通 | 容器监听地址或端口映射 | 确认服务绑定 0.0.0.0 且映射端口一致 |
| Service 访问不通但 Pod IP 可达 | Endpoints 或 kube-proxy 规则 | 先确认 Endpoints 非空,再查转发规则 |
| 容器间互通失败 | 网络隔离或网桥防火墙 | 确认是否同网络,检查网桥上的规则 |
经典的边界判据:容器内能解析但连不上,先怀疑路由或 NAT;容器内连 IP 都通、只有域名失败,几乎可以锁定在 DNS 配置这一段。