【发布时间】:2018-02-07 20:51:59
【问题描述】:
我正在运行 Docker 的 Windows 10 环境中并行开发 Laravel 和旧版 PHP 应用程序。对于旧的 PHP 应用程序,我想将开发转移到 Docker 容器内,但是,我似乎无法让 PHP 应用程序连接到本地网络上不同 Ubuntu 服务器上的 MySQL 数据库。我使用 Laradock 来简化 docker 容器映像和此类开发环境的设置。
这是我的设置:
- Windows 10 主机 (IP: 172.19.0.200) -- MySQL 服务器未安装在本地
- Ubuntu MySQL 服务器(IP:172.19.0.16)
- TeamSQL(MySQL 客户端)
Windows 上 cmd 控制台中 ipconfig 的结果:
Ethernet adapter vEthernet (Default Switch):
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::7ce7:47d:7b91:84a8%9
IPv4 Address. . . . . . . . . . . : 172.31.215.177
Subnet Mask . . . . . . . . . . . : 255.255.255.240
Default Gateway . . . . . . . . . :
Ethernet adapter vEthernet (DockerNAT):
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::8cc5:621:daba:48e3%4
IPv4 Address. . . . . . . . . . . : 10.0.75.1
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . :
Ethernet adapter Local Area Connection:
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::71fc:9102:366c:fb7d%15
IPv4 Address. . . . . . . . . . . : 172.19.0.200
Subnet Mask . . . . . . . . . . . : 255.255.0.0
Default Gateway . . . . . . . . . : 172.19.0.254
来自 Ubuntu 服务器上 ufw status 的结果(显示防火墙规则):
To Action From
-- ------ ----
22 ALLOW 172.19.0.0/24
3306 ALLOW 172.19.0.0/24
80 ALLOW 172.19.0.0/24
80 ALLOW 10.0.75.0/24
3306 ALLOW 10.0.75.0/24
80 ALLOW 172.20.0.0/24
3306 ALLOW 172.20.0.0/24
Ubuntu MySQL 中select host, user from mysql.user 查询的结果:
+----------------+------------------+
| host | user |
+----------------+------------------+
| % | root |
| 10.0.2.2 | root |
| 10.0.75.1 | root |
| 127.0.0.1 | root |
| 172.19.0.% | root |
| 172.19.0.15 | root |
| 172.19.0.16 | root |
| 172.19.0.200 | root |
| 172.19.0.65 | root |
| 172.20.0.1 | root |
| 172.20.0.6 | root |
| 172.31.215.177 | root |
| localhost | root |
+----------------+------------------+
我可以使用 TeamSQL 使用以下连接参数从 Windows 10 系统连接到 Ubuntu MySQL 实例:
Host: 172.19.0.16
Post: 3306
User: root
Password: thisisasamplepassword
所以,我知道至少允许来自 Windows IP 的连接并且凭据有效。
但是,我无法使用此连接字符串从 Docker 容器中的旧 PHP 应用程序进行连接:
$dbHost = "172.19.0.16"
$dbPort = "3306"
$dbName = "databasename"
$dbUser = "root"
$dbPassword = "thisisasamplepassword"
$connectionString = "mysql:host=$dbHost;port=$dbPort;dbname=$dbName;
$instance = new PDO($connectionString, $dbUser, $dbPassword);
当我使用此信息时,我收到SQLSTATE[HY000] [2002] Connection timed out 错误。所以在我的挖掘中,我发现this article 关于使用 PuTTY 通过 SSH 隧道将我的 Ubuntu MySQL 服务器的端口转发到我的 Windows 10 主机。我的想法是,如果我可以将 Ubuntu MySQL 端口转发到我的 Windows 10 端口,然后从 Docker 连接到我的 Windows 10 端口(因为 Windows 10 是主机),那么也许我可以让连接正常工作。我浏览了该教程并打开了 TeamSQL 并按照文章建议使用的方式切换了信息:
Host: 127.0.0.1
Post: 3306
User: root
Password: thisisasamplepassword
我收到“连接丢失:服务器关闭连接”错误。我认为这一定是防火墙问题,所以我关闭了 Windows 防火墙,但仍然无法使用 TeamSQL,但我决定从 PHP 应用程序中尝试。
我将 PHP 应用详细信息更改为:
$dbHost = "127.0.0.1"
$dbPort = "3306"
$dbName = "databasename"
$dbUser = "root"
$dbPassword = "thisisasamplepassword"
现在我在尝试连接时收到SQLSTATE[HY000] [2002] Connection refused 错误。
我一直在研究这个问题几乎令人尴尬的时间。在这一点上,我真的不在乎这是否是一个掌上型答案;我只是想让它工作。当我在 Windows 上使用 XAMPP 时,我的 PHP 应用程序和 Ubuntu MySQL 服务器之间的连接工作正常,但我试图通过使用 Docker 缩小本地开发环境和生产开发环境之间的差距。这就是进行转换的想法。
关于如何解决此问题的任何想法?提前致谢。
编辑
绑定地址已设置为 0.0.0.0,如查询 show global variables like 'bind_address'; 所示:
+---------------+---------+
| Variable_name | Value |
+---------------+---------+
| bind_address | 0.0.0.0 |
+---------------+---------+
1 row in set (0.00 sec)
来自 nginx 容器内 ifconfig 的结果:
eth0 Link encap:Ethernet HWaddr 02:42:AC:14:00:04
inet addr:172.20.0.4 Bcast:172.20.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:612 errors:0 dropped:0 overruns:0 frame:0
TX packets:484 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:136633 (133.4 KiB) TX bytes:98603 (96.2 KiB)
eth1 Link encap:Ethernet HWaddr 02:42:AC:13:00:03
inet addr:172.19.0.3 Bcast:172.19.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:156 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:9832 (9.6 KiB) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:4 errors:0 dropped:0 overruns:0 frame:0
TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:235 (235.0 B) TX bytes:235 (235.0 B)
编辑 2
根据@Canis 的建议,我执行了以下命令:
docker network create --driver=bridge --subnet=192.168.0.0/16 br0
docker network connect br0 laradock_nginx_1
我仍然无法访问 Ubuntu MySQL 容器。以下是ifconfig 的当前结果:
eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:00:02
inet addr:192.168.0.2 Bcast:192.168.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:25 errors:0 dropped:0 overruns:0 frame:0
TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:2154 (2.1 KiB) TX bytes:1209 (1.1 KiB)
eth1 Link encap:Ethernet HWaddr 02:42:AC:13:00:03
inet addr:172.19.0.3 Bcast:172.19.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:12 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:928 (928.0 B) TX bytes:252 (252.0 B)
eth2 Link encap:Ethernet HWaddr 02:42:AC:14:00:04
inet addr:172.20.0.4 Bcast:172.20.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:21 errors:0 dropped:0 overruns:0 frame:0
TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3330 (3.2 KiB) TX bytes:1394 (1.3 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:12 errors:0 dropped:0 overruns:0 frame:0
TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:1131 (1.1 KiB) TX bytes:1131 (1.1 KiB)
看起来 eth1 和 eth2 仍在使用可能冲突的 IP 地址。不过,我对如何从这里开始并没有最模糊的想法。想法?
【问题讨论】:
-
关于您在 docker 容器中使用的 localhost ip:这将指向运行 docker 映像的虚拟 Linux 客户机上的环回地址,而不是 Windows 主机。你能用 curl 或 wget 旋转图像吗?如果是这样,请尝试访问互联网,看看会发生什么。例如:wget google.com。如果能够连接,则至少允许来自容器的传出流量。
-
@Canis 我可以卷曲到 google.com 并收到 html 作为响应,所以很高兴知道。没想过尝试外部站点,只是一个内部 IP。
-
太棒了!然后基本路由按预期工作。从容器到 Ubuntu MySQL 服务器的 ping 怎么样。这能通过吗?如果不是,这些机器是否被 Ubuntu 上的客户端防火墙以外的任何其他防火墙或过滤机制隔开?可能是 VMware 来宾隔离或其他技术的类似内容。
-
您的 MYSQL 服务器是否配置为允许来自 localhost 以外的其他网络的流量?检查这个stackoverflow.com/a/15684341/2894123
-
如果您也可以在容器内发布
ifconfig的转储,那就太好了。
标签: php mysql windows ubuntu docker