在端口监听和访问之间的区别

我实际上是通过Docker文件读取Docker文件。 有一个地方你可以定义容器中的端口是如何暴露的 。 在阅读这个描述时,我发现我在这里理解了一个特殊的区别。

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

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

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

如果应用程序正在监听端口 – 例如,我可以启动一个HTTP请求,它会回答我的问题,对吧? 这不是我作为一个主机在这里定义的外部环境 )的某种访问吗?

文档有点混乱。

使用默认桥接networking,主机上运行的所有容器和主机本身都可以通过其内部 (网桥)IP地址访问彼此(即所有端口)(除非主机或容器上的防火墙被configuration为防止访问)。 此行为与任何EXPOSE-p-P选项无关。

由于默认桥接networking是主机内部的,所以外部networking上的其他主机将无法通过内部networking到达您的容器。 这是-p-P选项的来源,通过公开主机的外部接口上的一个端口转发到一个容器。

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

-P依靠EXPOSED端口自动设置端口转发到一个容器的监听端口。 主机端口被自动select。

Expose只是提供一个提示(信息)哪个端口正在被图像曝光。 假设您正在询问桥接(默认)容器 – 它们是隔离的,无法从主机networking访问,受到主机防火墙的保护。 因此,如果您对入站stream量感兴趣,则需要在主机networking和容器接口之间创build映射。 把它想成就像在特定的港口上打开一扇外部世界的窗口。

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

使用-P (--publish-all)你可以要求Docker守护进程为所有端口创build映射,该映像公开。 或者使用-p你可以dynamic分配映射。 例如 :

 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 

它将在端口上侦听,但不会在主机上默认访问它。 你可以传入-P ,像docker run -P my-docker-image启动一个容器,主机可以访问端口,但是你仍然需要检查集群( docker ps )来查看当你使用哪个端口时从主机发送请求。

这样,您可以控制运行映像时在主机上侦听的端口,而不是硬编码的值。 您可以使用相同的映像旋转两个容器,并将单独的主机端口映射到每个暴露的容器/图像端口。