Docker - 端口管理



根据设计,Docker 容器是隔离的,将内部端口保留给自己,不允许响应外部。可以在使用-p--publish Docker 标志创建容器时完成 Docker 主机上端口的此配置;然后,它允许发布端口。此映射使容器内运行的应用程序可访问,因为它们接收来自外部源的流量。可以为一个容器启用多个端口映射,这可以满足在同一容器内运行各种服务的场景。

此外,Docker Compose 为多容器应用程序抽象了端口映射的复杂性。通过定义所有服务及其端口映射的 docker-compose.yml 文件,Docker Compose 可以更轻松地创建和连接容器。这样做是为了自动分配唯一的端口,以避免冲突,从而使应用程序中容器之间的通信变得轻松。

能够避免冲突并使通信无缝进行,使其能够有效地控制端口,因此成为增强从开发到复杂应用程序部署工作流程的非常有用的工具。它是管理容器化环境的宝贵工具。

在本章中,让我们详细了解 Docker 端口管理。

EXPOSE 与 PUBLISH:了解差异

EXPOSE 和 PUBLISH(或 -p)都处理 Docker 中的端口,但它们是两个不同的东西 -

EXPOSE

EXPOSE 充当有关容器化应用程序打算用于通信的端口的文档。它是 Dockerfile 中的一条指令,让任何构建或运行容器的人都知道它可以提供的潜在服务。

但请记住,仅 EXPOSE 不会使这些容器端口在容器外部可访问;该指令本身或多或少充当开发人员或系统管理员的注释。

PUBLISH

这是实际的端口映射。当您发布端口时,即当您在 docker run 中包含 -p 或在 docker-compose.yml 中包含 ports 部分时,您就是在 Docker 容器中的某个端口与 Docker 主机上的端口之间建立关联。这就是使外部流量能够访问容器内运行的应用程序的原因,即您公开的“意图”成为现实的地方。

如何在 Docker 中使用 PUBLISH 公开端口?

Docker 提出了几种可以做到这一点的方法,但最直接且最广为人知的方法是在运行容器时使用 -p。以下是一个示例 -

基本语法

在运行 Docker 容器时公开端口的基本语法为 -

$ docker run -p <host_port>:<container_port> <image_name>
  • <host_port> − 这表示您要在 Docker 主机上公开应用程序的端口号。
  • <container_port> − 容器中您的应用程序侦听流量的端口号。
  • <image_name> − 您要运行的 Docker 镜像的名称。

示例:公共 Web 服务器端口

例如,您有一个应用程序配置为在容器中的端口 80 上运行 Web 服务器。您可以通过执行以下操作将其映射到本地机器端口 8080 -

$ docker run -p 8080:80 <your_web_server_image>

现在,您可以使用您喜欢的 Web 浏览器打开https://:8080并查看您的应用程序正在提供服务!

在 Docker 中发布多个端口

如果您的应用程序需要打开多个端口,您可以多次添加-p标志。

$ docker run -p 8080:80 -p 4433:443 <your_app_image>

这将主机上的端口 80(用于 HTTP)和端口 443(用于 HTTPS)公开到服务。

使用 Docker Compose 发布端口

使用 Docker Compose 为多容器应用程序维护端口映射非常简单。您可以在 docker-compose.yml 文件中每个服务的 ports 部分内执行此操作 -

services:
   web:
      image: <your_web_server_image>
      ports:
      - "8080:80"
   db:
      image: <your_database_image>
      # ... other configurations

关键注意事项

  • 端口冲突 − 确保您自己选择的端口尚未被系统中的任何其他应用程序或服务使用。
  • 防火墙 − 如果 Docker 在远程服务器上运行,您可能需要配置防火墙以允许跨公开端口的流量。
  • 安全 − Docker 漏洞很容易暴露 - 您的端口将被暴露,攻击者可以入侵容器。请考虑使用反向代理或其他安全措施来保护您的容器。

如何在 Dockerfile 中公开端口?

虽然 Dockerfile 中的 `EXPOSE` 指令不会发布端口,但它提供了有关容器在运行时预期侦听的端口的信息。实际上,它记录了 Docker 镜像将使用的端口,以便用户知道他们可以考虑在容器中发布哪些端口。以下是在 Dockerfile 中定义它的方法 -

EXPOSE 指令

语法很简单 -

EXPOSE <port> [<port>/<protocol>]
  • `<port>` − 您希望公开的端口。
  • `<protocol>` − 可选,默认为 TCP。可以是 TCP 或 UDP。

