一、先看看容器能不能上网

首先咱们得确认容器到底能不能访问外部网络。就像家里WiFi连不上,第一步肯定是看看手机能不能打开网页对吧?

# 技术栈:Docker
# 进入容器内部执行ping测试
docker exec -it my_container ping www.baidu.com

# 如果返回类似下面的结果,说明网络正常
# 64 bytes from 183.2.172.185: icmp_seq=1 ttl=50 time=25.3 ms

# 如果出现"unknown host"错误,说明DNS解析有问题
# ping: bad address 'www.baidu.com'

如果发现ping不通,别着急,咱们继续往下排查。这里有个小技巧:可以先用docker network ls看看有哪些可用网络,再用docker network inspect bridge查看默认网络的详细配置。

二、检查容器之间的通信

有时候容器能上网但是互相访问不了,这就好比家里所有手机都能上网,但两部手机之间不能传文件。这种情况在微服务架构中特别常见。

# 技术栈:Docker
# 创建两个测试容器
docker run -d --name container1 alpine sleep 3600
docker run -d --name container2 alpine sleep 3600

# 查看它们的IP地址
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container1
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container2

# 从一个容器ping另一个容器
docker exec -it container1 ping <container2的IP>

如果发现容器间无法通信,可能是这几个原因:

  1. 容器不在同一个Docker网络上
  2. 防火墙规则阻止了通信
  3. 容器使用了host网络模式但端口冲突

三、端口映射问题排查

端口映射就像快递柜,外部的请求需要通过宿主机的端口转发到容器的端口。这里最容易出问题。

# 技术栈:Docker
# 启动一个Nginx容器并映射端口
docker run -d --name web -p 8080:80 nginx

# 检查端口映射是否生效
# 在宿主机上执行
curl http://localhost:8080

# 如果返回Nginx欢迎页说明正常
# 如果连接被拒绝,可能是:
# 1. 容器内的服务没真正启动
# 2. 端口映射写错了(比如把8080:80写成8080:8080)

有个常见误区:很多人以为-p 8080:80就是把宿主机的8080映射到容器的80,其实左边是宿主机端口,右边是容器端口,千万别搞反了。

四、DNS解析问题处理

DNS问题就像手机通讯录坏了,你知道朋友的名字但找不到电话号码。容器里的应用经常遇到这类问题。

# 技术栈:Docker
# 进入容器查看DNS配置
docker exec -it my_container cat /etc/resolv.conf

# 正常情况下应该看到Docker的DNS服务器
# nameserver 127.0.0.11
# options ndots:0

# 如果发现DNS配置不对,可以这样启动容器指定DNS
docker run --dns 8.8.8.8 --dns 8.8.4.4 my_image

有时候公司内网有特殊DNS要求,这时候就需要自定义DNS配置。可以在docker daemon的配置文件中设置,或者直接给容器运行时指定--dns参数。

五、网络模式选择的影响

Docker提供了多种网络模式,就像手机有飞行模式、省电模式等不同选择,用错了模式就会导致网络异常。

# 技术栈:Docker
# 查看容器使用的网络模式
docker inspect -f '{{.HostConfig.NetworkMode}}' my_container

# 常见的网络模式:
# bridge - 默认的桥接网络
# host - 直接使用宿主机网络
# none - 完全没有网络
# overlay - 用于Swarm集群

# 比如使用host模式启动容器
docker run --network host my_image

选择网络模式时要特别注意:

  1. bridge模式适合大多数单机场景
  2. host模式性能更好但端口容易冲突
  3. overlay模式用于多主机通信

六、防火墙和SELinux的影响

防火墙就像小区的门禁系统,有时候会误拦正常的网络访问。

# 技术栈:Linux + Docker
# 检查防火墙规则
sudo iptables -L -n

# 临时关闭防火墙测试(生产环境慎用)
sudo systemctl stop firewalld

# 如果发现是SELinux的问题可以尝试
sudo setenforce 0

在CentOS/RHEL系统上,SELinux经常会导致各种"莫名其妙"的网络问题。如果确认是SELinux的问题,可以考虑:

  1. 永久禁用(不推荐)
  2. 调整SELinux策略
  3. 使用正确的安全上下文

七、使用Docker内置诊断工具

Docker自带了一些很好的诊断工具,就像手机的工程模式,可以查看很多底层信息。

# 技术栈:Docker
# 查看容器详细网络配置
docker inspect my_container | grep -i network -A 20

# 检查Docker服务日志
journalctl -u docker.service

# 查看网络数据包流动情况
docker exec -it my_container tcpdump -i eth0

这些工具特别有用:

  1. docker inspect 查看容器完整配置
  2. 服务日志查看Docker daemon的运行情况
  3. tcpdump查看实际网络流量

八、常见问题解决方案汇总

根据经验,90%的网络问题都是以下几类:

  1. 容器根本就没联网

    • 检查是否使用了--network none
    • 确认Docker服务正常运行
  2. 端口映射错误

    • 确认-p参数格式正确
    • 检查宿主机端口是否被占用
  3. DNS解析失败

    • 检查/etc/resolv.conf
    • 尝试使用IP直接访问
  4. 防火墙拦截

    • 检查iptables规则
    • 临时关闭防火墙测试
  5. 跨主机通信问题

    • 确认使用overlay网络
    • 检查物理网络连通性

应用场景分析

这些排查方法特别适合以下场景:

  1. 开发环境突然无法访问容器服务
  2. 生产环境容器间通信异常
  3. CI/CD流水线中容器网络测试失败
  4. 迁移到新环境后的网络适配

技术优缺点

优点:

  1. 方法通用,适用于大多数Docker环境
  2. 从简单到复杂逐步排查
  3. 不依赖特殊工具,使用Docker自带命令

缺点:

  1. 某些云环境的特殊网络配置可能需要额外处理
  2. Kubernetes环境的网络问题更复杂,需要额外方法

注意事项

  1. 生产环境谨慎操作,特别是修改防火墙规则
  2. 记录每一步的操作和结果,方便回滚
  3. 网络问题可能由多个因素共同导致,要全面检查
  4. 容器内某些工具可能需要手动安装(如ping、telnet)

文章总结

排查Docker网络问题就像医生看病,要望闻问切一步步来。从最基本的网络连通性测试开始,到端口映射、DNS解析、防火墙设置等,每个环节都可能成为问题的源头。掌握这套排查流程,大多数Docker网络问题都能在10分钟内定位。记住,遇到问题不要慌,按步骤排查准没错!