服务部署:解决Docker容器与虚拟机主机之间MySql连接访问问题

一、场景:

虚拟机上Ubuntu系统安装了Mysql,现在有一个服务应用需要使用docker来部署,服务应用需要连接mysql做数据库基础使用,配置文件中配置了虚拟主机的IP和端口,但是还是无法连接到Mysql,报错无法连接超时异常

复制代码
Caused by: java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:111)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:98)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:90)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:64)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:74)
	at com.mysql.cj.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:885)
	at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:810)
	at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:438)
	at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241)
	at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189)
	at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
	at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
	at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
	at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
	at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
	at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
	at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
	at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160)
	at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118)
	at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81)
	... 25 common frames omitted

二、解决方案

要让 Docker 容器中的应用访问主机上的 MySQL 数据库,你需要确保以下几点:

  1. MySQL 服务在主机上正常运行
  2. Docker 容器可以通过网络访问主机的 MySQL 服务

1. 确保 MySQL 服务在主机上正常运行

首先,确保 MySQL 服务在你的 Ubuntu 主机上正常运行,并且你可以通过命令行或其他客户端工具连接到 MySQL。

复制代码
sudo systemctl status mysql

如果 MySQL 没有运行,可以启动它:

复制代码
sudo systemctl start mysql

2. 获取虚拟主机IP

方法 2:使用 ip addr 命令

在虚拟机的终端中执行以下命令:

复制代码
ip addr show

这个命令会显示所有网络接口的信息。找到与你的网络连接相关的接口(例如 eth0wlan0),并查看其 inet 地址。例如:

复制代码
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:53:8b:dc brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.100/24 brd 192.168.1.255 scope global dynamic eth0
       valid_lft 86396sec preferred_lft 86396sec
    inet6 fe80::a00:27ff:fe53:8bdc/64 scope link 
       valid_lft forever preferred_lft forever

在上面的示例中,inet 192.168.1.100/24 表示虚拟机的 IP 地址是 192.168.1.100

方法 3:使用 ifconfig 命令

如果你的系统安装了 net-tools 包,你可以使用 ifconfig 命令:

复制代码
ifconfig

类似于 ip addr show,这个命令也会显示所有网络接口的信息。找到与你的网络连接相关的接口,并查看其 inet 地址。例如:

