将Docker容器连接到远程MySQL数据库

时间:2018-02-07 20:51:59

标签: php mysql windows ubuntu docker

我在运行Docker的Windows 10环境中并行开发Laravel和遗留PHP应用程序。对于遗留的PHP应用程序,我想将开发转移到Docker容器内,但是,我似乎无法将PHP应用程序连接到本地网络上不同Ubuntu服务器上的MySQL数据库。我使用Laradock来简化此类开发环境的docker容器映像和设置。

这是我的设置:

  • Windows 10主机(IP:172.19.0.200) - MySQL服务器未在本地安装
  • Ubuntu MySQL Server(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地址。关于如何从这里开始,我还没有最模糊的想法。想法?

2 个答案:

答案 0 :(得分:0)

docker容器内的内部ip-network与外部ip-networks重叠,或设置为$methodName = $formName."Processor"; //.... $formsProcessor->{$methodName}();` 。如果未设置为host,则会使Linux主机内的路由尝试在本地查找该资源,而不是在Internet上发送请求。

尝试更改容器的网络,如下所示:

host

请记住将docker network create --driver=bridge --subnet=192.168.0.0/16 br0 docker network connect br0 your-nginx-container 替换为正在运行的容器的实际名称。如果您使用your-nginx-container创建容器,则可以通过添加docker create来指定要使用的网桥,其中--network=br0是我们在上面的br0命令中使用的名称。 / p>

修改

看到您的最新docker network create后,我建议您尝试删除其他网络。你能看出这个命令是否有效吗?它应该从容器中删除ifconfig网络驱动程序,希望删除这两个接口。

host

答案 1 :(得分:0)

我用主机IP或网络(都对我有用)解决了laradock .env文件中的DOCKER_HOST_IP设置。

DOCKER_HOST_IP=172.16.4.1

希望可以帮助某人。