VMware虚拟机部署CentOS7+Docker+MySQL:从环境搭建到容器实操

发布时间:2026/10/6 3:50:11
VMware虚拟机部署CentOS7+Docker+MySQL:从环境搭建到容器实操 1. 先把方案想清楚这套组合到底解决什么问题很多人第一次接触“虚拟机 CentOS7 Docker MySQL”这个组合时第一反应就是折腾虚拟机里套个系统系统里再套个容器容器里再跑个数据库听着就绕。但真按这条路径走下来你会发现它其实是目前学习Linux、Docker和MySQL最稳的一条组合拳尤其是在Windows笔记本上想模拟服务器环境、想复用一套配置、想随时删了重来的场景下。拆开看这套组合的核心理由虚拟机的意义在于给你一个“随便折腾、坏了大不了重装”的隔离环境CentOS7是当前运维圈存量最大、资料最多的发行版踩了坑搜索到的答案基本都能对上号Docker解决的是MySQL安装中间件的繁琐问题——不需要手动解压二进制包、不需要手动初始化数据目录、不需要自己写systemd服务文件一条docker run命令就把数据库拉起来。而你需要的所有知识其实都集中在“如何让这三个层次正确协作”上。这篇内容适合谁刚接触Linux和容器的小白可以把它当成一条完整的入门链路已经会装MySQL但想切到容器方式的半熟手可以重点关注目录挂载和参数设计部分甚至你只是想要一个“能跑、能远程连、数据不会丢”的数据库环境这篇也能直接照抄。我尽量把每个环节为什么要这么做讲透因为这类教程真正的坑不在命令而在命令背后的那层理解。2. 环境准备虚拟机与CentOS7的基础配置细节2.1 VMware虚拟机创建与镜像选择虚拟机软件我一般用VMware Workstation版本15以上都行16.x和17.x现在也很稳定。系统镜像强烈建议选CentOS 7.9的Minimal版也就是不带桌面环境的精简版。很多新手喜欢装DVD版带图形界面但既然是跑Docker和MySQL多一个桌面就多一堆内存占用和无关组件实战服务器上几乎全是纯命令行环境越早适应越好。创建虚拟机时有几个关键参数直接影响后面的使用体验CPU分配2核起步如果你的笔记本内存够大16G以上给4核也无妨MySQL编译安装时会快一些Docker镜像虽然是拉取不是编译但解压和初始化也吃CPU。内存分配至少2GB建议4GB。MySQL 5.7在容器内默认占用不算高但系统本身、Docker守护进程再加上MySQL2GB会有点紧如果你还要跑别的容器4GB是舒适区。磁盘分配20GB够用建议40GB因为Docker镜像、容器层、MySQL数据目录都会膨胀后期扩容虽然可以做但麻烦不如一步到位。网络模式这一步我强烈建议直接用NAT模式。桥接模式虽然能让虚拟机在局域网里获得独立IP但依赖路由器DHCP策略和网卡驱动经常出现虚拟机连不上网的情况。NAT模式由VMware虚拟交换机做NAT转发宿主机能上网虚拟机就能上网出问题概率最小。镜像下载直接用CentOS官方的archive源里的CentOS-7-x86_64-Minimal-2009.iso一定要认准2009这个版本号这是CentOS 7生命周期内的最终版本坑最少。2.2 虚拟机网络排查ping不通百度怎么办这是整个流程里第一个高频卡点热词里“centos7无法ping通百度”长期霸榜我几乎每次带新手都会遇到。如果你装完系统执行ping www.baidu.com超时按这个顺序排查第一步确认虚拟机的网络适配器确实选的是NAT模式。VMware菜单虚拟机 → 设置 → 网络适配器看是否勾选NAT。如果你之前点过桥接模式立刻改回NAT。第二步检查网卡配置文件。CentOS 7默认网卡名一般是ens33编辑/etc/sysconfig/network-scripts/ifcfg-ens33。重点看两个字段ONBOOT是否等于yesBOOTPROTO是dhcp还是static。我用NAT模式时直接让BOOTPROTOdhcp然后重启网络服务systemctl restart network。这里有个细节——很多人改了ONBOOTyes后不重启网络甚至不知道要重启结果一直以为没改对。第三步看路由和DNS。执行ip route看是否有默认路由执行cat /etc/resolv.conf看DNS是否为虚拟机网关地址或公网DNS如223.5.5.5。NAT模式下默认DNS一般是192.168.X.1VMware虚拟网关也能用。如果DNS有问题直接改/etc/resolv.conf加上nameserver 223.5.5.5即可。我遇到过最隐蔽的情况是VMware的NAT服务没启动Windows服务里找VMware NAT Service状态必须是“正在运行”如果被优化软件禁用了手动启动就好。2.3 换国内yum源没有这一步后面全程难受CentOS 7自带的基础源和epel源都在境外在你没有特殊网络工具的情况下下载速度极其感人。我第一次装Docker时光yum缓存更新就等了十几分钟后来果断换阿里云镜像源。操作很简单先备份系统自带repo文件mkdir /etc/yum.repos.d/bak mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak/然后下载阿里云的CentOS 7 repocurl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo再装epel源curl -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo最后清理缓存并重新生成yum clean all yum makecache换源后跑一次yum -y update把系统内核和基础包更新到当前源里的最新版本。这一步不只是为了“新”更重要的是让后续yum install docker这类操作不会因为依赖版本太旧而报错。更新完重启一次虚拟机确保内核和用户态组件统一。这里要留意yum update会占用不少时间正好可以把下一小节的防火墙配置做了。2.4 关闭防火墙与SELinux别让系统自带的安全策略挡住端口CentOS 7默认开了firewalldSELinux也是Enforcing状态。它们本身是好东西但在学习阶段、在NAT隔离的虚拟机里它们带来的麻烦远大于收益MySQL端口映射到宿主机后宿主机访问没问题但如果以后你想在局域网里让另一台物理机直连这个MySQLfirewalld会直接拦掉3306端口。SELinux更隐蔽它会对容器目录的访问做策略限制Docker的某些挂载目录如果上下文不对容器内进程可能莫名其妙没权限。我的建议执行以下三件事systemctl stop firewalld systemctl disable firewalld sed -i s/SELINUXenforcing/SELINUXdisabled/ /etc/selinux/config改SELinux配置后必须重启系统才生效。注意disable只是“不主动加载策略”不是删掉虚拟机里做到这步就够了。关闭后你可以用getenforce确认输出是Disabled。有朋友会问这样安全吗实话讲在NAT模式的虚拟机里这台机器的端口本来就只对宿主机可见对外部网络几乎是隐藏的严格说风险不大。如果你以后把它部署到云服务器上再按需开启防火墙和端口白名单就好学习阶段别让安全策略变成学习障碍。3. Docker安装与核心概念准备3.1 通过yum安装Docker CECentOS 7自带的源里没有Docker需要在yum源里加入Docker官方的仓库。国内环境不建议直接连官方仓库直接走阿里云的docker-ce镜像源配置方法yum install -y yum-utils yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo然后安装yum install -y docker-ce docker-ce-cli containerd.io这里有个经常遇到的版本怪圈如果直接yum install docker可能会装到一个很老的docker 1.13版本这是CentOS 7源里的遗留物不是docker-ce很多新镜像的配置格式它都不认。一定要装docker-ce。安装完成后启动Dockersystemctl start docker再设置开机自启systemctl enable docker。用docker version验证client和server都正常输出就说明装好了。3.2 配置镜像加速器解决拉取MySQL镜像慢或超时Docker默认从Docker Hub拉镜像海外网络环境时好时坏尤其在部分地区经常出现拉取中途卡死的情况。解决办法是配镜像加速器国内常用的有阿里云容器镜像服务、网易镜像、中科大镜像等。阿里云的加速地址会为每个账号生成专属域名也可以在daemon.json里写公共加速地址实际操作以阿里云控制台里分配的地址为准。创建或编辑/etc/docker/daemon.json{ registry-mirrors: [ https://你的专属加速地址.mirror.aliyuncs.com ] }改完执行systemctl daemon-reload systemctl restart docker判断是否生效docker info | grep -A 5 Registry Mirrors看到自己的加速地址就说明配好了。我之前没配加速器时拉一个mysql:5.7镜像能等十分钟甚至超时配完基本一分钟内搞定这个对比非常明显。3.3 理解Docker里MySQL的运行机制镜像、容器、数据卷在动手拉MySQL镜像之前必须先把三个概念理清否则后面对着一堆报错会毫无头绪。镜像是一个只读模板MySQL的所有二进制文件、配置文件、依赖环境都打包在镜像里本身不会变化。容器是镜像运行后的实例你可以在容器里写文件、安装工具、改配置但这些改动默认只存在当前容器层容器一旦删除改动全部消失。数据卷volume或bind mount则是把宿主机的某个目录映射到容器内的某个目录MySQL的数据落盘到那里容器删了数据还在这是数据库容器化的关键。所以规划MySQL容器时必须想清楚三件事数据目录放哪里、配置文件放哪里、日志放哪里。这决定了你后续是“用完即扔”还是“长期运维”。我的建议是全部用绝对路径的bind mount方式挂在宿主机的一个固定目录下比如/home/mysql下分data、conf、logs三个子目录。这样即使容器挂了数据、配置、日志都还在宿主机换个容器参数重新run就能恢复。4. MySQL容器部署实战从拉镜像到远程连接4.1 镜像版本选择与拉取为什么我推荐mysql:5.7.44MySQL可选的Docker镜像版本非常多8.0是主流新版本5.7是存量老版本另外还有percona分支等。我推荐的组合是如果你是学习用途选用mysql:5.7.44这是5.7系列最后一个发布版本稳定性经过长期验证教程资源也几乎都是基于5.7写的排错时最不容易迷路。如果项目要求较新特性直接上mysql:8.0但要注意8.0在认证插件、权限管理、sql_mode等方面和5.7有差异参考老教程时容易踩坑。拉取命令很简单docker pull mysql:5.7.44拉完执行docker images确认镜像存在。如果你要的是8.0docker pull mysql:8.0.36即可tag选具体小版本而不是latest因为latest会漂移哪天官方更新生命周期你就会有“昨天还能跑今天起不来”的体验。4.2 目录规划与run命令参数逐项拆解先建目录mkdir -p /home/mysql/data mkdir -p /home/mysql/conf mkdir -p /home/mysql/logs然后开始run。我直接给出一个完整可用的配置docker run -d \ --name mysql57 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDYourStrongPass2024 \ -e TZAsia/Shanghai \ -v /home/mysql/data:/var/lib/mysql \ -v /home/mysql/conf:/etc/mysql/conf.d \ -v /home/mysql/logs:/var/log/mysql \ --restartalways \ mysql:5.7.44逐项解释每个参数的意义因为复制别人的命令前必须知道自己在干什么--name mysql57容器名后续docker exec、docker logs、docker stop都用这个名字定位不用记一串容器ID。-d后台运行终端退出后容器继续跑。如果去掉-d你会在前台看到MySQL日志刷屏CtrlC容器就停了。-p 3306:3306宿主机3306端口映射到容器3306端口。左边是宿主机端口右边是容器端口。如果宿主机3306已经被占用比如你自己装过MySQL或者Windows本地也有MySQL把左边改成3307比如-p 3307:3306这时候远程连接端口就是3307。-e MYSQL_ROOT_PASSWORD设置MySQL root用户的初始密码。这里有个关键点这个环境变量只在容器首次初始化数据目录时生效如果数据目录已经存在这个参数不会帮助你修改已有密码。-e TZAsia/Shanghai设置容器时区为上海。不设置的话容器默认UTC时间MySQL里NOW()函数返回的时间和北京时间差8小时排查问题时非常迷惑。-v 数据目录映射宿主机/home/mysql/data对应容器内/var/lib/mysqlMySQL默认数据目录。这个挂载是数据安全的核心保障。-v 配置目录映射容器内/etc/mysql/conf.d下会读取所有.cnf文件宿主机配置文件放这里MySQL启动时自动加载。-v 日志目录映射MySQL的error log、slow query log都在/var/log/mysql。--restartalwaysDocker守护进程启动时自动启动这个容器。相当于开机自启而且容器异常退出后会自动拉起除非你手动docker stop。4.3 容器启动后的验证与常见状态检查执行docker ps正常会看到STATUS为“Up”的mysql57容器。如果STATUS是“Restarting”或者“Exited”立刻看日志docker logs mysql57日志里出现“mysqld: ready for connections”才是真正启动完成。初次启动时容器要做数据库初始化这个阶段要几十秒属正常现象不要一看到没有立刻变成Up就以为失败。等容器进入Up状态后进入容器内验证MySQL可用性docker exec -it mysql57 mysql -uroot -p输入刚才设置的密码看到mysql提示符就说明服务正常。接下来可以执行几个简单SQL验证基本信息SELECT VERSION(); SELECT NOW(); SHOW VARIABLES LIKE character%;这里我想强调一个很容易被忽略的细节docker exec -it进入容器后它内部是精简版Linux未必有vim、bash也可能只是sh。MySQL官方镜像基于Oracle Linux精简而来没有文本编辑器很正常。所以修改配置文件不要试图在容器内vi直接在宿主机编辑挂载目录下的文件才是正确姿势。4.4 创建业务库、业务用户与远程授权MySQL默认只有root用户而且root默认只允许localhost连接也就是只有容器内部能连。你从宿主机、从Navicat、从其他服务器用MySQL客户端连这个3306端口时会被拒绝报错一般是“Host xxx is not allowed to connect to this MySQL server”。所以必须创建一个允许远程访问的用户。MySQL 5.7标准做法CREATE USER appuser% IDENTIFIED BY AppUser2024; GRANT ALL PRIVILEGES ON mydb.* TO appuser%; FLUSH PRIVILEGES;这里%是通配符表示任意主机都可以用这个账号连接mydb库。生产环境不建议这样写学习阶段无所谓但也要知道风险——如果你在云服务器上这样做相当于用密码保护你的数据库暴露在公网后续会收到各种爆破尝试。如果你想更稳妥先创建库再授权CREATE DATABASE IF NOT EXISTS mydb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;然后授权时指定mydb.*。授权完成后从宿主机执行验证mysql -h127.0.0.1 -P3306 -uappuser -p能连上就说明端口映射、用户授权、网络链路全部通了。注意连本机虚拟机时用127.0.0.1 映射端口这个场景下-h千万别写成localhost因为MySQL客户端对localhost有特殊处理走socket而非TCP而Docker端口映射走的是TCP协议。4.5 字符集、时区与性能参数的配置修正Docker镜像默认字符集是latin1时区是UTC。这就意味着如果你不显式配置插入中文会乱码时间会比北京时间慢8小时。推荐在宿主机/home/mysql/conf下创建my.cnf扩展名必须是.cnfMySQL才会读取[mysqld] character-set-serverutf8mb4 collation-serverutf8mb4_unicode_ci default-time-zone08:00 max_connections500 innodb_buffer_pool_size256M slow_query_log1 slow_query_log_file/var/log/mysql/slow.log long_query_time2注意几个细节default-time-zone08:00和容器时区参数TZAsia/Shanghai都设置双重保险innodb_buffer_pool_size对学习环境256M足矣生产按物理内存的50%-70%设置max_connections默认151如果你以后接多个应用再调高。改完配置重启容器docker restart mysql57然后用docker exec进入验证SHOW VARIABLES LIKE character%;看到utf8mb4就对了。这里有个经验改配置后如果MySQL启动失败第一时间docker logs mysql57看错误日志常见原因是配置项拼写错误或参数值格式不对日志会明确告诉你哪一行有问题。5. 备份恢复与日常维护实操容器跑的MySQL备份方式跟物理机略有区别但核心还是mysqldump。我常用的备份有两种在容器内直接导出或从宿主机用mysqldump客户端导出。推荐前者因为不用额外安装客户端直接执行docker exec mysql57 sh -c exec mysqldump -uroot -p$MYSQL_ROOT_PASSWORD --all-databases /home/mysql/backup/all_$(date %Y%m%d).sql恢复则用cat /home/mysql/backup/all_20240101.sql | docker exec -i mysql57 mysql -uroot -p你的密码这两个命令有几个坑mysqldump输出重定向到宿主机文件时要用单引号包shell命令防止$MYSQL_ROOT_PASSWORD在宿主机侧被展开。恢复时docker exec必须加-i参数不然标准输入不会传给容器内的mysql。日常维护建议用crontab写个定时备份任务备份目录按日期滚动删除7天前的文件。这是我的常用脚本0 2 * * * docker exec mysql57 sh -c exec mysqldump -uroot -p密码 mydb /home/mysql/backup/mydb_$(date \%Y\%m\%d).sql 0 3 * * * find /home/mysql/backup -mtime 7 -name *.sql -delete注意crontab里%需要转义成%否则会被当作换行符。这个坑我实际踩过备份文件名变成纯mydb_.sql排查半天才发现是转义问题。6. 高频率问题排查速查表与核心雷区标题里和热词里高频出现的“docker安装mysql失败”往往不是安装动作本身失败而是启动后各种环境问题。我整理了几个最常遇到的场景问题现象可能原因处理方式docker pull mysql超时未配镜像加速器或加速器失效重新配置/etc/docker/daemon.json检查docker info中的Registry Mirrors容器一直Restarting端口被占用、数据目录权限错误、配置参数不合法先docker logs mysql57看日志然后检查宿主3306是否被占用netstat -tlnp宿主机连接不上3306firewalld未完全关闭、MySQL用户host限制确认systemctl status firewalld为inactive并用GRANT授权远程用户MySQL root密码失效修改了挂载目录下的配置文件但数据目录已初始化MYSQL_ROOT_PASSWORD不生效删除/home/mysql/data下的所有文件再重新run或者用skip-grant-tables方式重置密码mysql客户端报SSL连接错误客户端使用默认的SSL模式连接连接命令加--ssl-modeDISABLED或配置客户端跳过SSL校验容器删除后数据丢失数据没挂载到宿主机检查run命令中-v参数/var/lib/mysql必须对应宿主机持久目录其中“数据目录已初始化”这点强烈建议新手理解docker run第一次执行时如果挂载的data目录是空的容器会用镜像里的初始化逻辑生成全套MySQL数据文件如果data目录里已经有mysql系统库文件再改密码、改初始化参数都不会作用到这个已有实例上。这也是为什么我强调挂载目录规划要在第一次run之前就做好而不是启动后再补。还有一个小众但烦人的问题有人把宿主机挂载的conf目录权限设置成755甚至777然后MySQL启动报“Directory /etc/mysql/conf.d cannot be read”这个本质是容器内mysql用户无法读取宿主机传过去的目录权限。解决办法是确认目录可读chmod -R 755 /home/mysql/conf并且确保文件也带读权限。SELinux关闭后这类权限报错会少很多。关于MySQL 8.0如果你选的是8.0版本遇到最多的是认证插件问题客户端连不上报“Authentication plugin caching_sha2_password cannot be loaded”。这是8.0默认认证插件和5.x客户端不兼容。解决办法创建用户时指定mysql_native_passwordCREATE USER appuser% IDENTIFIED WITH mysql_native_password BY AppUser2024;或者直接在配置文件里加default-authentication-pluginmysql_native_password然后重启。7. 结尾再啰嗦几句这套方案我从第一次在虚拟机里折腾docker run mysql开始前前后后翻过无数坑最深刻的体会是所有报错都不可怕可怕的是不愿意打开docker logs去看具体报错。Docker的好处之一就是日志集中如果一个容器运行异常docker logs docker inspect这两个命令能解决90%的排查需求别再一头扎进系统日志里翻找。另外建议你在一切跑通之后自己手写一遍完整的run命令不要复制粘贴这样才能真正记住每个参数的作用。以后换到云服务器、换到生产环境这套思路依然成立只是把虚拟机换成云计算实例、把宿主机目录换成云盘而已。手里有了这套环境你可以继续折腾Docker Compose编排MySQL应用或者把数据目录迁移到宿主机独立磁盘上练手Docker数据卷迁移都是很好的后续实操方向。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询