必须用shell provision自动化安装并初始化MySQL,因默认box未预装MySQL、未开3306端口、未设root密码、未配置远程访问且bind-address默认为127.0.0.1。

直接在 Vagrant 中配好 forwarded_port 或 private_network,根本连不上 MySQL——因为默认 CentOS/Ubuntu box 里压根没装 MySQL,更不会初始化 root 密码、开放 3306、关闭 bind-address 限制。必须靠 provision 自动化完成整套安装+配置+授权,否则每次 vagrant destroy && up 都得重来一遍手敲命令。
为什么只改 Vagrantfile 的 network 配置没用
很多人加了这行就以为能连:
config.vm.network "forwarded_port", guest: 3306, host: 3306
结果宿主机 mysql -h127.0.0.1 -P13306 -uroot -p 连不上,常见现象包括:
-
ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1'(服务根本没跑) -
ERROR 1045 (28000): Access denied for user 'root'@'192.168.56.1'(没授权远程访问) -
telnet 192.168.56.10 3306超时(firewalld 拦着,或 mysqld 没启动)
根本原因有三个:mysqld 未安装、未启动、未配置远程访问权限。网络转发只是“通道”,不是“服务”。
用 shell provision 安装并初始化 MySQL 5.7(CentOS 7)
把这段脚本贴进 Vagrantfile 的 config.vm.provision "shell", inline: 块里,它会自动完成全部初始化动作:
yum install -y mysql-community-server --nogpgcheck
systemctl start mysqld
systemctl enable mysqld
TEMP_PASS=$(grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}')
mysql -u root -p"$TEMP_PASS" --connect-expired-password -e "
ALTER USER 'root'@'localhost' IDENTIFIED BY 'vagrant';
CREATE USER 'root'@'%' IDENTIFIED BY 'vagrant';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
"
sed -i 's/^bind-address.*/bind-address = 0.0.0.0/' /etc/my.cnf
systemctl restart mysqld关键点说明:
-
--nogpgcheck避免 yum 卡在 GPG 签名校验上 -
ALTER USER ... --connect-expired-password是 MySQL 5.7+ 强制首次改密的绕过方式 -
CREATE USER 'root'@'%'+GRANT ... TO 'root'@'%'才允许宿主机用 IP 连 -
bind-address = 0.0.0.0必须改,否则只监听127.0.0.1
别漏掉防火墙和 SELinux(CentOS 7 常坑)
即使 MySQL 跑起来了,firewalld 和 SELinux 默认也会拦住 3306 流量。在 shell provision 脚本末尾追加:
firewall-cmd --permanent --add-port=3306/tcp firewall-cmd --reload setsebool -P mysqld_connect_any 1
注意:
-
firewall-cmd --reload必须带,否则规则不生效 -
setsebool -P mysqld_connect_any 1是永久开启 SELinux 对 MySQL 远程连接的放行(CentOS 7 默认拒绝) - 如果跳过这两步,
ping得通、ssh进去也能mysql -u root -p,但宿主机就是连不上
整个流程最易被忽略的是临时密码提取逻辑和 bind-address 修改——前者失败会导致后续 SQL 全部报错,后者漏改会让所有远程连接请求静默丢弃。建议第一次跑完 provision 后,立刻进虚拟机执行 ss -tlnp | grep :3306 确认监听地址是 *:3306,而不是 127.0.0.1:3306。


















