Docker命令中的--net = host选项真的有用吗?

时间:2017-04-10 06:37:34

标签: docker docker-networking

我对Docker有点初学者了。我无法找到有关此选项在docker run命令中做了什么的明确描述,并且对此有点困惑。

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

3 个答案:

答案 0 :(得分:72)

在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上的bridgenetwork。

现在您还拥有了主机网络。哪个没有容器网络容器化。因此,如果您在主机网络中启动容器,它将看起来像这样(它是第一个):

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对于更好地理解它也很有用。

答案 1 :(得分:0)

  1. 您可以创建自己的新网络,例如-net =“ anyname”
  2. 这样做是为了将服务与其他容器隔离开。
  3. 假设相同的服务在不同的容器中运行,但是端口映射 保持不变,第一个容器启动良好,但是来自第二个容器的相同服务将失败。 为避免这种情况,请更改端口映射或创建网络。

答案 2 :(得分:0)

从网络的角度来看,--net=host选项用于使Docker容器中的程序看起来像在主机本身上运行。它允许容器提供比正常情况下更大的网络访问权限。

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

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

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

通常来说,--net=host仅在运行具有非常特殊的,异常网络需求的程序时才需要。

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