1. 概述
在 Docker 中,了解容器化应用程序监听的端口至关重要。我们还需要一种方法从外部访问应用程序。
为了应对这些关切,Docker 允许我们暴露并发布端口。
本文将学习如何暴露和发布端口。我们将使用简单的 Nginx Web 服务器容器作为示例。
2. 暴露端口
暴露的端口是关于容器化应用程序的元数据。在大多数情况下,这显示了应用程序正在监听的端口。Docker 自身不会对暴露的端口做任何事情。然而,在启动容器时,我们可以利用此元数据来发布端口。
2.1. 使用 Nginx 暴露端口
让我们使用 Nginx Web 服务器来尝试一下。
如果查看 Nginx 官方 Dockerfile,我们会看到使用以下命令暴露了端口 80:
EXPOSE 80
端口 80 在这里被暴露,因为它默认是 HTTP 协议的端口。让我们在本地机器上运行 Nginx 容器,并查看是否可以通过端口 80 访问它:
$ docker run -d nginx
上述命令将使用 Nginx 的最新镜像并运行容器。我们可以使用以下命令再次检查 Nginx 容器是否正在运行:
$ docker container ls
此命令将输出有关所有运行容器的信息,包括 Nginx:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cbc2f10f787f nginx "/docker-entrypoint..." 15 seconds ago Up 15 seconds 80/tcp dazzling_mclean
在这里,我们看到端口部分有 80。既然端口 80 已被暴露,我们可能会认为通过 localhost:80(或仅 localhost)可以显示 Nginx 的默认页面,但这并非如此:
$ curl http://localhost:8080
... no web page appears
尽管端口已暴露,但 Docker 并没有打开它以供主机使用。
2.2. 暴露端口的方法
在 Docker 中暴露端口主要有两种方式。我们可以在 Dockerfile 中使用 EXPOSE 命令进行操作:
EXPOSE 8765
或者,我们也可以在运行容器时使用 –expose 选项暴露端口:
$ docker run --expose 8765 nginx
3. 发布端口
对于容器端口要在主机上可访问,我们需要发布它。
3.1. 使用 Nginx 发布端口
让我们使用映射端口来运行 Nginx:
$ docker run -d -p 8080:80 nginx
上述命令将主机的端口 8080 映射到容器的端口 80。选项的一般语法如下:
-p <hostport>:<container port>
如果我们访问 localhost:8080,我们应该会收到 Nginx 的默认欢迎页面:
$ curl http://localhost:8080
StatusCode : 200
StatusDescription : OK
Content : <!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
... more HTML
让我们列出所有正在运行的容器:
$ docker container ls
现在我们应能看到容器具有端口映射:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
38cfed3c61ea nginx "/docker-entrypoint..." 31 seconds ago Up 30 seconds 0.0.0.0:8080->80/tcp dazzling_kowalevski
在 ports 部分,我们有一个 0.0.0.0:8080->80/tcp 映射。
默认情况下,Docker 为主机添加了一个非路由元地址 0.0.0.0。这意味着映射适用于主机的所有地址/接口。
3.2. 限制容器访问
我们可以根据主机 IP 地址限制对容器的访问。 而不是允许来自所有接口(0.0.0.0 所做的那样),我们可以指定主机 IP 地址作为映射的一部分。
让我们仅限制来自 127.0.0.1 循环回路地址的访问:
$ docker run -d -p 127.0.0.1:8081:80 nginx
在这种情况下,容器仅可以从主机本身访问。这使用了发布的扩展语法,其中包含地址绑定:
-p <binding address>:<hostport>:<container port>
4. 发布所有暴露的端口
暴露的端口元数据可用于启动容器,因为 Docker 给我们提供了发布所有暴露端口的能力:
$ docker run -d --publish-all nginx
在这里,Docker 将容器中暴露的所有端口绑定到主机上的自由随机端口。
让我们看看此命令启动的容器:
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0a23e78732ce nginx "/docker-entrypoint..." 6 minutes ago Up 6 minutes 0.0.0.0:32768->80/tcp pedantic_curran
正如我们所期望的,Docker 从主机选择了随机端口(本例中为 32768)并将其映射到暴露的端口。
5. 总结
在本文中,我们学习了如何在 Docker 中暴露和发布端口。
我们也讨论了暴露的端口是关于容器化应用程序的元数据,而发布端口是一种从主机访问应用程序的方法。