我刚刚开始学习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
指的是什么?
答案 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.0
(localhost
上任何适配器的别名)9991
端口流量映射到此容器的端口3306
UDP
)三个附加说明:
EXPOSE 3306
。这纯粹是纪录片,绝不会影响docker run ... --publish=XXXX/3306..
命令。0.0.0.0:XXXX/YYYY
)实际上是标识哪个容器(主机名分辨率)和哪个端口的组合。