主机网络驱动程序

如果您为容器使用 host 网络模式,该容器的网络堆栈不会与 Docker 主机隔离(容器共享主机的网络命名空间),并且该容器不会获得自己的 IP 地址分配。例如,如果您运行一个绑定到端口 80 的容器并使用 host 网络,该容器的应用程序将在主机的 IP 地址的端口 80 上可用。

注意

鉴于在使用 host 模式网络时容器没有自己的IP地址, 端口映射 不会 生效,且 -p--publish-P--publish-all 选项会被 忽略,转而产生警告:

WARNING: Published ports are discarded when using host network mode

主机模式网络在以下使用场景中非常有用:

  • 为了优化性能
  • 在容器需要处理大量端口的情况下

这是因为不需要网络地址转换(NAT),并且不会为每个端口创建“用户空间代理”。

主机网络驱动程序在 Docker Engine(仅限 Linux)和 Docker Desktop 版本 4.34 及更高版本上受支持。

你也可以通过向 docker service create 命令传递 --network host 来为 swarm 服务使用 host 网络。在这种情况下,控制流量(与管理和 swarm 及服务相关的流量)仍然通过 overlay 网络发送,但各个 swarm 服务容器使用 Docker 守护进程的主机网络和端口发送数据。这会产生一些额外的限制。例如,如果一个服务容器绑定到端口 80,那么在给定的 swarm 节点上只能运行一个服务容器。

Docker Desktop版

Docker Desktop 版本 4.34 及更高版本支持主机网络。 要启用此功能:

  1. 在 Docker Desktop 中登录您的 Docker 账户。
  2. 导航到 设置
  3. 资源 选项卡下,选择 网络
  4. 勾选 启用主机网络 选项。
  5. 选择 应用并重启

此功能在两个方向上都有效。这意味着您可以从主机访问运行在容器中的服务器,也可以从任何启用了主机网络的容器访问运行在主机上的服务器。TCP 和 UDP 均被支持作为通信协议。

示例

以下命令在容器中启动 netcat,监听端口 8000

$ docker run --rm -it --net=host nicolaka/netshoot nc -lkv 0.0.0.0 8000

主机上的端口 8000 将可用,您可以从另一个终端使用以下命令连接到它:

$ nc localhost 8000

您在此处输入的内容将显示在容器正在运行的终端上。

要从容器访问主机上运行的服务,可以使用以下命令启动启用了主机网络的容器:

$ docker run --rm -it --net=host nicolaka/netshoot

如果您随后想从容器访问主机上的服务(在此示例中为运行在端口 80 上的 web 服务器),您可以这样操作:

$ nc localhost 80

限制

  • 容器内的进程无法绑定到主机的 IP 地址, 因为容器没有直接访问主机接口的权限。
  • Docker Desktop 的主机网络功能在第 4 层运行。这意味着与 Linux 上的 Docker 不同,不支持在 TCP 或 UDP 之下运行的网络协议。
  • 启用增强容器隔离后,此功能无法使用,因为将容器与主机隔离并允许它们访问主机网络是相互矛盾的。
  • 仅支持 Linux 容器。主机网络不适用于 Windows 容器。

后续步骤