ESXi克隆虚拟机踩坑实录

开机报错、网络不通------ESXi 克隆虚拟机的那些坑我帮你踩完了

上周在实验室搭环境,需要快速复制一台 Oracle Linux 10 的虚拟机出来。原本以为三分钟的事,结果搞了快一个小时------开机报"在当前状况下不允许执行此操作",开机后网络全挂,克隆完发现两台虚拟机 MAC 地址一模一样......

踩了一圈坑之后,我把整个流程彻底捋清楚了。今天写下来,希望你能比我少花点时间。

先说清楚这是什么情况

很多人第一次在 ESXi 上克隆虚拟机,下意识会去找 Web 界面的"克隆"按钮。找了一圈才发现:免费版的 ESXi 没有这个功能,那是 vCenter 才有的能力。

但其实不买 vCenter 照样能克隆,而且一点都不复杂------SSH 连上去,几条命令搞定。核心工具就一个:vmkfstoolsESXi 自带的磁盘操作命令,专门用来做这种事。

我这次的场景:

  • 源虚拟机:oel10-192.168.26.13,已经装好了 Oracle Linux 10,配置好了基础环境
  • 目标:快速复制出一台 oel10-192.168.26.15,改个 IP 就能用
  • 存储路径:/vmfs/volumes/data

整个流程只有六步

第一步:先把源虚拟机关掉

这步不能省。虚拟机运行状态下直接复制文件,轻则数据不一致,重则克隆出来的系统启动就崩。

bash 复制代码
# 先查 VMID
vim-cmd vmsvc/getallvms | grep 26.13

# 关机,假设 VMID 是 1
vim-cmd vmsvc/power.off 1

# 确认已关机
vim-cmd vmsvc/get.state 1

当然,直接去 ESXi Web 界面右键关机也行,看你习惯。

第二步:建目录,把配置文件复制过去

bash 复制代码
cd /vmfs/volumes/data

# 建目标虚拟机的目录
mkdir oel10-192.168.26.15

# 复制配置文件(注意不是复制磁盘,磁盘要用专用命令)
cp oel10-192.168.26.13/oel10-192.168.26.13.vmx oel10-192.168.26.15/oel10-192.168.26.15.vmx
cp oel10-192.168.26.13/oel10-192.168.26.13.nvram oel10-192.168.26.15/oel10-192.168.26.15.nvram

这里复制的是 .vmx(虚拟机配置文件)和 .nvram(BIOS 固件存储)。磁盘文件要单独处理。

第三步:克隆磁盘------这步最慢,但最关键

不能直接 cp 复制 vmdk 文件。 直接 cp 会把磁盘的 UUID 也一并复制过去,两台虚拟机磁盘 UUID 相同,ESXi 会疯掉。必须用 vmkfstools

bash 复制代码
vmkfstools -i /vmfs/volumes/data/oel10-192.168.26.13/oel10-192.168.26.13.vmdk \
           /vmfs/volumes/data/oel10-192.168.26.15/oel10-192.168.26.15.vmdk \
           -d thin

-d thin 是精简置备,磁盘文件只占实际使用量,不会一下子把空间吃满。如果你需要厚置备(比如追求稳定的 I/O 性能),用 -d eagerzeroedthick

这一步耗时取决于磁盘大小,通常几十 GB 的盘大概需要几分钟到十几分钟,有进度条,等着就行。

第四步:改 vmx 配置------坑最集中的地方

这步是整个流程里最容易出问题的。很多人把文件复制完就直接注册虚拟机,然后就开始了一系列诡异报错。

克隆之后必须重新生成 UUID 和 MAC 地址,否则两台虚拟机会互相冲突。

bash 复制代码
cd /vmfs/volumes/data/oel10-192.168.26.15

# 把所有文件里的旧虚拟机名批量替换
sed -i 's/oel10-192.168.26.13/oel10-192.168.26.15/g' oel10-192.168.26.15.vmx

