介绍
Docker 是一种被广泛采用的容器化技术,它彻底改变了应用程序的开发、打包和部署方式。了解 Docker 容器的暴露端口是使用 Docker 的一个基本方面,因为它允许你访问和与容器内运行的服务进行交互。本教程将指导你检查 Docker 容器的暴露端口的过程,使你能够更好地管理和优化你的容器化应用程序。
Docker 是一种被广泛采用的容器化技术,它彻底改变了应用程序的开发、打包和部署方式。了解 Docker 容器的暴露端口是使用 Docker 的一个基本方面,因为它允许你访问和与容器内运行的服务进行交互。本教程将指导你检查 Docker 容器的暴露端口的过程,使你能够更好地管理和优化你的容器化应用程序。
在我们深入研究检查容器端口之前,让我们首先了解什么是端口以及它们在 Docker 容器中的重要性。
在 Docker 中,端口允许容器内运行的服务与外部世界通信。将端口想象成你容器化应用程序的门——如果不打开这些门,任何人都无法访问里面的服务。
Docker 支持两种主要的端口配置类型:
暴露端口 (Exposed Ports):容器使其可用于潜在连接的端口,但不能从主机自动访问。
发布端口 (Published Ports):映射到主机上端口的暴露端口,允许外部访问容器服务。
让我们运行一个简单的 Web 服务器容器来更好地理解这一点:
docker run -d --name web-demo nginx
在终端中运行此命令。这会以分离模式(在后台运行)启动一个名为 web-demo
的 Nginx Web 服务器容器。
输出将显示一个容器 ID,类似于:
3a6e8df899a9b723de9e4684542dc9987af26381118fa36496757d17ac952c9f
这个 Nginx 容器默认暴露了端口 80(在其 Dockerfile 中定义),但我们尚未将其发布到主机,因此我们无法从外部访问它。
现在我们的容器正在运行,让我们检查一下它的端口配置。
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 web-demo
输出:
80/tcp -> 0.0.0.0:8080
这表明容器中的端口 80/tcp 映射到所有主机接口上的端口 8080。
对于更详细的信息,请使用 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"
}
]
}
这显示了详细的端口映射信息:
如果你有多个容器,你可以使用以下命令查看所有端口映射:
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
现在我们有两个容器运行不同的服务,每个服务都有自己的端口映射。
现在我们了解了如何检查和访问容器化服务,让我们探索一些额外的端口管理概念。
以下是可能遇到的一些常见场景:
如果端口 8080 已经在你的主机上使用,你可以映射到不同的端口:
docker stop web-demo
docker rm web-demo
docker run -d --name web-demo -p 8081:80 nginx
现在可以通过端口 8081 访问 Nginx 容器:
curl localhost:8081
除了绑定到所有接口(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 接口,使其无法从主机外部访问。
如果你不关心使用哪个主机端口,让 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。
以下是针对常见端口相关问题的解决方案:
docker run -d --name another-web -p 8082:80 nginx
host.docker.internal
而不是 localhost
:docker run --rm alpine ping -c 2 host.docker.internal
sudo lsof -i :8080
让我们清理我们的容器:
docker stop web-demo redis-demo
docker rm web-demo redis-demo
在这个实验中,你已经学习了如何使用 Docker 容器端口,包括:
这些技能是使用 Docker 容器的基础,对于在开发和生产环境中部署容器化应用程序至关重要。掌握了这些知识,你现在可以自信地配置和管理 Docker 容器的网络方面。