如何读取docker端口映射信息?

How to read docker port mapping information?

我刚开始学习docker,我对docker中的端口映射有点困惑。我有如下容器(运行 mysql 服务)运行:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS

59efytd163d3        myapp:mysql         "docker-entrypoint.s…"   10 months ago       Up 5 minutes        0.0.0.0:9991->3306/tcp  

对于PORTS字段,0.0.0.0:9991->3306/tcp是什么意思?

我检查了 mysql 的端口号,即容器外 运行 的端口号:

john@MacBook-Pro:~/Documents$ lsof -n -P -i TCP | grep mysql
mysqld     1742 john   58u  IPv4 0xd3c7de51ef6d2a49      0t0  TCP 127.0.0.1:3306 (LISTEN)

可以看到,端口是3306,所以我以为容器里面的mysql运行的端口号一定是9991,但是进入容器查看后mysql:

mysql> SHOW GLOBAL VARIABLES LIKE 'PORT'
    -> ;
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| port          | 3306  |
+---------------+-------+
1 row in set (0.00 sec)

还显示3306。

容器内外的mysql服务运行的端口号都是3306,那么0.0.0.0:9991->3306/tcp是什么意思呢? 0.0.0.0:9991 指的是什么?

Docker 运行 个虚拟网络上的容器:

docker network ls
NETWORK ID          NAME                 DRIVER              SCOPE
1234567890ab        bridge               bridge              local
cdef01234567        deployment_default   bridge              local
890abcdef012        host                 host                local
34567890abcd        none                 null                local

这些端口映射将您主机上的端口与这些网络上的容器绑定 运行。

将每个容器视为其自己的本地主机,并具有所有可用端口。在这种情况下,您的 MySQL 实例在其容器上公开端口 3306。这是必要的,因为容器中的二进制文件也在 3306 上 运行ning。这解释了为什么在容器中您会看到 3306.

非常方便,当您 运行 一个容器时,Docker 提供了一种机制让您将容器端口(例如 3306)重新映射到不同的端口(例如 9991 ) 在您的主机上。

这不仅仅是一种便利。如果你想要 运行 第二个 MySQL 容器镜像并且它也被配置为 3306,你将无法同时访问两个容器,因为它们会与主机上的端口 3306

因此,您定义了一个 port-mapping。在您的示例中,您可以从本地工作站(主机)访问 localhost:9991 上的 MySQL 容器实例,并且 Docker 将该端口的流量重新映射到 MySQL 容器的端口 3306 并且容器将其路由到 MySQL 二进制文件(也在 3306 上)。

所以:0.0.0.0:9991->3306/tcp 意思是:

  • 0.0.0.0localhost 上任何适配器的别名)
  • 9991 端口流量映射到此容器的端口 3306
  • 使用 TCP(您将看到的另一种协议是 UDP

三个补充说明:

  • 此图片的 Docker 文件可能包含例如EXPOSE 3306。这纯粹是纪录片,绝不会影响 docker run ... --publish=XXXX/3306.. 命令。
  • 容器不需要将端口发布到本地主机。仅当必须从主机访问容器镜像时才需要这样做。如果您命名您的容器并将它们放在 user-defined 网络上或使用 Docker Compose,一个容器可以访问另一个容器上的端口 而不会 将端口暴露给主机。像这样公开端口应该是 (!) 安全考虑。
  • 当您 运行 容器映像时,Docker 使用默认网络。 port-mapping解析(0.0.0.0:XXXX/YYYY)实际上是识别哪个容器(主机名解析)和哪个端口的组合。