
看到标题里那个了吗我第一次建项目目录老老实实起名CentOS8Ubuntu22Ubuntu24然后在 bash 里执行vagrant up整个终端直接把我干沉默了——在 shell 里是连接符目录名里有这玩意儿等于把命令拆成三截没报错纯属当时运气好。所以先给你们一个忠告项目目录能多简单就多简单别带别带空格最好全小写。这次折腾的目标很明确一台工作站上用一份 Vagrantfile 同时拉起 CentOS 8、Ubuntu 22.04 和 Ubuntu 24.04 三个虚拟机用于本机跑联调测试和三套系统环境验证。整个过程不算顺利box 下载、SSH 超时、CentOS 8 停服之后仓库失效、Ubuntu 24 和 VirtualBox 版本兼容性……全部踩了一遍。这篇文章就是把这些坑按时间线记下来附带排查思路和最终能跑通的配置适合准备用 Vagrant 管理多台虚拟机、或者只是想给本机装几套 Linux 做实验的人参考。1. 项目概述为什么用 Vagrant 管多虚拟机1.1 我的使用场景我在本地工作站上要维护三套环境CentOS 8 是模拟老项目的生产服务器Ubuntu 22.04 是常用开发环境Ubuntu 24.04 则是为了验证新特性顺手加的。如果每套都用 VirtualBox 手动新建、手动装系统、手动配网络三台下来至少折腾半天而且每次重建都得重复劳动。Vagrant 的价值就在这里把系统镜像、硬件配置、网络设置、初始化脚本全部写进 Vagrantfile一条vagrant up全部搞定重建环境也只是一条命令的事。很多朋友对 Vagrant 的理解停留在它能启动一个虚拟机但真正的核心其实是多机编排。它的config.vm.define语法支持在一个文件里定义多个 VM分别指定不同的 box、内存、网络、启动顺序和初始化脚本。这意味着你本地可以维护一个接近生产结构的多机环境而不用买服务器。1.2 为什么是这三个系统选这三个发行版不是拍脑袋。CentOS 8 代表了 RHEL 系的老传统虽然官方已经停服但存量机器和旧项目基本都是它的影子Ubuntu 22.04 和 24.04 分别对应两代 LTS软件源、内核、网络管理方式都有明显差异。把这三个放在同一台机器上等于同时覆盖了两种包管理生态和三代系统特性对搞运维和开发异构环境测试的人来说挺典型。p.s. 如果你家里电脑总共就 8GB 内存三台全跑起来会非常紧张我的建议是拿一台内存 16GB 以上的机器专门做虚拟化实验否则光内存交换就能让你怀疑人生。具体内存怎么分我在第 3 节详细说。2. 前置准备版本匹配和 box 选型2.1 Vagrant 与 VirtualBox 版本匹配是第一道坎很多人一上来直接vagrant up卡住了就怪运气。实际上 Vagrant、VirtualBox、box 之间是强耦合的尤其 VirtualBox 升级后老的 Vagrant 插件经常崩。我这次用的组合是 VirtualBox 7.0.12 Vagrant 2.4.1整体比较稳。如果你还在用 VirtualBox 6.x 配新版 Vagrant大概率会遇到宿主机虚拟网络适配器初始化失败、虚拟机启动后没有 IP 这类问题。这里给一个保守建议Vagrant 不要追求最新VirtualBox 也不要追求最新两者都选当前时间点附近已经发布半年以上的稳定版本遇到奇葩问题的概率会低很多。安装顺序也有讲究先装 VirtualBox再装 Vagrant装完打开 VirtualBox 确认 Host-Only 网络适配器已经创建成功。2.2 box 选哪个generic 系更省心Vagrant 世界里没有官方全包的说法box 基本靠社区维护。CentOS 8 官方已经停止维护直接用centos/8这个老 box 很可能拉取失败或者里面的仓库配置失效。我更推荐generic/centos8这是 Roboxes 维护的通用 box支持 VirtualBox 和 VMware 后端generic/ubuntu2204、generic/ubuntu2404同理。选择 box 之前建议先跑一下vagrant box list看看本地有没有旧缓存再用vagrant box add generic/centos8 --provider virtualbox拉镜像。如果这一步就卡在下载上不要硬刚看下面这个坑。目标系统推荐 box说明CentOS 8generic/centos8基于 CentOS 8.5能提供最小化环境仓库需要用 vault 源Ubuntu 22.04generic/ubuntu2204稳定经典box 体积适中Ubuntu 24.04generic/ubuntu2404内核版本高要求 VirtualBox 和 Guest Additions 版本同步更新注意box 名称里的generic/前缀代表了维护方不是系统版本号。拉之前最好去 Vagrant Cloud 看一眼这个 box 是否还存活有些老 box 会因为维护者删除而直接 404。2.3 拉取 box 太慢或失败时的应急方案我这边网络环境访问 Vagrant Cloud 的速度堪比老牛拉破车vagrant box add要么卡在等待响应要么直接超时。这时候不要反复重试我的方案是先拿到 box 的直链下载地址比如从 Vagrant Cloud 盒子的页面里复制.box文件的 URL用浏览器或者下载工具直接拉下来再执行本地导入vagrant box add /path/to/generic-ubuntu2404.box --name generic/ubuntu2404本地导入之后Vagrantfile 里正常写config.vm.box generic/ubuntu2404即可Vagrant 不会再去远程检索。这个方法也适合公司内网部署你可以把 box 文件放到内网共享目录所有人统一导入减少重复下载。3. 核心配置一份 Vagrantfile 拉起三个系统3.1 多机定义的典型结构Vagrantfile 本质上是 Ruby 脚本但就算你没写过 Ruby 也能直接照抄。我这里把三台机器写在一个文件里每台用config.vm.define单独声明。下面这个配置是最终能跑通的版本我逐行注释了# -*- mode: ruby -*- Vagrant.configure(2) do |config| # 基础镜像设置三个虚拟机默认用这个 config.vm.box generic/centos8 config.vm.box_check_update false # 共享一个 SSH 配置避免每台重复写 config.ssh.insert_key false # ---------- CentOS 8 ---------- config.vm.define centos8 do |centos| centos.vm.box generic/centos8 centos.vm.hostname centos8-node centos.vm.network private_network, type: dhcp centos.vm.provider virtualbox do |vb| vb.name vagrant-centos8 vb.memory 1024 vb.cpus 1 end end # ---------- Ubuntu 22.04 ---------- config.vm.define ubuntu22 do |u22| u22.vm.box generic/ubuntu2204 u22.vm.hostname ubuntu22-node u22.vm.network private_network, type: dhcp u22.vm.provider virtualbox do |vb| vb.name vagrant-ubuntu22 vb.memory 1536 vb.cpus 2 end end # ---------- Ubuntu 24.04 ---------- config.vm.define ubuntu24 do |u24| u24.vm.box generic/ubuntu2404 u24.vm.hostname ubuntu24-node u24.vm.network private_network, ip: 192.168.56.24 u24.vm.provider virtualbox do |vb| vb.name vagrant-ubuntu24 vb.memory 1536 vb.cpus 2 end end end这个文件有几个细节值得说。第一type: dhcp和直接指定ip我混用了目的是让你看到两种方式都可行。DHCP 方式简单省心但每次启动后 IP 可能要重新vagrant ssh进去查指定 IP 适合需要固定访问地址的机器比如你要给 Ubuntu 24 配 nginx 端口转发或多站点域名固定 IP 最方便。第二config.ssh.insert_key false是我测试后加上的。默认情况下 Vagrant 会为每台机器生成新的 SSH key但在国内网络环境下有些 proxy 或安全软件会干扰 SSH 握手关掉密钥插入能少一些离奇报错。生产环境不建议这样做本地实验倒无所谓。3.2 内存和 CPU 的分配逻辑三台机器都开图形界面显然不现实我全部用最小化环境CentOS 8 分 1GB 内存 1 核Ubuntu 两台各分 1.5GB 内存 2 核总计 4GB 内存和 5 核。这个配置在 16GB 内存、8 核 16 线程的机器上跑同时开三个实例依然有点喘但能保证基本操作不卡死。如果你的宿主机内存只有 8GB建议砍掉一台或者把 Ubuntu 24 降到 1GB。实际操作中VM 里跑编译任务时内存会瞬间飙高多留 500MB 余量也能避免虚拟机被 OOM killer 误杀。另外VirtualBox 默认会为每台虚拟机分配一部分显存如果你根本不打算进图形界面可以在 provider 配置里加一行vb.gui false显存也能省下来。3.3 初始化脚本写进 provisionVagrant 的shellprovisioner 可以在虚拟机开机时自动执行命令我习惯把装机后的基础操作全部放进去省得手动打命令。来看一个最小的初始化脚本#!/bin/bash set -e # 更新系统时间避免证书和时间不同步问题 timedatectl set-ntp true # 安装常用工具 if command -v yum /dev/null; then yum install -y vim curl net-tools htop elif command -v apt /dev/null; then export DEBIAN_FRONTENDnoninteractive apt update apt install -y vim curl net-tools htop fi # 关闭防火墙方便局域网内测试端口连通性 systemctl stop firewalld || true systemctl disable firewalld || true systemctl stop ufw || true systemctl disable ufw || true这段脚本同时兼容了 yum 和 apt 两个体系对应 CentOS 和 Ubuntu。注意我用了|| true原因是 CentOS 8 根本没有 ufwUbuntu 则不一定装了 firewalld如果不用|| true兜底脚本会判断失败并中断 provisioning。在 Vagrantfile 里对应位置加上centos.vm.provision shell, path: init.sh u22.vm.provision shell, path: init.sh u24.vm.provision shell, path: init.sh这里有个小坑path是相对于宿主机上 Vagrantfile 所在目录的所以三个 VM 可以共用同一个init.sh省事。4. 启动阶段的经典坑box 下载、SSH 超时、Guest Additions4.1 卡在Waiting for machine to boot怎么办vagrant up最让人血压升高的时刻就是最后那行default: SSH address: 127.0.0.1:2222 default: SSH username: vagrant default: SSH auth method: private key Timed out while waiting for the machine to boot.这个报错出现的原因五花八门但最常见的就是 VirtualBox 的 NAT 端口转发没有生效或者虚拟机确实没起来。我的排查顺序是固定的打开 VirtualBox GUI看那台虚拟机的运行状态如果虚拟机窗口停在小黑屏或者启动 logo说明系统还没起来加长config.vm.boot_timeout 600试试如果虚拟机已经起来但没有 IP多半是网卡配置问题检查 VirtualBox 全局网络设置里的 Host-Only Network 是否存在如果 SSH 一直拒绝连接先手动vagrant ssh看报错再检查宿主机防火墙是否拦截了 2222 等端口转发。在这个环节我实际遇到的是第二个原因某次升级 VirtualBox 之后原有的 Host-Only 网卡消失了导致 private_network 无法创建。解决办法很简单VirtualBox 全局设置里删除旧的 Host-Only Network重新添加一个然后重启 VirtualBox 服务。折腾完再vagrant up --provision通常就能过。4.2 box 下载失败的两种处理姿势如果你第一次拉 box 时走到一半断了Vagrant 会留下残缺文件在~/.vagrant.d/boxes下次vagrant add可能直接报file already exists之类的错。这时候千万别慌vagrant box list看名字vagrant box remove 名字删掉残货重新拉要么再本地导入。国内网络环境下走官方源确实慢我采取了两条路短期解近渴找到 box 直链用下载工具拉到本地然后vagrant box add本地导入就像上面说过的那样长期保平安搭建一个内网的 box 镜像目录团队之间共享.box文件大家统一导入相同版本。这样 Vagrantfile 里的 box 名称不变但拉取过程可以完全离线。提示有些 box 文件体积超过 1GB导入之前记得确认磁盘剩余空间。Vagrant 在导入阶段会复制一份到~/.vagrant.d/boxes本地残留文件不要急着删等三台机器全部 up 成功再清理。4.3 共享目录同步失败的背后如果你跟我一样在 Vagrantfile 里设置了同步目录比如写config.vm.synced_folder ., /vagrant那么 Guest Additions 版本必须和 VirtualBox 版本匹配。Ubuntu 24.04 刚出那会儿很多 box 自带的 Guest Additions 还是旧版本启动后 Vagrant 会在宿主机日志里警告 vboxsf 模块不存在共享目录挂载失败机器却照样能登录。我的解法是安装vagrant-vbguest插件让它在启动后自动更新 Guest Additionsvagrant plugin install vagrant-vbguest装好后再次vagrant reload --provision插件会尝试在虚拟机里编译新的 Guest Additions。这个过程依赖编译工具链Ubuntu 上一般会自动装好 kernel headers。如果你的机器上网络源太慢直接在初始化脚本里预装gcc make linux-headers-$(uname -r)能省很多时间。5. 按发行版拆开看CentOS 8、Ubuntu 22、Ubuntu 24 各有各的坑5.1 CentOS 8 停服后的仓库和 box 问题这是三个系统里最容易翻车的一个。CentOS 8 在 2021 年末就 EOL 了官方仓库已经停止保留yum install默认指向的 mirrorlist 地址根本解析不到。现象就是Errors during downloading metadata for repository AppStream: Status: 404 curl: (6) Could not resolve host: mirrorlist.centos.org解决办法是手动把 CentOS 8 的仓库源切到 vault.centos.org。在初始化脚本里提前处理或者启动后手动执行。我的建议是直接用 vault 源的配置文件覆盖sudo sed -i s|^mirrorlist|#mirrorlist|g /etc/yum.repos.d/CentOS-Linux-*.repo sudo sed -i s|^#baseurlhttp://mirror.centos.org|baseurlhttp://vault.centos.org|g /etc/yum.repos.d/CentOS-Linux-*.repo具体版本号还需要和系统匹配建议先写一个dl.vault.centos.org的 baseurl验证下yum update是否正常工作然后再批量应用。如果 box 拉不到或启动失败也可以试试改用bento/centos-stream-8它是 CentOS Stream 的 box不是标准 CentOS 8但至少还在维护仓库也是活的。两者差异需要你自己判断我的项目里偏向模拟旧生产环境所以最后还是用generic/centos8 vault 源解决了。5.2 Ubuntu 22.04 的 netplan 与私网配置Ubuntu 22.04 早就用 netplan 管理网络了Vagrant 的 private_network 本质上是在 VirtualBox 里新增一张 Host-Only 网卡guest 里需要用 netplan 把这张网卡带上。大多数官方 box 已经做了自动化配置但如果你的vagrant up之后发现ip addr看不到 192.168.56.x 的地址八成是 netplan 没有生成对应配置文件。最简单的排查方式是ip addr show cat /etc/netplan/01-netcfg.yaml如果发现缺失手动写一个配置文件指定 DHCP 或静态 IPnetwork: version: 2 renderer: networkd ethernets: eth1: dhcp4: true然后sudo netplan apply即可。Vagrant box 的网卡名称不一定是 eth1要根据ip addr输出里的实际接口名来改。这个坑在 VirtualBox 升级后偶尔会出现因为网卡 MAC 变了netplan 里的旧接口名匹配不上。5.3 Ubuntu 24.04 的新内核和 VirtualBox 版本兼容Ubuntu 24.04 的内核版本一路飙到了 6.8 以上VirtualBox 7.0 早期版本对这种新内核的虚拟化支持并不完美典型表现是启动时卡在 GRUB 或者 Guest Additions 编译失败。如果你遇到类似问题优先升级 VirtualBox 到 7.0.10 以上再配合vagrant-vbguest插件强制重建 vboxsf。另外Ubuntu 24.04 默认禁用了 root 用户 SSH 登录Vagrant 使用的是 vagrant 用户我这里没什么影响但如果你习惯切到 root记得手动配置PermitRootLogin yes。还有一个细节Ubuntu 24.04 的apt默认使用deb822格式源文件如果你手动改过/etc/apt/sources.list更新后可能会发现源被系统提示忽略建议老老实实沿用/etc/apt/sources.list.d/ubuntu.sources的结构。6. 常见问题排查与速查表6.1 碰到这些症状直接翻表我把这次折腾过程中遇到的典型问题整理成了速查表后面再踩坑直接对着查症状可能原因解决思路vagrant up卡在 box 添加过程网络访问 Vagrant Cloud 太慢下载 .box 文件本地导入Timed out while waitingVirtualBox Host-Only 网卡丢失或端口转发异常重建 Host-Only 网络调大config.vm.boot_timeout虚拟机起来了但无法 SSHSSH key 对接异常、防火墙拦截端口检查宿主机防火墙vagrant reload --provision共享目录/vagrant为空Guest Additions 版本不匹配安装 vagrant-vbguest 插件并 reloadCentOS 8 内 yum 报 404CentOS 8 仓库已转 vault修改 yum repo 指向 vault.centos.orgUbuntu 22 没有私有网络 IPnetplan 缺少对应网卡配置编写 netplan 配置并 applyUbuntu 24 启动卡死VirtualBox 版本太旧不支持新内核升级 VirtualBox 到 7.0.106.2 三台机器如何验证都正常全部 up 起来之后我习惯做一个快速健康检查确认三台都能互通然后再决定是否进入项目开发vagrant ssh centos8 -c ip addr show eth0 | grep inet ; hostname; uptime vagrant ssh ubuntu22 -c ip addr show | grep inet ; hostname; uptime vagrant ssh ubuntu24 -c ip addr show | grep inet ; hostname; uptime如果三台都返回了 IP 和系统信息说明 Vagrantfile 基础配置没问题。接下来我还会测试一下宿主机到三台虚拟机的网络连通性用ping和curl各试一轮。平时用的端口转发比如 8080、3306也应该逐一点一遍确认没有防火墙拦路。7. 最后的几个小技巧省内存、省时间、少返工在完整跑通这一套之后我积累了几个能显著提升体验的习惯。第一个是善用vagrant snapshot。三台虚拟机同时跑起来后再想重新测试某个系统的初始状态重新 provision 一遍要浪费好几分钟。我通常在装好基础环境后执行vagrant snapshot save centos8 initial vagrant snapshot save ubuntu22 initial vagrant snapshot save ubuntu24 initial之后如果搞坏了直接vagrant snapshot restore initial秒回春这比重新建机省太多事。第二个是不要迷信default这一台多机环境下所有命令都带上机器名比如vagrant up ubuntu24、vagrant reload centos8 --provision。不带机器名的话Vagrant 会对所有机器执行操作初看很爽遇到某台机器没配置好时报错都分不清是哪台。第三个和资源占用有关宿主机内存有限的情况下不用的时候记得vagrant halt挂起别一直让它占内存。如果三台同时开着不干活光内存就吃掉 4GB对开发机的编译任务也是一个不小的负担。最后是给所有想折腾的人一句话不要为了纠结某个 box 版本把时间全耗在网络上box 的本质就是一个基础镜像换不了源就本地导入换不了版本就换维护方先把环境跑起来再慢慢优化配置。我自己第一次把三台全拉起来的时候宿主机的可用内存只剩不到 300MB鼠标都开始跳了后来调整了内存分配和启动顺序才终于稳定下来。这个配置我现在还留着做多机网络实验和异构系统联调时直接复用省下的时间比调试它的时候多出好几倍。