Docker-Compose中host.docker.internal失效时容器连接宿主机故障排查
问题:容器可ping通宿主机但无法连接端口,目标实现FastAPI容器与宿主机MySQL通信
最终目标是让运行FastAPI应用的容器与宿主机上的MySQL数据库通信,当前测试容器能ping通宿主机,但nc -vz连接80端口始终失败,以下是详细测试过程:
测试场景1:使用host.docker.internal
Dockerfile
FROM debian:latest RUN apt update && apt install -y \ netcat \ iputils-ping CMD echo "tailing /dev/null" && tail -f /dev/null
docker-compose.yml
version: "3.2" services: test: build: context: "." extra_hosts: - "host.docker.internal:host-gateway"
测试结果
- ping正常:
root@5981bcfbf598:/# ping host.docker.internal PING host.docker.internal (172.17.0.1) 56(84) bytes of data. 64 bytes from host.docker.internal (172.17.0.1): icmp_seq=1 ttl=64 time=0.079 ms 64 bytes from host.docker.internal (172.17.0.1): icmp_seq=2 ttl=64 time=0.067 ms 64 bytes from host.docker.internal (172.17.0.1): icmp_seq=3 ttl=64 time=0.068 ms ^C --- host.docker.internal ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2013ms rtt min/avg/max/mdev = 0.067/0.071/0.079/0.005 ms
- nc连接失败:
root@5981bcfbf598:/# nc -vz host.docker.internal 80 nc: connect to host.docker.internal (172.17.0.1) port 80 (tcp) failed: Connection refused
测试场景2:手动指定自定义网络
docker-compose.yml
version: "3.2" networks: test: name: test-network attachable: true ipam: driver: default config: - subnet: 172.42.0.0/16 ip_range: 172.42.5.0/24 gateway: 172.42.0.1 services: test: build: context: "." networks: - test
测试结果
- 网关确认:
$ docker inspect test-test-1 -f '{{range .NetworkSettings.Networks}}{{.Gateway}}{{end}}' 172.42.0.1
- ping正常,但nc连接仍失败:
root@07f81c211a0c:/# nc -vz 172.42.0.1 80 nc: connect to 172.42.0.1 port 80 (tcp) failed: Connection refused
宿主机环境信息
- Apache仅监听IPv6的80端口:
$ netstat -tulpn ... tcp6 0 0 :::80 :::* LISTEN 1258/apache2
- 系统:Ubuntu 18.04.6 LTS,Docker版本20.10.21,防火墙已允许80端口所有入站请求。
解决方案
核心问题是宿主机服务仅监听IPv6地址,而容器通过IPv4地址访问宿主机,导致连接被拒绝。以下是两种解决思路:
1. 修改服务监听配置,同时支持IPv4和IPv6
针对Apache
修改/etc/apache2/ports.conf配置文件,添加IPv4监听规则:
Listen 0.0.0.0:80 Listen [::]:80
重启Apache服务:
sudo systemctl restart apache2
针对MySQL
修改/etc/mysql/mysql.conf.d/mysqld.cnf(或对应配置文件)中的bind-address字段:
bind-address = 0.0.0.0
确保skip-ipv6未被启用(若需IPv6支持),然后重启MySQL:
sudo systemctl restart mysql
2. 让容器通过IPv6访问宿主机
若不想修改服务监听配置,可在容器内使用宿主机的IPv6地址访问:
- 查看宿主机IPv6地址:
ip -6 addr show - 在容器内执行
nc -vz [宿主机IPv6地址] 80测试连接
同时需确保Docker网络支持IPv6,可在docker-compose.yml中添加IPv6配置:
networks: test: name: test-network attachable: true enable_ipv6: true ipam: driver: default config: - subnet: 172.42.0.0/16 ip_range: 172.42.5.0/24 gateway: 172.42.0.1 - subnet: fd00::/80 gateway: fd00::1
验证效果
修改完成后,重新进入容器执行nc -vz host.docker.internal 80,应显示连接成功:
root@9fe8de220d44:/# nc -vz host.docker.internal 80 Connection to host.docker.internal (172.17.0.1) port 80 (tcp) succeeded!
内容的提问来源于stack exchange,提问作者AJ Livingston
相关产品推荐
相关产品推荐