# 删掉旧的 UUID,重新生成
sed -i '/^uuid.bios/d' oel10-192.168.26.15.vmx
sed -i '/^uuid.location/d' oel10-192.168.26.15.vmx
echo "uuid.bios = \"$(uuidgen)\"" >> oel10-192.168.26.15.vmx
echo "uuid.location = \"$(uuidgen)\"" >> oel10-192.168.26.15.vmx

# 删掉旧的 MAC 地址,让 ESXi 开机时自动生成新的
sed -i '/ethernet0.generatedAddress/d' oel10-192.168.26.15.vmx
sed -i '/ethernet0.addressType/d' oel10-192.168.26.15.vmx
echo 'ethernet0.addressType = "generated"' >> oel10-192.168.26.15.vmx

改完之后验证一下,确认 displayName 和 uuid 都正确:

bash 复制代码
grep -E "displayName|uuid\.|ethernet0" oel10-192.168.26.15.vmx

第五步:注册虚拟机

bash 复制代码
vim-cmd solo/registervm /vmfs/volumes/data/oel10-192.168.26.15/oel10-192.168.26.15.vmx

执行成功后会返回一个数字,这是新虚拟机的 VMID,记下来后面要用。

bash 复制代码
[root@bogon:/vmfs/volumes/68d7222b-5832bf30-789b-d0946685487f/oel10-192.168.26.15] vim-cmd solo/registervm /vmfs/volumes/da
ta/oel10-192.168.26.15/oel10-192.168.26.15.vmx
55
[root@bogon:/vmfs/volumes/68d7222b-5832bf30-789b-d0946685487f/oel10-192.168.26.15] 

第六步:启动虚拟机

bash 复制代码
# 先确认主机不在维护模式(这是我踩的第一个坑)
esxcli system maintenanceMode get

# 如果返回 true,先退出维护模式
esxcli system maintenanceMode set --enable false

# 启动(VMID 换成上一步的返回值)
vim-cmd vmsvc/power.on <VMID>

开机后还有几步收尾

虚拟机起来了,但现在它和源机器除了 MAC 地址不同,其他配置都一样------主机名、IP、machine-id,这些都得改。

改主机名:

bash 复制代码
hostnamectl set-hostname oel10-192.168.26.15

改 IP 地址:

bash 复制代码
# 先看一下当前的连接名
nmcli connection show

# 修改 IP(连接名换成实际的,比如 ens34)
nmcli connection modify ens34 ipv4.addresses 192.168.26.15/22
nmcli connection modify ens34 ipv4.gateway 192.168.27.254
nmcli connection modify ens34 ipv4.dns "114.114.114.114"
nmcli connection up ens34

改 /etc/hosts:

bash 复制代码
sed -i 's/192.168.26.13/192.168.26.15/g' /etc/hosts

重新生成 machine-id,然后重启:

bash 复制代码
rm -f /etc/machine-id
dbus-uuidgen --ensure=/etc/machine-id
reboot

machine-id 这个很多人忽略。如果你的环境里有 DHCP、Kerberos 或者某些依赖 systemd 机器唯一性的服务,两台机器 machine-id 相同会出各种奇怪问题,最好养成习惯每次克隆都改掉。

嫌步骤多?有一键脚本

把上面所有步骤打包成一个脚本,改三个变量直接粘贴到 SSH 终端跑:

bash 复制代码
SRC_VM="oel10-192.168.26.13"
DST_VM="oel10-192.168.26.15"
DATASTORE="/vmfs/volumes/data"

# 关闭源虚拟机
SRC_ID=$(vim-cmd vmsvc/getallvms | grep "$SRC_VM" | awk '{print $1}')
echo "源 VMID: $SRC_ID"
vim-cmd vmsvc/power.off $SRC_ID
sleep 10

