我实际上正在阅读Docker文件的Docker文档。您可以在其中定义容器中的端口公开的方式。在阅读该描述时,我发现我在这里理解一个特定的差异时遇到了问题。
来自:https://docs.docker.com/engine/reference/builder/#expose
EXPOSE指令通知Docker容器在运行时侦听指定的网络端口。 EXPOSE不会使容器的端口可供主机访问。
收听端口并使其可访问的容器(或服务器应用程序)之间有什么区别?
如果应用程序正在侦听端口 - 我可以在其上启动HTTP请求,它会回答我,对吧?是不是某种访问我必须将其作为主机(在此定义外部上下文)?
答案 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端口自动设置端口转发到容器的侦听端口。主机端口会自动选中。