侦听端口并使其可访问之间的区别

时间:2017-08-29 21:24:01

标签: docker networking dockerfile ports

我实际上正在阅读Docker文件的Docker文档。您可以在其中定义容器中的端口公开的方式。在阅读该描述时,我发现我在这里理解一个特定的差异时遇到了问题。

来自:https://docs.docker.com/engine/reference/builder/#expose

  

EXPOSE指令通知Docker容器在运行时侦听指定的网络端口。 EXPOSE不会使容器的端口可供主机访问。

收听端口并使其可访问的容器(或服务器应用程序)之间有什么区别?

如果应用程序正在侦听端口 - 我可以在其上启动HTTP请求,它会回答我,对吧?是不是某种访问我必须将其作为主机在此定义外部上下文)?

3 个答案:

答案 0 :(得分:2)

Expose只提供一个提示(信息),哪些端口是由图像公开的。假设您询问桥接(默认)容器 - 它们是隔离的,无法从主机网络访问,受主机防火墙保护。因此,如果您对入站流量感兴趣,则需要在主机网络和容器接口之间创建映射。可以把它想象成在特定端口上打开通往外部世界的窗口。

假设您对我们感兴趣的图片公开了端口5000和6000,您希望将容器端口映射到外部世界。

使用-P (--publish-all),您可以让Docker守护程序为所有端口创建映射,该图像公开。或者使用-p,您可以动态分配映射。 例如:

docker run -d --name my_app -p 5000 -p 6000 my_image // this will map both exposed ports

相同
docker run -d --name my_app -P my_image // this will map all exposed ports (5000 and 5000) 

或者您甚至可以添加其他要暴露的端口

docker run -d --name my_app -expose 8000 -P my_image // now 5000, 6000, 8000 are mapped

或者您可以重新映射到其他端口,例如:

docker run ... -p 3000:4000 ... // 
             host_port:container_port

映射后,您可以查看所有端口映射

docker port my_app(或容器ID而不是my_app)

这会给你这样的东西

5000/tcp -> 0.0.0.0:32773
6000/tcp -> 0.0.0.0:32772
8000/tcp -> 0.0.0.0:32771

答案 1 :(得分:1)

它将侦听端口,但默认情况下不允许从主机访问它。您可以传递-P,例如docker run -P my-docker-image来启动包含主机可访问端口的容器,但您仍需检查群集(docker ps)以查看您拥有的端口在从主机发送请求时使用。

这样您就可以在运行映像时控制它在主机上侦听哪个端口,而不是硬编码值。您可以使用相同的映像启动两个容器,并将单独的主机端口映射到已公开的每个容器/映像端口。

答案 2 :(得分:0)

文档有点令人困惑。

使用默认网桥,主机上运行的所有容器和主机本身都可以通过内部(网桥)相互访问(即所有端口) ip地址(当然除非主机或容器上的防火墙配置为阻止访问)。此行为独立于任何EXPOSE-p-P选项。

由于默认网桥是主机内部网络,因此外部网络上的其他主机无法通过内部网络访问您的容器。这是-p-P选项通过在主机的外部接口上公开转发到容器的端口来实现的。

-p选项要求您指定要转发到的容器端口,但指定主机端口是可选的(如果未指定,将随机选择主机端口)。

-P依靠EXPOSED端口自动设置端口转发到容器的侦听端口。主机端口会自动选中。