如何检查 Docker 容器的暴露端口

DockerDockerBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

Docker 是一种被广泛采用的容器化技术,它彻底改变了应用程序的开发、打包和部署方式。了解 Docker 容器的暴露端口是使用 Docker 的一个基本方面,因为它允许你访问和与容器内运行的服务进行交互。本教程将指导你检查 Docker 容器的暴露端口的过程,使你能够更好地管理和优化你的容器化应用程序。

理解 Docker 容器端口

在我们深入研究检查容器端口之前,让我们首先了解什么是端口以及它们在 Docker 容器中的重要性。

什么是容器端口

在 Docker 中,端口允许容器内运行的服务与外部世界通信。将端口想象成你容器化应用程序的门——如果不打开这些门,任何人都无法访问里面的服务。

端口配置的类型

Docker 支持两种主要的端口配置类型:

  1. 暴露端口 (Exposed Ports):容器使其可用于潜在连接的端口,但不能从主机自动访问。

  2. 发布端口 (Published Ports):映射到主机上端口的暴露端口,允许外部访问容器服务。

让我们运行一个简单的 Web 服务器容器来更好地理解这一点:

docker run -d --name web-demo nginx

在终端中运行此命令。这会以分离模式(在后台运行)启动一个名为 web-demo 的 Nginx Web 服务器容器。

输出将显示一个容器 ID,类似于:

3a6e8df899a9b723de9e4684542dc9987af26381118fa36496757d17ac952c9f

这个 Nginx 容器默认暴露了端口 80(在其 Dockerfile 中定义),但我们尚未将其发布到主机,因此我们无法从外部访问它。

检查容器端口配置

现在我们的容器正在运行,让我们检查一下它的端口配置。

使用 docker ps 查看端口映射

docker ps 命令显示正在运行的容器及其端口配置。

在你的终端中运行此命令:

docker ps

你将看到类似于以下的输出:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
3a6e8df899a9   nginx     "/docker-entrypoint.…"   2 minutes ago    Up 2 minutes    80/tcp    web-demo

注意 PORTS 列。它显示 80/tcp,表明端口 80 已暴露但未发布到主机。

运行带有发布端口的容器

让我们停止第一个容器,并创建一个带有发布端口的新容器:

docker stop web-demo
docker rm web-demo

现在运行一个带有端口映射的新容器:

docker run -d --name web-demo -p 8080:80 nginx

-p 8080:80 选项将容器的端口 80 发布到主机上的端口 8080。

再次运行 docker ps 以查看差异:

docker ps

输出:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                  NAMES
f7d483e51ef2   nginx     "/docker-entrypoint.…"   10 seconds ago   Up 10 seconds   0.0.0.0:8080->80/tcp   web-demo

注意 PORTS 列现在如何显示 0.0.0.0:8080->80/tcp,表明容器中的端口 80 映射到所有主机接口上的端口 8080。

检查容器端口详细信息

Docker 提供了多个命令来详细检查容器端口配置。让我们探索这些选项。

使用 docker port 命令

docker port 命令显示容器的端口映射:

docker port web-demo

输出:

80/tcp -> 0.0.0.0:8080

这表明容器中的端口 80/tcp 映射到所有主机接口上的端口 8080。

使用 docker inspect 获取详细信息

对于更详细的信息,请使用 docker inspect 命令:

docker inspect web-demo

此命令会生成大量 JSON 输出,其中包含有关容器的详细信息。要仅过滤端口信息,请使用此命令:

docker inspect --format='{{json .NetworkSettings.Ports}}' web-demo | jq

如果未安装 jq,你可以使用以下命令安装它:

sudo apt-get update && sudo apt-get install -y jq

过滤后的 inspect 命令的输出将如下所示:

{
  "80/tcp": [
    {
      "HostIp": "0.0.0.0",
      "HostPort": "8080"
    }
  ]
}

这显示了详细的端口映射信息:

  • 容器端口:80/tcp
  • 主机 IP:0.0.0.0(所有接口)
  • 主机端口:8080

列出所有容器端口

如果你有多个容器,你可以使用以下命令查看所有端口映射:

docker ps --format "{{.Names}}: {{.Ports}}"

输出:

web-demo: 0.0.0.0:8080->80/tcp

这在管理具有不同端口配置的多个容器时非常有用。

通过暴露的端口访问服务

