我只是想了解为什么在 Windows 上 的 IPhost.docker.internal
不是主机的 IP,也不是172.17.0.1
。
所有这些在 Docker 上是如何运作的?
我已经阅读过文档但不明白这一切是如何运作的。
连接流动如下:容器 > 172.17.0.1
> host.docker.internal
> 主机?
如果是,为什么它不直接连接到主机而是通过host.docker.internal
?
我只是想了解为什么在 Windows 上 的 IPhost.docker.internal
不是主机的 IP,也不是172.17.0.1
。
所有这些在 Docker 上是如何运作的?
我已经阅读过文档但不明白这一切是如何运作的。
连接流动如下:容器 > 172.17.0.1
> host.docker.internal
> 主机?
如果是,为什么它不直接连接到主机而是通过host.docker.internal
?
让我用图表来说明一下直接在 Linux 主机上运行 Docker 引擎的情况和 Docker Desktop 的情况(这或多或少是 Windows 中唯一的情况,因为 Windows 不是 Linux)之间的区别:
请注意,本答案中的图表说明了“网络结构”。这就是为什么您看到容器位于 Linux 主机“外部”的原因。至少对于 Linux 主机,您几乎可以使用在其任何接口上配置的 IP 访问它。因此,基本上您可以使用、、某些(非默认 docker 网桥)上的 IP 配置或“默认”网络命名空间 (netns) 中存在的任何其他 IP 访问 docker 主机
eth0
。docker0
从br-xxx
网络角度来看,不同的 netns 非常像不同的主机,这就是为什么每个都有自己的 netns 的 docker 容器就像“虚拟”LAN(在“模拟”的意义上;无论如何,不是“VLAN”)中的独立主机。docker 网桥就像虚拟交换机,其中一个端口连接到主机,其他端口连接到容器。因此,docker 主机就像连接到多个 LAN(广播域),它充当容器的路由器。 (eth0
从容器的角度来看,您或多或少可以将其视为“WAN 接口”。)对于 Docker Desktop 来说,这实际上就像将“裸机”Linux 外壳嵌套到 VM 中一样。VM 显然就像容器一样,就像一个“单独的主机”,并且至少在默认情况下,它也连接到“内部交换机”,这就像容器的 docker 桥,因此,您可以使用该交换机上配置的 IP 访问 Windows 主机(您也可以将其视为连接到该交换机端口的虚拟 NIC)。
请注意,交换机实际上并不是“docker 的一部分”,而只是 WSL / Hyper-V 的一部分。使用的私有 IP/子网也不是由 docker 选择的。
我还没有真正看过 docker 的代码(实际上它可能甚至还没有开放,因为我认为 Docker Desktop 由 blob 组成),但我相信 DNS“答案”来自
host.docker.internal
VM 默认路由(即默认网关)中的网关地址。(坦率地说,我甚至没有在 Windows 上真正检查过。我只是通过在 Linux 上运行 Docker Desktop 来“事实核查”,它使用 qemu 运行 KVM。)默认网关由虚拟机管理程序通过 DHCP 通告给 VM。我不太清楚微软为什么决定“隐藏”某些内部开关(嗯,“默认”/“特殊”开关),但据我所知,隐藏它们并不一定意味着您无法通过这些开关上配置的 IP 访问 Windows 主机。
我不完全清楚您是否可以通过一个在未连接到网络的适配器上配置 IP 的网络访问 Windows 主机(就像您可以访问 Linux 主机一样)。
无论如何,适配器不是单独的主机,当您与同一目标主机通信时,不存在从适配器到另一个适配器的“流” 。当流量通过接口到达主机时,它们就到达了。只有当它们的“最终”目的地不是主机而是其他主机时,它们才会通过另一个(或同一个)接口,在这种情况下会发生 L3/IP 转发(基本上,这意味着主机作为网关/路由器工作,流量从一个网络流向另一个网络;有时是同一个网络)。例如,如果您的容器尝试访问 Google 或家庭 LAN 中的设备。
我不太明白这个问题,但我想是的,它
172.17.0.1
是一个“路由器的 IP”,从某种意义上说,Linux 主机(运行容器,无论它是否是 VM)是容器的路由器/(默认)网关。请注意,您可以拥有多个 docker 桥,并且172.17.0.1
只是在默认桥上配置的通常地址(docker0
)。容器的默认网关实际上会设置为它们所连接的 docker 桥上配置的 IP 地址。值得一提的是,这
host.docker.internal
是“Docker Desktop 专用的”,即默认情况下/OOTB 在“裸机”情况下你不会得到任何答案,尽管似乎添加了一些“基础设施”以允许你“模仿”类似的东西。 (我还没有真正检查“基础设施”是否会提供在相应的 docker 桥上配置的 IP 或 Linux 主机上的默认网关。)此外,这里
gateway.docker.internal
提到的(也)给出了与(至少当 Docker Desktop 在 Linux 上运行时)相同的答案。不过,我仍然不确定在任何情况下他们是否会给出不同的答案。host.docker.internal