示例:公开 Web 服务器端口

在 Web 服务器镜像的 Dockerfile 中,您将拥有 -

# ... other Dockerfile instructions
EXPOSE 80

这会通知任何查看您的镜像的人,内部应用程序很可能正在侦听端口 80(标准 HTTP 端口)上的传入连接。

打开多个端口和协议

您可以在 Dockerfile 中拥有多个 `EXPOSE` -

EXPOSE 80
EXPOSE 443/tcp
EXPOSE 443/udp

这意味着您的应用程序默认使用 TCP 端口 80 和 TCP/UDP 端口 443。

关键要点

`EXPOSE` 不是必需的;但是,记录容器的网络使用情况是一个好习惯。

它不会将端口发布到主机 - 执行此操作仍然需要在运行容器时使用 `-p` 或在 `docker-compose.yml` 文件中定义 `ports`。

当从您的 Dockerfile 构建镜像时,来自 `EXPOSE` 的指令会在图片的元数据中自动记下注释,您可以使用`docker inspects <image_name>`公开它。

Dockerfile 和运行容器

FROM nginx

EXPOSE 80

# ... any additional configuration you need

运行此容器,Web 服务器现在可以在主机的端口 8080 上访问 -

$ docker run -p 8080:80 <your_nginx_image>

结论

掌握 Docker 中的端口管理对于任何处理容器中运行的应用程序的人员至关重要。了解 EXPOSE 和 PUBLISH 之间的区别并应用公开端口的最佳实践,确保所有容器通信都与外部世界完美配合。

无论您是开发简单的应用程序还是管理规模庞大的多容器环境,Docker 端口管理都具有灵活性和控制能力,可以创建有效且可访问的解决方案。

在继续您的 Docker 之旅时,请始终考虑安全最佳实践。请记住保持端口映射更新,使用安全的通信协议,并考虑更多安全层 - 例如,反向代理。然后,这使您能够充分利用 Docker 的强大功能,同时通过专注于积极主动来保护应用程序和基础设施安全。

常见问题解答

问 1. docker 中 EXPOSE 和 -p(或 PUBLISH)有什么区别?

它们都处理端口,但方式完全不同。EXPOSE 是 Dockerfile 中的一条指令,它更像是一个规则语句,用于描述您的应用程序将利用哪些端口进行通信。

将其视为构建或运行您的容器的人员的友好注释。另一方面,-p 或 PUBLISH 是一个实际的运行时命令,用于将 Docker 主机上的端口映射到容器中的端口,以使您的应用程序可从外部访问。

问 2. 即使在公开端口后,为什么也无法访问我的应用程序?

这里可能有几个罪魁祸首。确保主机上的防火墙没有阻止在此公开端口上的流量。确保您没有选择已被其他应用程序使用的端口。

如果您在某些虚拟机或远程服务器上运行 Docker,请再次确保网络配置正确。最后,请确保您提供的端口映射(主机端口到容器端口)是正确的,并且与应用程序的配置方式相符。

问 3. 如何为单个容器公开多个端口?

Docker 可以轻松地管理它。只需为您的 docker run 命令指定多个 -- -p 标志,每个标志都有不同的端口映射即可。当使用 Docker Compose 时,必须在 docker-compose.yml 文件的 ports 部分中进行多个映射。

每个映射将为外部流量提供一条通往容器内运行的不同服务或组件的单独路径。

问 4. 在 Docker 中公开端口安全吗?

每个为访问您的应用程序而公开的端口都会为潜在攻击者创建越来越大的攻击面。请遵守所有安全最佳实践以减少风险。启用强身份验证,仅允许来自受信任来源的访问,并可能添加更多安全层,例如反向代理或防火墙。

监视系统并在常规更新可用时更新 Docker 镜像以修补已知的漏洞。

问 5. 在 Docker 中管理端口时应避免哪些常见错误?

最常见的错误是在端口公开方面存在安全疏忽,将应用程序暴露给攻击者。另一个是使用先前启动的其他服务使用的端口;在这种情况下,会出现冲突。

在端口映射方面要非常小心,并确保主机上的正确端口和容器内的正确端口连接。

最后,别忘了记录你的端口映射,无论是在 Dockerfile 中使用 EXPOSE 还是在项目文档中,以便你或其他人将来可以轻松参考。

广告

© . All rights reserved.