解决Linux虚拟机中启动的MySQL数据库,在宿主机中无法连接的问题

2,929 阅读6分钟

1.前言

    在Ubuntu虚拟机中运行Linux系统,使用docker启动MySQL(8.0版本 )数据库,宿主机尝试采用Navicat Premimu连接,但是测试连接时出现"Access denied for user ‘root’@’localhost’ (using password: YES)",如下图1所示:

2.解决方案

     1.首先根据提示信息的字面意思,我密码是输入进去了,但是访问被拒绝。有可能是密码错误的问题,也有可能是权限的问题。但是我在虚拟机中启动MySQL的命令:

docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -d mysql:8.0

密码写的清清楚楚,不至于输错密码。权限的话,我上MySQL上看了下:

use mysql;
select host,user from user;

也给root用户设置为可以远程访问了。--%表示允许所有的远程地址访问。
     注意:如果发现自己的root权限不够,可以进入mysql,使用命令为root设置权限:

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'youpassword' WITH GRANT OPTION;

     需要注意的是:这种写法是不支持MySQL8.0及以上版本的,对于8.0及以上版,可以使用:

grant all on *.* to 'root'@'%';

     2.在经过一番搜索后,大概明白了问题出在哪里,由于MySQL首次安装后,root的密码是随机的,所以需要对root密码进行修改。操作如下:

docker exec -it mysql bash;                        ---进入docker的bash
mysql -u root -p;                                  ---登录mysql
set password for 'root'@'%'='password';            ---设置root用户的密码为password
flush privileges;                                  ---刷新用户信息

重启MySQL后,发现能够连接该数据库。

3.设置静态IP

     本以为这样MySQL就可以正常连接了,由于我是在虚拟机中使用docker方式启动的MySQL,并且VirtualBox中设置该虚拟机的网络连接方式为桥接模式,所以无法使用LocatHost连接,在连接MySQL时需要输入虚拟机的IP地址,如下图所示:

但是每次重启虚拟机,或者接入另一个局域网,虚拟机的IP地址都会变,这样就很麻烦。所以需要为虚拟机设置静态IP地址。
     在VirtualBox中新增一个网卡,点击勾选DHCP服务器:

    接下来在宿主机上更改适配器,设置这两个网卡:

将能够上网的适配器共享给其他网络:

这时候系统一般会提醒你这个操作会修改#2网卡的IP,我们可以手动修改回来:

在启动虚拟机之前,为虚拟机选中刚刚设置好的网卡:
进入虚拟机,使用ifconfig命令查看虚拟机的网卡信息:

将enp0s3网卡作为我们将要设置的网卡,使用:

sudo  vim /etc/network/interfaces

或者

sudo gedit /etc/network/interfaces

对网络参数进行修改,内容如下:

# This file describes the network interfaces avaliable on your system
# and now to activate them.For more information,see interfaces(5)
source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto enp0s3
# iface enp0s3 inet dhcp
iface enp0s3 inet static
address 192.168.104.3
netmask 255.255.255.0
gateway 192.168.104.1
dns-nameserver 192.168.104.1

保存后重启虚拟机。

4.解决ifconfig看不到网卡的IP地址的问题

    按照前面的步骤重启虚拟机之后,使用ifconfig命令有时候会发现,居然看不到网卡的IP地址,网关,子网掩码等信息,如下图所示:

解决方法是,通过DHCP服务器为该网卡分配IP地址,使用命令:

sudo dhclient 网卡名称   -- 例如:sudo dhclient enp0s3
sudo ifconfig 网卡名称   -- 例如:sudo ifconfig enp0s3

5.宿主机中成功连接虚拟机中的MySQL数据库

    在虚拟机中通过docker启动MySQL数据库后,使用刚刚获取的IP地址,去Navicat客户端中连接,连接成功,并且虚拟机的IP地址不会改变。

6.引深学习

  • 1.桥接模式、地址转换模式、仅主机模式的具体含义

桥接模式(Bridged)——桥接模式就是将主机网卡与虚拟机虚拟的网卡利用虚拟网桥进行通信。在桥接的作用下,类似于把物理主机虚拟为一个交换机,所有桥接设置的虚拟机连接到这个交换机的一个接口上,物理主机也同样插在这个交换机当中,所以所有桥接下的网卡与网卡都是交换模式的,相互可以访问而不干扰。在桥接模式下,虚拟机ip地址需要与主机在同一个网段,如果需要联网,则网关与DNS需要与主机网卡一致。其网络结构如下图所示:

地址转换模式(NAT)——NAT模式借助虚拟NAT设备和虚拟DHCP服务器,使得虚拟机可以联网。其网络结构如下图所示:

仅主机模式(Host-Only)——Host-Only模式其实就是NAT模式去除了虚拟NAT设备,然后使用VMware Network Adapter VMnet1虚拟网卡连接VMnet1虚拟交换机来与虚拟机通信的,Host-Only模式将虚拟机与外网隔开,使得虚拟机成为一个独立的系统,只与主机相互通讯。其网络结构如下图所示:

  • 2.VirtualBox中如何设置共享文件夹将主机中的日志信息共享到虚拟机中?

\quad 工作中经常用到tail -f命令来实时查看日志文件,但是在windows系统中是没有这个命令的,这就需要为主机与虚拟机之间设置一个共享文件夹,将日志文件共享到虚拟机中。步骤如下:

\quad 在项目中引入log4j的包依赖,并且在resources目录下创建log4j.properties文件,在其中指定日志文件的输出位置:

 ### 设置###
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=/home/duqi/logs/debug.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = D:\\software\\IDEA IU\\IntelliJ IDEA 2019.3\\log\\debug.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=/home/admin/logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =D:\\software\\IDEA IU\\IntelliJ IDEA 2019.3\\log\\error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

接着将该文件夹设置为共享文件夹,操作如下:

设置要共享的文件夹的路径:

设置完成后的效果:

接着使用ctrl+alt+T打开命令行,创建并挂载虚拟机中的文件夹:

mkdir -p /mnt/log
mount -t vboxsf logs /mnt/log

执行完毕后,可以看到该文件夹下已经有了主机中的两个文件:

通过代码实测一下:

public static Logger logger = Logger.getLogger(SendHttpPost.class);
logger.debug("12313213131");

可以看到主机中运行的项目,在其中打印的日志信息已经可以在虚拟机中查看了。

7.参考链接