# 复制文件
mkdir -p $DATASTORE/$DST_VM
cp $DATASTORE/$SRC_VM/$SRC_VM.vmx $DATASTORE/$DST_VM/$DST_VM.vmx
cp $DATASTORE/$SRC_VM/$SRC_VM.nvram $DATASTORE/$DST_VM/$DST_VM.nvram

# 克隆磁盘
vmkfstools -i $DATASTORE/$SRC_VM/$SRC_VM.vmdk $DATASTORE/$DST_VM/$DST_VM.vmdk -d thin

# 改 vmx
cd $DATASTORE/$DST_VM
sed -i "s/$SRC_VM/$DST_VM/g" $DST_VM.vmx
sed -i '/^uuid.bios/d' $DST_VM.vmx
sed -i '/^uuid.location/d' $DST_VM.vmx
echo "uuid.bios = \"$(uuidgen)\"" >> $DST_VM.vmx
echo "uuid.location = \"$(uuidgen)\"" >> $DST_VM.vmx
sed -i '/ethernet0.generatedAddress/d' $DST_VM.vmx
sed -i '/ethernet0.addressType/d' $DST_VM.vmx
echo 'ethernet0.addressType = "generated"' >> $DST_VM.vmx

# 注册并启动
NEW_ID=$(vim-cmd solo/registervm $DATASTORE/$DST_VM/$DST_VM.vmx)
echo "新 VMID: $NEW_ID"

esxcli system maintenanceMode set --enable false
vim-cmd vmsvc/power.on $NEW_ID
echo "完成,登录后记得改主机名和 IP"

脚本执行完,去虚拟机里改一下主机名和 IP 就行了。

踩过的那几个坑

坑1:开机报"在当前状况下不允许执行此操作"

大概率是主机在维护模式。执行这条退出来:

bash 复制代码
esxcli system maintenanceMode set --enable false

坑2:开机后网络完全不通

有两种可能。第一,vmx 里 MAC 地址没改干净------按照上面第四步重新检查一遍。第二,虚拟机内 IP 还是旧的------进系统用 nmcli 改掉。

检查方法:

bash 复制代码
# 在 ESXi 上看虚拟机的 MAC
vim-cmd vmsvc/get.guestinfo <VMID> | grep -i mac

# 在虚拟机内确认 IP
ip addr show

坑3:注册虚拟机失败

一般是路径写错了,或者文件没复制成功。检查一下:

bash 复制代码
ls -la /vmfs/volumes/data/oel10-192.168.26.15/

看看 vmx 和 vmdk 文件是不是都在。

小结

整个流程回顾一下:

  1. 关源虚拟机
  2. 建目录,复制 vmx 和 nvram
  3. vmkfstools 克隆磁盘
  4. 修改 vmx 里的 UUID 和 MAC 地址
  5. 注册虚拟机
  6. 退出维护模式,开机
  7. 进系统改主机名、IP、machine-id

绕过 vCenter,全程 SSH,不依赖任何付费功能。一个字:稳。

如果你也在折腾 ESXi 实验环境,或者遇到了其他奇怪的克隆问题,欢迎评论区聊聊------说不定你的坑我也踩过。

相关推荐
黎阳之光1 小时前
智慧环卫一体化管理:视频融合技术助力环卫作业与设施运维管控
运维
念恒123061 小时前
库制作与原理---库的理解和加载(中)
linux·运维·服务器
宁静@星空2 小时前
009-Linux环境安装宝塔
linux·运维·服务器
蜡笔婧萱2 小时前
LInux---Web网站建立的实战演练(2)
linux·运维·服务器
剑神一笑2 小时前
Linux crontab 命令详解:定时任务的底层实现与实战技巧
linux·运维·chrome
江木1232 小时前
Linux安装Matlab过程
linux·运维·matlab
YuanDaima20482 小时前
Docker 工程化安装与核心命令实战
运维·人工智能·docker·微服务·容器·bash
Lehjy2 小时前
【Linux】文件系统磁盘存储结构
android·linux·运维
ggaofeng2 小时前
自己如何实现ssh协议
运维·ssh