抬头仰望星空,是否能发现自己的渺小。

伪斜杠青年

人们总是混淆了欲望和理想

Docker 端口映射理解错误导致的 mysqli::real_connect(): (HY000/2002) 问题

这些天在做服务器的容器化,说起来没什么特殊的,就是日常折腾,docker 也玩了很久了,本来想着一切迁移正常,但凡事都有例外。为了方便说明,这里用 MySQL 和 phpMyAdmin 做例子。

这是之前本地使用的 compose 文件,aos 是一个自建网络,bridge 驱动,docker network create 直接创建的。

MySQL:

version: '3'
 services:
   mysql8:
     image: mysql:8
     container_name: mysql8
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     networks:
       - wpsite
     ports:
       - "3308:3306"
     environment:
       MYSQL_ROOT_PASSWORD: pwd
 networks:
   wpsite:
     name: aos
 volumes:
   db_data:

phpMyAdmin:

version: "3"
 services:
   phpmyadmin:
     image: phpmyadmin
     container_name: phpmyadmin
     restart: always
     ports:
       - 8080:80
     environment:
       PMA_HOST: mysql8
       PMA_PORT: 3306
       MYSQL_ROOT_PASSWORD: pwd
     networks:
       - wpsite
 networks:
   wpsite:
     name: aos
 volumes:
   db_data:

按这两个配置,打开 phpMyAdmin 是可以直接连接到 SQL 数据库一番风顺的,因为在本地一直都是这样跑来调试。但,因为要上云,要保证数据切换的无感知,所以我将 mysql 的映射端口进行了修改,由 3306 改为了 3308,同时将 phpMyAdmin 的环境变量 PMA_HOST 也改为了 3308 。上云后问题就出现了:

mysqli::real_connect(): php_network_getaddresses: getaddrinfo failed: Name or service not known

这个提示其实已经很清楚了,但问题就在于它提示得太清楚了!!!同时网上又有很多迷惑信息,导致了我百思不得其解。首选我在 phpMyAdmin 上 pingSQL 容器(很可惜这里没去 ping 端口),可以 ping 通,看 SQL 容器日志,日志显示 3306 端口监听中,一切都很正常。所以后来,我在想是不是 tcp6 的问题,但通过了解IPV6相关的东西,知道在监听 :: 地址的情况下,IPV4 的请求也是会兼容的,后来又去看 root 用户访问权限等等。再后来经过和别人的 compose 文件对比,不断的创建重试,总算是发现了猫腻。首先需要理解 端口暴露的意义,端口暴露是为了方便容器与宿主机器的通信,而不是容器间通信。

问题就在这里,容器之间所处的环境是与宿主隔离的,也就是说,容器间的端口访问不会受端口暴露影响。容器间通信,不暴露端口也是可以的,拿上面问题说就是,不论 SQL容器对外暴露为 3308,还是 3309, 这都不重要,容器间访问依旧是 3306,所以解决上面改完端口后的连接问题的办法就是,phpMyAdmin 的 PMA_HOST 依旧保持 3306 ,因为这是容器互联,如果说宿主机器上有 SQL 相关的管理软件需要连接,那么才是需要将端口改为 3308

所有简单的问题复杂化后,解决办法往往都非常简单,都是细节问题!!!


本站由以下主机服务商提供服务支持:

0条评论

发表评论