今天在做mybatis项目的数据库连接池部分时,在使用简单实现的非池化数据源(封装JDBC)创建数据库连接时出现了如下报错,而使用Druid数据源就不会:
问题解决
参照回答https://stackoverflow.com/questions/17975120/access-denied-for-user-rootlocalhost-using-password-yes-no-privileges,在数据库中用下列命令解决了问题:
CREATE USER 'phuan'@'192.168.65.1' IDENTIFIED WITH mysql_native_password BY '123456';
SHOW GRANTS FOR 'phuan'@'192.168.65.1';
GRANT ALL PRIVILEGES ON *.* TO 'phuan'@'192.168.65.1';
FLUSH PRIVILEGES;
推测问题的原因是:
mysql装在docker下,且权限设置如下:
可以看到仅能从本地主机连接。
docker在默认情况下,所有容器都是以bridge方式连接到Docker的同一个虚拟网桥docker0上。主机可以直接访问到这些容器。我们配置的是127.0.0.1:13306的数据库地址,为什么不在本地了呢?初步推断问题应该出在docker的网络配置上。
为什么会是192.168.65.1?
在安装Docker的时候,会在宿主机安装一个虚拟网关
docker0
,但是,不同系统下宿主机的IP是不同的,例如Linux下一般是172.17.0.1
, macOS下一般是192.168.65.1
。博主使用的是mac系统,所以是192.168.65.
1。
上面是在其他博主看到的解释,但是实际上,通过 docker network inspect bridge
查看 bridge 的详细信息发现,docker的地址确实是172.17.0.1
。那是什么原因导致mysql容器收到的请求是来自192.168.65.1
的?
实际上是更深层的原因是:Docker for Mac 使用由 HyperKit 创建的 Linux虚拟机 来存储和运行Mac上的容器。也就是说,macOS上的 Docker 实际上是在Linux虚拟机中运行的Docker容器。
docker0配置在虚拟机中,所以运行 docker network inspect bridge 时,查看的到是 Linux 虚拟机内部的 docker0 网络配置。那确实是172.17.0.1
。在虚拟机中运行ifconfig如下:
moby:~# ifconfig
docker0 Link encap:Ethernet HWaddr 02:42:00:CF:6F:AD
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::42:ff:fecf:6fad%32719/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:77 errors:0 dropped:0 overruns:0 frame:0
TX packets:58 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:4151 (4.0 KiB) TX bytes:28040 (27.3 KiB)
eth0 Link encap:Ethernet HWaddr C0:FF:EE:C0:FF:EE
inet addr:192.168.65.2 Bcast:192.168.65.7 Mask:255.255.255.248
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:109 errors:0 dropped:0 overruns:0 frame:0
TX packets:112 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:45044 (43.9 KiB) TX bytes:8691 (8.4 KiB)
可以看出这个虚拟机的对外网卡eth0的ip是192.168.65.2
,合理推断宿主机的ip地址就是192.168.65.1
!!!
因此,Mac host 向 虚拟机的docker0网关 发送请求,在虚拟机的视角下,这个请求是来自192.168.65.1
,这就能就是为什么mysql会拒绝这个请求了。
备注:
HyperKit是专为macOS系统设计的轻量级虚拟化工具包,在Docker for Mac等桌面应用程序版本构建中扮演了重要角色。详细情况请参考这篇文章:https://www.showapi.com/news/article/66f81d1b4ddd79f11a1fde29