复制代码
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.100  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::a00:27ff:fe53:8bdc  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:53:8b:dc  txqueuelen 1000  (Ethernet)
        RX packets 12345  bytes 67890123 (67.8 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 54321  bytes 12345678 (12.3 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

在上面的示例中,inet 192.168.1.100 表示虚拟机的 IP 地址是 192.168.1.100

3. 查看docker容器是否可以访问虚拟主机和Mysql

首先确保容器已经启动。

方法1:

在 Docker 容器中执行以下命令,验证是否能够访问虚拟机上的 MySQL 服务:

复制代码
docker exec -it yourappcontainer ping 192.168.1.100

如果能 ping 通虚拟机,再尝试通过 telnet 连接 MySQL 端口:

复制代码
docker exec -it yourappcontainer telnet 192.168.1.100 3306

如果 telnet 成功,说明网络连接没有问题。如果失败,请检查防火墙设置和 Docker 网络配置。

方法2 :

如果你需要进入容器进行调试或其他操作,可以使用 docker exec 命令:

复制代码
docker exec -it yourappcontainer /bin/bash

这将打开一个交互式的 Bash shell,让你可以在容器内执行命令。

例证:

这里展示我的虚拟机结果(使用docker exec 命令打开一个交互式的 Bash shell):

1、ip可以ping通

复制代码
root@580c2f50a2d2:/# ping 10.0.2.15
PING 10.0.2.15 (10.0.2.15) 56(84) bytes of data.
64 bytes from 10.0.2.15: icmp_seq=1 ttl=64 time=0.032 ms
64 bytes from 10.0.2.15: icmp_seq=2 ttl=64 time=0.049 ms
64 bytes from 10.0.2.15: icmp_seq=3 ttl=64 time=0.055 ms
64 bytes from 10.0.2.15: icmp_seq=4 ttl=64 time=0.035 ms
64 bytes from 10.0.2.15: icmp_seq=5 ttl=64 time=0.033 ms
^C
--- 10.0.2.15 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4102ms
rtt min/avg/max/mdev = 0.032/0.040/0.055/0.009 ms

2、mysql(默认3306端口)telnet不通

复制代码
root@580c2f50a2d2:/# telnet 10.0.2.15 3306
Trying 10.0.2.15...
telnet: Unable to connect to remote host: Connection refused

3、检查配置防火墙

确保防火墙允许从 Docker 容器的 IP 地址访问 MySQL 端口。你可以使用 ufw 来管理防火墙规则:

复制代码
sudo ufw allow 3306/tcp
sudo ufw reload

4、再次telnet

复制代码
root@580c2f50a2d2:/# telnet 10.0.2.15 3306
Trying 10.0.2.15...
Connected to 10.0.2.15.
Escape character is '^]'.
CHost '172.17.0.2' is not allowed to connect to this MySQL serverConnection closed by foreign host.

这个错误信息表明你的 Docker 容器已经成功连接到 MySQL 服务器,但由于权限问题,MySQL 拒绝了连接请求。具体来说,MySQL 配置不允许来自 172.17.0.2(Docker 容器的 IP 地址)的连接。

接着往下操作。

4. 配置 MySQL 允许远程访问

默认情况下,MySQL 只允许本地连接。你需要修改 MySQL 配置文件以允许远程访问。

步骤1:检查Mysql配置并修改

编辑 MySQL 配置文件(通常位于 /etc/mysql/mysql.conf.d/mysqld.cnf/etc/mysql/my.cnf):

复制代码
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

找到 bind-address 行,将其注释掉或者改为 0.0.0.0

复制代码
# bind-address = 127.0.0.1
bind-address = 0.0.0.0

保存并关闭文件。

步骤2:授予远程访问权限

查看想要用于登录连接的账号权限:比如root账号

1、确保你已经以 root 用户身份登录到 MySQL 数据库:

复制代码
mysql -u root -p

输入你的 MySQL root 用户密码。

2、指定到mqsql数据库

复制代码
use mysql;

3、查看账号权限:

复制代码
SELECT Host,User FROM user where User='root';

结果:

Host列为localhost说明该账号只允许从本地主机使用连接。

4、修改访问权限

执行以下 SQL 命令,授予 root 用户从任何主机(即 %)连接的权限:

复制代码
update  user set Host = '%' where User='root';
步骤3:重启 MySQL 服务
复制代码
sudo systemctl restart mysql

root账号是为了演示作用,也可以新建一个账号,授予权限。

至此,docker容器的用于可以连接登录访问虚拟机主机的Mysql应用了。

三、总结

通过以上步骤,你可以解决 MySQL 远程连接的问题。确保防火墙和网络配置正确,MySQL 配置允许远程连接,并且用户具有适当的权限。如果仍然遇到问题,请检查 MySQL 日志文件(通常位于 /var/log/mysql/)以获取更多信息。

相关推荐
用户13573999256601 分钟前
Windows 从 0 搭建 WSL2 原生 AI 开发环境:Codex + Docker + VSCode
docker
程序员小崔日记23 分钟前
一篇文章彻底搞懂 MySQL 和 Redis:原理、区别、项目用法全解析(建议收藏)
redis·mysql·项目实战
vi_h1 小时前
在 macOS 上通过 Docker 安装并运行 Ollama(详细可执行教程)
macos·docker·ollama
黑心老魔1 小时前
通过 Docker 创建开发环境
docker·开发环境
IvorySQL2 小时前
PostgreSQL 技术日报 (3月5日)|规划器控制力升级,内核能力再进阶
数据库·postgresql·开源
武子康2 小时前
大数据-241 离线数仓 - 实战:电商核心交易数据模型与 MySQL 源表设计(订单/商品/品类/店铺/支付)
大数据·后端·mysql
冬奇Lab15 小时前
一天一个开源项目(第41篇):Workout.cool - 现代化开源健身教练平台,训练计划与进度追踪
docker·开源·资讯
数据组小组16 小时前
免费数据库管理工具深度横评:NineData 社区版、Bytebase 社区版、Archery,2026 年开发者该选哪个?
数据库·测试·数据库管理工具·数据复制·迁移工具·ninedata社区版·naivicat平替
用户83071968408220 小时前
MySQL 查询优化 30 条封神技巧:用好索引,少耗资源,查询快到飞起
mysql
天朝八阿哥1 天前
使用Docker+vscode搭建离线的go开发调试环境
后端·docker·visual studio code