如何从 Docker 容器内部获取宿主机的 IP 地址?
容器内获取宿主机 IP:用 host.docker.internal 域名(Mac/Win 内置,Linux 加 --add-host),或读默认网关 ip route | awk '/default/ {print $3}',即 docker0 网桥地址。本文给出各平台命令。
两种通用方法:①域名方式——Mac/Windows 直接解析 host.docker.internal,Linux 启动加 --add-host host.docker.internal:host-gateway 后同样可用;②命令方式——容器内执行 ip route | awk '/default/ {print $3}',拿到的默认网关地址就是宿主机在该 Docker 网络中的 IP(默认网桥下通常是 172.17.0.1)。
方法一:host.docker.internal(推荐)
# 容器内解析测试
getent hosts host.docker.internal
# 或
ping -c1 host.docker.internal
跨平台写法统一,应用配置里写域名最干净。老版本 Docker Desktop 上的 docker.for.mac.localhost 已被 host.docker.internal 取代,别再用了。
方法二:读路由表拿网关 IP
docker run --rm alpine sh -c "ip route | awk '/default/ {print \$3}'"
# 输出示例:172.17.0.1
容器里没装 iproute2 的话:apk add iproute2(alpine)或 apt install iproute2(debian 系)。
方法三:宿主机侧查网桥
宿主机上:
ip addr show docker0 | grep 'inet '
# inet 172.17.0.1/16 ... → 容器侧就用 172.17.0.1
自定义网络则查对应网桥(docker network ls + docker network inspect)。
拿 IP 之后的注意事项
- 用途是访问宿主机服务:服务必须监听
0.0.0.0或该网桥 IP,只听 127.0.0.1 访问不到 - 别写死:网桥 IP 可配可变,优先用域名方式
- host 网络模式下无意义:共享网络栈时宿主机 IP 就是 localhost
观测云对照
采集配置里写域名不写死 IP。 容器内应用向宿主机上的 DataKit 上报数据时,用 host.docker.internal 这类域名配置,网桥重建、网段变更都不影响链路。
常见问题(FAQ)
Q:Mac 上 ping 得通但 Linux 不行?
A:Linux 需要 --add-host host.docker.internal:host-gateway(Docker 20.10+),Desktop 是默认内置的。
Q:K8s Pod 里怎么拿节点 IP?
A:Downward API 注入:fieldRef: status.hostIP 到环境变量。
Q:容器能拿宿主机的公网 IP 吗?
A:那不属于 Docker 网络范畴;容器内访问外网查询服务(如 ifconfig.me)或让宿主机通过环境变量注入。