从 Docker 容器中访问主机上的 MySQL 数据库

Posted

技术标签:

【中文标题】从 Docker 容器中访问主机上的 MySQL 数据库【英文标题】:Accessing MySQL Database on Host Machine from within Dockers Container 【发布时间】:2017-11-30 23:17:00 【问题描述】:

我有一个在 Dockers 容器内运行的 Spring Boot 应用程序。该应用程序提供 REST 端点,可以使用 http://localhost:8080/endpoint 从主机成功调用。以前,当此应用程序在主机上而不是在 Docker 中运行时,我可以在应用程序中使用 jdbc:mariadb://localhost:3308/fi?user=userName&password=thePassword 调用本地 MariaDB。现在应用程序在 Dockers 中运行,连接返回错误:“无法连接到地址=(主机=本地主机)(端口=3308)(类型=主):连接被拒绝(连接被拒绝)”

建立连接的代码sn-p如下:

Connection connection = DriverManager.getConnection("jdbc:mariadb://localhost:3308/fi?user=username&password=thePassword");
        Statement stmt = connection.createStatement();
        String query = "";
        ResultSet rs = stmt.executeQuery("SELECT * ....;");

我已经发布了 8080 端口以接受来自主机的 REST 调用,并尝试发布或公开 3308 端口以允许进行数据库调用,但都没有帮助。

提前谢谢你!

【问题讨论】:

我建议你在另一个容器中运行你的数据库——这是 docker 建议的方式。 除了创建另一个容器并重新设置数据库之外,是否需要进行其他特殊更改以允许一个 docker 中的应用程序调用另一个 docker 中的数据库? 【参考方案1】:

在 docker 中使用数据库的建议方法是在单独的容器中运行它。 Docker 容器在同一个(docker)网络中,所以你只需要link 他们。 Here 你有 MariaDB 图像和如何使用它的指南。您可以将现有数据库转储到您的图像中(因此您无需再次执行所有操作)。

为此,您必须:

    创建新的数据库映像(其中转储数据库) 运行数据库容器(设置名称!) 使用链接执行数据库容器运行 REST 容器

【讨论】:

链接模式是旧模式。相反,建议使用网络服务发现。基本上,只要你的容器都连接到同一个docker network create 类型的网络,它们就可以通过它们的--name 相互解析。 你说得对 - 我是凭记忆写的,我一直使用 --link :)【参考方案2】:

如果您只想进行开发,您可以链接容器,或者更好地使用docker-compose。但请注意:容器中的数据库不用于生产!

从容器中,您可以使用 ip route show 检索 docker 主机 IP

# ip route show
default via 172.17.0.1 dev eth0 
172.17.0.0/16 dev eth0  proto kernel  scope link  src 172.17.0.2

那么默认路由就是你的主机IP(这里是172.17.0.1)

此时,请注意主机的防火墙会阻止连接

在您的入口点脚本中,您可以使用ip route show | awk '/default/ print $3' 检索主机IP。然后您可以通过环境变量传递此 IP 并在您的应用程序中检索它。

【讨论】:

以上是关于从 Docker 容器中访问主机上的 MySQL 数据库的主要内容,如果未能解决你的问题,请参考以下文章

无法从 docker 容器中访问 MacOSX 主机上的端口

无法从我的本地主机访问 docker 上的 apache

docker容器跑起mysql后,在宿主机无法进去mysql?

如何解决docker宿主机无法访问容器中的服务

从 Docker 容器连接到主机上的服务的规范方法

docker中的Spring应用程序如何访问主机或云mysql中的mysql?