如何从 Docker 容器内部访问宿主机上的端口?

容器内访问宿主机服务,用特殊域名 host.docker.internal:端口(Linux 需 --add-host host.docker.internal:host-gateway),或宿主机内网 IP;原生 Linux 桥接访问需服务监听可达宿主地址;Docker Desktop 转发行为不同,不必一律绑定 0.0.0.0。

最佳实践
如何从 Docker 容器内部访问宿主机上的端口?封面

做法:容器内把 localhost 换成宿主机的地址——Mac/Windows 直接用 host.docker.internal:端口;Linux 启动时加 --add-host host.docker.internal:host-gateway 后用同样域名,或直接用宿主机的内网 IP。原生Linux桥接容器需服务绑定可达的宿主地址,仅回环通常不可达;Docker Desktop转发行为不同,不必一律改成0.0.0.0。地址指Docker daemon所在主机,远程context不一定是当前电脑。

典型场景

宿主机上跑着 MySQL(3306),容器里的应用要连它:

# 容器内测试连通性
mysql -h host.docker.internal -P 3306 -u app -p # 使用MySQL客户端
# Linux 启动容器时先加映射
docker run -d --add-host host.docker.internal:host-gateway myapp

docker-compose:

services:
  app:
    extra_hosts:
      - "host.docker.internal:host-gateway"

用宿主机 IP 的备选方案

查宿主机在 docker 网桥上的地址:

ip addr show docker0 | grep inet   # 通常是 172.17.0.1

容器内以MySQL协议连接该地址的3306端口,不使用HTTP。缺点:网桥 IP 可能随 Docker 配置变化,不如 host-gateway 稳定。

三个常见失败原因

  1. 服务只听 127.0.0.1:容器流量从网桥进来,不算本地回环,应绑定允许容器访问的具体宿主地址,避免不必要地开放所有接口(注意评估暴露面,配合防火墙只放行内网)。
  2. 防火墙拦截:宿主机 iptables/firewalld 拦了 docker0 网段的入站。
  3. 容器内还在用 localhost:容器内 localhost 是容器自己,不是宿主机。

反向问题:宿主机访问容器

方向反过来时用端口映射 docker run -p 8080:80,宿主机访问 localhost:8080——两个方向机制不同,别混淆。

常见问题(FAQ)

Q:K8s 里 Pod 怎么访问节点上的服务?
A:用节点 IP(status.hostIP 可注入环境变量)或 hostNetwork;推荐把服务也容器化或用 Service 抽象。

Q:host.docker.internal 能 ping 通但连不上端口?
A:ping只检查ICMP,不能证明TCP端口与数据库认证可用;还需检查服务、地址、端口和策略,按上面三点逐个查。

Q:生产环境推荐这种做法吗?
A:权宜之计可以,长期建议服务全部容器化编排,或数据库用云服务的内网地址,减少宿主机耦合。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台