Skip to main content

容器内访问物理网络

· 3 min read
Alan

概述

如果安装的是最新版的 Docker, 在容器内部直接使用 host.docker.internal 即可访问主机网络, 比如在容器执行 curl http://host.docker.internal:8080 即可访问主机的8080端口. (对于Linux环境, 创建容器时需要增加--add-host=host.docker.internal:host-gateway参数)

How to access host port from docker container

参考: How to access host port from docker container

Linux

Docker v20.10及以上版本

在Linux环境,执行docker命令时,增加--add-host=host.docker.internal:host-gateway参数开启此特性(Docker Compose 配置如下),然后就可以在容器内部使 host.docker.internal 访问主机网络(可使用 cat /etc/hosts 查看此参数增加的DNS解析记录)。

等价的Docker Compose配置
extra_hosts:
- "host.docker.internal:host-gateway"

macOS 和 Windows

Docker v18.03及以上版本

直接使用 host.docker.internal 即可访问主机网络。(该DNS Name,Linux默认尚不支持,进度参考 https://github.com/docker/for-linux/issues/264 )

macOS低版本尝试使用 docker.for.mac.host.internal 或者 docker.for.mac.localhost.

I want to connect from a container to a service on the host

翻译自 I want to connect from a container to a service on the host

主机(host)的IP是动态的(或者没有网络访问). 我们建议你(容器内)访问特定的DNS名称: host.docker.internal, 这个DNS名会被解析成主机(host)IP地址. 这是为了方便开发, 所以在非Mac版Docker的生产环境不可用.

你也可以在容器内部使用DNS名gateway.docker.internal访问网关(gateway)

假如你的物理机器安装了python, 使用下面的指令作为例子, 在容器里访问主机(host)服务.

  1. 在主机(host)上使用python -m http.server 8000创建一个监听8000端口的web服务
  2. 执行以下命令创建一个容器, 并借助curl命令访问第一步在主机创建的web服务:
docker run --rm -it alpine sh
apk add curl
curl http://host.docker.internal:8000
note

如果容器内部无法访问 curl http://host.docker.internal:8000, 有可能是防火墙限制了8000端口的访问, 对于支持ufw命令的Linux系统, 可以在主机(host machine)使用命令 ufw allow 8000 开放 8000 端口的访问, ufw命令参考UFW allow port range – How we do it?.