现在我们了解了如何检查容器端口,让我们访问在容器中运行的 Web 服务器。

测试容器可访问性

由于我们将容器的端口 80 映射到主机上的端口 8080,因此我们可以通过端口 8080 访问 Nginx Web 服务器。

让我们使用 curl 命令向我们的 Web 服务器发出请求:

curl localhost:8080

你应该看到 Nginx 欢迎页面的 HTML:

<!DOCTYPE html>
<html>
  <head>
    <title>Welcome to nginx!</title>
    <style>
      html {
        color-scheme: light dark;
      }
      body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
      }
    </style>
  </head>
  <body>
    <h1>Welcome to nginx!</h1>
    <p>
      If you see this page, the nginx web server is successfully installed and
      working. Further configuration is required.
    </p>

    <p>
      For online documentation and support please refer to
      <a href="http://nginx.org/">nginx.org</a>.<br />
      Commercial support is available at
      <a href="http://nginx.com/">nginx.com</a>.
    </p>

    <p><em>Thank you for using nginx.</em></p>
  </body>
</html>

这确认了我们可以通过发布的端口访问在容器内运行的 Nginx Web 服务器。

运行多个服务

让我们创建另一个具有不同服务和端口映射的容器:

docker run -d --name redis-demo -p 6379:6379 redis

此命令启动一个 Redis 数据库容器,并将其默认端口 6379 映射到主机上的相同端口。

检查正在运行的容器:

docker ps

输出:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                    NAMES
a45df67e21b3   redis     "docker-entrypoint.s…"   10 seconds ago   Up 10 seconds   0.0.0.0:6379->6379/tcp   redis-demo
f7d483e51ef2   nginx     "/docker-entrypoint.…"   10 minutes ago   Up 10 minutes   0.0.0.0:8080->80/tcp     web-demo

现在我们有两个容器运行不同的服务,每个服务都有自己的端口映射。

管理容器端口配置

现在我们了解了如何检查和访问容器化服务,让我们探索一些额外的端口管理概念。

常见的端口管理场景

以下是可能遇到的一些常见场景:

1. 更改端口映射

如果端口 8080 已经在你的主机上使用,你可以映射到不同的端口:

docker stop web-demo
docker rm web-demo
docker run -d --name web-demo -p 8081:80 nginx

现在可以通过端口 8081 访问 Nginx 容器:

curl localhost:8081

2. 绑定到特定接口

除了绑定到所有接口(0.0.0.0),你还可以绑定到特定的 IP:

docker stop web-demo
docker rm web-demo
docker run -d --name web-demo -p 127.0.0.1:8080:80 nginx

这会将容器端口仅绑定到 localhost 接口,使其无法从主机外部访问。

3. 使用随机主机端口

如果你不关心使用哪个主机端口,让 Docker 分配一个:

docker stop web-demo
docker rm web-demo
docker run -d --name web-demo -P nginx

-P 标志将所有暴露的端口发布到主机上的随机端口。

检查分配的端口:

docker port web-demo

输出:

80/tcp -> 0.0.0.0:49153

确切的端口号会有所不同,但在本例中,端口 80 被映射到端口 49153。

解决常见的端口问题

以下是针对常见端口相关问题的解决方案:

  1. 端口已在使用中:如果你看到类似“端口已分配”的错误,请选择不同的端口:
docker run -d --name another-web -p 8082:80 nginx
  1. 容器无法连接到主机:如果容器需要连接到主机上的服务,请使用特殊的 Docker DNS 名称 host.docker.internal 而不是 localhost
docker run --rm alpine ping -c 2 host.docker.internal
  1. 检查哪个进程使用了端口:如果主机上某个端口已在使用中,请查找该进程:
sudo lsof -i :8080

清理

让我们清理我们的容器:

docker stop web-demo redis-demo
docker rm web-demo redis-demo

总结

在这个实验中,你已经学习了如何使用 Docker 容器端口,包括:

  • 了解暴露端口和发布端口之间的区别
  • 使用特定的端口映射运行容器
  • 使用各种 Docker 命令检查容器端口配置
  • 通过映射端口访问在容器内运行的服务
  • 管理和解决常见的端口相关场景

这些技能是使用 Docker 容器的基础,对于在开发和生产环境中部署容器化应用程序至关重要。掌握了这些知识,你现在可以自信地配置和管理 Docker 容器的网络方面。