使用 Docker 时,您通常将构成堆栈的服务容器化,并使用容器间网络在它们之间进行通信。有时,您可能需要一个容器来与主机上尚未容器化的服务进行通信。以下是访问Docker 容器localhost
或127.0.0.1
从 Docker 容器内访问的方法。
简单的选择
适用于 Windows 和 Mac 的 Docker Desktop 18.03+ 支持host.docker.internal
作为localhost
. 在您的容器中使用此字符串来访问您的主机。
localhost
和127.0.0.1
– 这些解析为容器。host.docker.internal
– 这解析到外部主机。
如果您在主机上运行 MySQL 服务器,Docker 容器可以通过连接到host.docker.internal:3306
. 当您在 Windows 或 Mac 机器上工作时,这是最简单的技术。
在Linux上泊坞窗引擎可让使用者host.docker.internal
通过太--add-host
标志docker run
。使用此标志启动容器以公开主机字符串:
docker run -d --add-host host.docker.internal:host-gateway my-container:latest
该--add-host
标志将一个条目添加到容器的/etc/hosts
文件中。上面显示的值映射host.docker.internal
到容器的主机网关,与实际localhost
值匹配。host.docker.internal
如果你愿意,你可以用你自己的字符串替换。
连接到主机网络
Docker 提供了一个host
网络,让容器可以共享主机的网络堆栈。这种方法意味着localhost
容器内部解析为物理主机,而不是容器本身。
通过添加--network=host
标志,容器与主机网络一起启动:
docker run -d --network=host my-container:latest
现在您的容器可以引用localhost
或127.0.0.1
直接。
如果您使用 Docker Compose,请修改容器的服务定义以包含以下network_mode
字段:
服务:
我的服务:
network_mode :主机
这种方法有一些注意事项。在使用它之前考虑所有的影响是很重要的。容器通常有自己的私有网络,独立于主机的堆栈。当您指定时--network=host
,容器默认从您的主机继承共享网络设置。
容器公开的任何端口都将在主机上公开,即使它们没有用-p
标志显式声明。容器的默认主机名将与主机的主机名匹配,尽管这可以通过--hostname
标志进行更改。
主机网络可能是一个安全问题,它打破了 Docker 容器的隔离模型。在您确信运行的容器不会相互冲突或导致主机环境出现问题的情况下,它仍然很有用。主机网络模式也比默认桥接模式更快,因为没有虚拟化层让流量通过。
使用默认桥接模式访问主机
您的主机仍然可以在默认bridge
网络模式下从容器访问。你只需要通过它的 Docker 网络 IP 来引用它,而不是localhost
或127.0.0.1
。
大多数 Docker 引擎安装将主机表示为172.17.0.1
默认docker0
桥接网络。您可以通过在主机上运行以下命令来检查自己的 IP:
ip地址显示docker0
您的主机的 Docker IP 将显示在该inet
行上。从容器内连接到此 IP 地址以成功访问主机上运行的服务。
这种方法的一个缺陷是您可能无法连接到直接绑定到localhost
. 您需要确保您的服务正在侦听 Docker 网桥 IP 以及localhost
和 上的连接127.0.0.1
。否则,您将connection refused
在容器中看到或类似的错误。
概括
当您需要从 Docker 容器外部访问您机器的localhost
. 如果您使用的是 Windows 或 Mac,最好使用内置host.docker.internal
别名。Linux 用户可以--add-host
在启动容器时设置与该标志类似的内容。
主机网络模式是一种通用的替代方案,它允许容器共享主机的网络堆栈。您可以localhost
直接参考,但需要注意风险和限制。当需要强大的网络隔离时,它不是一个合适的选择。
坚持使用桥接模式可能是支持它的工作负载的最佳选择。将主机的服务绑定到其 Docker IP,然后使用该地址从容器内进行连接。这让您可以使用 Docker 的每个容器虚拟化网络,同时在需要时提供到您的主机的路由。