【问题标题】:How to read docker port mapping information?如何读取 docker 端口映射信息?
【发布时间】:2019-07-08 16:04:35
【问题描述】:

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

【问题讨论】:

    标签: mysql docker port


    【解决方案1】:

    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 二进制文件(也在 @ 987654331@).

    所以: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) 实际上是识别哪个容器(主机名解析)和哪个端口的组合。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-05
      • 1970-01-01
      • 1970-01-01
      • 2017-08-02
      • 1970-01-01
      • 2022-10-17
      • 2014-12-14
      • 1970-01-01
      相关资源
      最近更新 更多