Docker 命令中的 --net=host 选项到底有什么作用?
What does --net=host option in Docker command really do?
我是 Docker 的新手。我找不到关于这个选项在 docker 运行 命令中的作用的任何清晰描述,对此我有点困惑。
我们可以在不指定端口的情况下使用它来访问 docker 容器上的 运行ning 应用程序吗?例如,如果我 运行 通过使用 docker 运行 命令中的选项 -p 8080:8080
通过端口 8080 中的 docker 图像部署的 Web 应用程序,我知道我将拥有在 Docker 容器 ip /theWebAppName 的 8080 端口上访问它。但我真的想不出 --net=host
选项如何工作的方式。
安装 docker 后默认有 3 个网络:
docker network ls
NETWORK ID NAME DRIVER SCOPE
f3be8b1ef7ce bridge bridge local
fbff927877c1 host host local
023bb5940080 none null local
我尽量保持简单。因此,如果您默认启动一个容器,它将在网桥 (docker0) 网络内创建。
$ docker run -d jenkins
1498e581cdba jenkins "/bin/tini -- /usr..." 3 minutes ago Up 3 minutes 8080/tcp, 50000/tcp friendly_bell
在 jenkins 的 docker 文件中,端口 8080
和 50000
被暴露。这些端口在其桥接网络上为容器打开。因此,该桥接网络内的所有内容都可以访问端口 8080
和 50000
上的容器。桥接网络中的所有内容都在 "Subnet": "172.17.0.0/16",
的私有范围内,如果你想从外部访问它们,你必须将端口映射到 -p 8080:8080
。这会将容器的端口映射到真实服务器(主机网络)的端口。因此,在 8080
上访问您的服务器将路由到端口 8080
上的桥接网络。
现在你也有了自己的主机网络。这不会容器化容器网络。因此,如果您在主机网络中启动一个容器,它将如下所示(这是第一个):
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1efd834949b2 jenkins "/bin/tini -- /usr..." 6 minutes ago Up 6 minutes eloquent_panini
1498e581cdba jenkins "/bin/tini -- /usr..." 10 minutes ago Up 10 minutes 8080/tcp, 50000/tcp friendly_bell
区别在于端口。您的容器现在位于您的主机网络内。因此,如果您在主机上打开 8080
端口,您将立即访问容器。
$ sudo iptables -I INPUT 5 -p tcp -m tcp --dport 8080 -j ACCEPT
我已经在我的防火墙中打开了端口 8080
,当我现在在端口 8080
上访问我的服务器时,我正在访问我的 jenkins。我认为 this blog 也有助于更好地理解它。
- 您可以创建自己的新网络,例如 --net="anyname"
- 这样做是为了隔离来自不同容器的服务。
- 假设同一个服务运行在不同的容器中,但是端口映射
保持不变,第一个容器启动良好,但第二个容器的相同服务将失败。
所以要避免这种情况,请更改端口映射或创建网络。
--net=host
选项用于使 Docker 容器内的程序从网络的角度看起来就像在主机本身上 运行ning 一样。它允许容器获得比正常情况下更大的网络访问权限。
通常你必须将主机的端口转发到容器中,但是当容器共享主机的网络时,任何网络 activity 直接发生在主机上——就像程序是运行在主机本地而不是在容器内。
虽然这确实意味着您不再需要公开端口并将它们映射到容器端口,但这意味着您必须编辑 Docker 文件来调整每个容器侦听的端口,以避免冲突不能有两个容器在同一个主机端口上运行。但是,此选项的真正原因是 运行 宁需要网络访问的应用程序难以转发到端口级别的容器。
例如,如果您想 运行 一个 DHCP 服务器,那么您需要能够侦听网络上的广播流量,并从数据包中提取 MAC 地址。此信息在端口转发过程中丢失,因此 运行 Docker 内的 DHCP 服务器的唯一方法是 运行 容器作为 --net=host
。
一般来说,--net=host
仅当您 运行 具有非常具体、不寻常的网络需求的程序时才需要。
最后,从安全角度来看,Docker 容器可以侦听多个端口,即使它们只通告(公开)一个端口。通常这很好,因为您只转发单个预期端口,但是如果您使用 --net=host
那么您将获得 all 容器在主机上侦听的端口,即使那些不是' 列在 Docker 文件中。这意味着您需要仔细检查容器(特别是如果它不是您的,例如软件项目提供的官方容器)以确保您不会无意中暴露机器上的额外服务。
请记住一点,主机网络驱动程序仅适用于 Linux 主机,Docker 桌面 Mac、Docker 桌面 [=] 不支持12=],或 Docker Windows 服务器
的 EE
我是 Docker 的新手。我找不到关于这个选项在 docker 运行 命令中的作用的任何清晰描述,对此我有点困惑。
我们可以在不指定端口的情况下使用它来访问 docker 容器上的 运行ning 应用程序吗?例如,如果我 运行 通过使用 docker 运行 命令中的选项 -p 8080:8080
通过端口 8080 中的 docker 图像部署的 Web 应用程序,我知道我将拥有在 Docker 容器 ip /theWebAppName 的 8080 端口上访问它。但我真的想不出 --net=host
选项如何工作的方式。
安装 docker 后默认有 3 个网络:
docker network ls
NETWORK ID NAME DRIVER SCOPE
f3be8b1ef7ce bridge bridge local
fbff927877c1 host host local
023bb5940080 none null local
我尽量保持简单。因此,如果您默认启动一个容器,它将在网桥 (docker0) 网络内创建。
$ docker run -d jenkins
1498e581cdba jenkins "/bin/tini -- /usr..." 3 minutes ago Up 3 minutes 8080/tcp, 50000/tcp friendly_bell
在 jenkins 的 docker 文件中,端口 8080
和 50000
被暴露。这些端口在其桥接网络上为容器打开。因此,该桥接网络内的所有内容都可以访问端口 8080
和 50000
上的容器。桥接网络中的所有内容都在 "Subnet": "172.17.0.0/16",
的私有范围内,如果你想从外部访问它们,你必须将端口映射到 -p 8080:8080
。这会将容器的端口映射到真实服务器(主机网络)的端口。因此,在 8080
上访问您的服务器将路由到端口 8080
上的桥接网络。
现在你也有了自己的主机网络。这不会容器化容器网络。因此,如果您在主机网络中启动一个容器,它将如下所示(这是第一个):
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1efd834949b2 jenkins "/bin/tini -- /usr..." 6 minutes ago Up 6 minutes eloquent_panini
1498e581cdba jenkins "/bin/tini -- /usr..." 10 minutes ago Up 10 minutes 8080/tcp, 50000/tcp friendly_bell
区别在于端口。您的容器现在位于您的主机网络内。因此,如果您在主机上打开 8080
端口,您将立即访问容器。
$ sudo iptables -I INPUT 5 -p tcp -m tcp --dport 8080 -j ACCEPT
我已经在我的防火墙中打开了端口 8080
,当我现在在端口 8080
上访问我的服务器时,我正在访问我的 jenkins。我认为 this blog 也有助于更好地理解它。
- 您可以创建自己的新网络,例如 --net="anyname"
- 这样做是为了隔离来自不同容器的服务。
- 假设同一个服务运行在不同的容器中,但是端口映射 保持不变,第一个容器启动良好,但第二个容器的相同服务将失败。 所以要避免这种情况,请更改端口映射或创建网络。
--net=host
选项用于使 Docker 容器内的程序从网络的角度看起来就像在主机本身上 运行ning 一样。它允许容器获得比正常情况下更大的网络访问权限。
通常你必须将主机的端口转发到容器中,但是当容器共享主机的网络时,任何网络 activity 直接发生在主机上——就像程序是运行在主机本地而不是在容器内。
虽然这确实意味着您不再需要公开端口并将它们映射到容器端口,但这意味着您必须编辑 Docker 文件来调整每个容器侦听的端口,以避免冲突不能有两个容器在同一个主机端口上运行。但是,此选项的真正原因是 运行 宁需要网络访问的应用程序难以转发到端口级别的容器。
例如,如果您想 运行 一个 DHCP 服务器,那么您需要能够侦听网络上的广播流量,并从数据包中提取 MAC 地址。此信息在端口转发过程中丢失,因此 运行 Docker 内的 DHCP 服务器的唯一方法是 运行 容器作为 --net=host
。
一般来说,--net=host
仅当您 运行 具有非常具体、不寻常的网络需求的程序时才需要。
最后,从安全角度来看,Docker 容器可以侦听多个端口,即使它们只通告(公开)一个端口。通常这很好,因为您只转发单个预期端口,但是如果您使用 --net=host
那么您将获得 all 容器在主机上侦听的端口,即使那些不是' 列在 Docker 文件中。这意味着您需要仔细检查容器(特别是如果它不是您的,例如软件项目提供的官方容器)以确保您不会无意中暴露机器上的额外服务。
请记住一点,主机网络驱动程序仅适用于 Linux 主机,Docker 桌面 Mac、Docker 桌面 [=] 不支持12=],或 Docker Windows 服务器
的 EE