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

时间:2019-07-08 16:04:35

标签: mysql docker port

我刚刚开始学习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指的是什么?

1 个答案:

答案 0 :(得分:2)

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上运行。这说明了为什么在容器中看到3306

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

这不仅仅是一种便利。如果您要运行第二个MySQL容器映像,并且还为3306配置了该映像,则您将无法同时访问这两个容器,因为它们与您端口上的端口3306冲突主机。

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

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

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

三个附加说明:

  • 此映像的Dockerfile可能包含例如EXPOSE 3306。这纯粹是纪录片,绝不会影响docker run ... --publish=XXXX/3306..命令。
  • 容器不需要将端口发布到本地主机。仅当必须从主机访问容器映像时才需要执行此操作。如果您命名容器并将其放在用户定义的网络上或使用Docker Compose,则一个容器可以访问另一个容器上的端口而不会将端口暴露给主机。公开这样的端口应该是(!)安全考虑。
  • 运行容器映像时,Docker使用默认网络。端口映射分辨率(0.0.0.0:XXXX/YYYY)实际上是标识哪个容器(主机名分辨率)和哪个端口的组合。