Docker 命令中的 --net=host 选项到底有什么作用?

新手上路,请多包涵

我是 Docker 的初学者。我在 docker run 命令中找不到任何关于此选项的明确描述,对此我感到有些困惑。

我们可以使用它来访问在 docker 容器上运行的应用程序而不指定端口吗?例如,如果我在 docker run 命令中使用选项 -p 8080:8080 运行通过端口 8080 中的 docker 映像部署的 webapp,我知道我必须在 Docker 容器 ip /theWebAppName 的 8080 端口上访问它。但我真的想不出 --net=host 选项如何工作。

原文由 Ravindu Nirmal Fernando 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 3.5k
2 个回答

安装 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 的 dockerfile 中,端口 808050000 被暴露。这些端口在其桥接网络上为容器打开。因此,桥接网络内的所有内容都可以访问端口 808050000 上的容器。桥接网络中的所有内容都在 "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 我正在访问我的詹金斯。我认为 这个博客 也有助于更好地理解它。

原文由 lvthillo 发布,翻译遵循 CC BY-SA 3.0 许可协议

从网络的角度来看, --net=host 选项用于使 Docker 容器内的程序看起来像是在主机本身上运行。它允许容器比它通常可以获得的更大的网络访问权限。

通常,您必须将端口从主机转发到容器中,但是当容器共享主机的网络时,任何网络活动都直接发生在主机上 - 就像程序在主机上本地运行而不是在容器。

虽然这确实意味着您不再需要公开端口并将它们映射到容器端口,但这意味着您必须编辑 Dockerfile 以调整每个容器侦听的端口,以避免冲突,因为您不能让两个容器在同一个容器上运行主机端口。但是,此选项的真正原因是运行需要网络访问的应用程序,这些应用程序难以在端口级别转发到容器。

例如,如果您想运行 DHCP 服务器,那么您需要能够监听网络上的广播流量,并从数据包中提取 MAC 地址。此信息在端口转发过程中丢失,因此在 Docker 中运行 DHCP 服务器的唯一方法是将容器运行为 --net=host

一般来说, --net=host 仅在您运行具有非常特殊的、不寻常的网络需求的程序时才需要。

最后,从安全的角度来看,Docker 容器可以监听许多端口,即使它们只通告(公开)一个端口。通常这很好,因为您只转发单个预期端口,但是如果您使用 --net=host 那么您将获得在主机上侦听的 所有 容器端口,即使是那些未在 Dockerfile 中列出的端口。这意味着您需要仔细检查容器(特别是如果它不是您的,例如软件项目提供的官方容器),以确保您不会无意中在机器上暴露额外的服务。

原文由 Malvineous 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题