ESXi 虚拟机克隆(CLI方式)
适用于 VMware ESXi 免费版 / 独立主机(无 vCenter),通过 shell 命令实现完整克隆(full clone),避免 UUID/MAC 冲突,确保新 VM 可独立启动。
相对于vmware略微麻烦些,ui控制台没有直接克隆的方式,也有可能是我不会哈哈哈。
适用场景:
- 没有 vCenter,无法使用图形界面 Clone。
- 需要快速复制 VM 用于测试、备份或扩容。
- 源 VM 已关机(重要!运行中文件被锁定,无法 vmkfstools)。
前提条件
- 源 VM 已关机(power off)。
- 已启用 ESXi Shell / SSH(Host → Actions → Services → Enable Secure Shell (SSH))。
- 有足够 datastore 空间(克隆会复制磁盘数据)。
- 登录为 root(或有足够权限)。
步骤总结
以 devops-1 → devops-2 示例
启用exsi shell


查找源 VM 位置
find / -name devops-1 # 输出示例:/vmfs/volumes/696858b1-809ba051-0a8c-000c29018345/devops-1进入 datastore 并创建目标目录
cd /vmfs/volumes/696858b1-809ba051-0a8c-000c29018345/ mkdir devops-2 cd devops-2复制 .vmx 配置文件
cp ../devops-1/devops-1.vmx ./devops-2.vmx克隆虚拟磁盘
vmkfstools -i ../devops-1/devops-1.vmdk ./devops-2.vmdk # 或推荐 thin 节省空间(如果源是 thick,也可转 thin) # vmkfstools -i ../devops-1/devops-1.vmdk ./devops-2.vmdk -d thin # 进度显示 100% done. 即完成可选参数说明:
-d thin:薄配置(thin provisioning),节省空间,但 I/O 稍慢。-d zeroedthick:默认,预零厚配置-d eagerzeroedthick:预零厚,适合高性能/故障转移场景。
编辑 devops-2.vmx 文件(关键步骤!)
用 sed 批量替换:
sed -i 's/devops-1/devops-2/g' devops-2.vmx这会替换所有出现 "devops-1" 的地方,包括:
- displayName = "devops-1" → "devops-2"
- scsi0:0.fileName = "devops-1.vmdk" → "devops-2.vmdk"
- uuid.bios / uuid.location 等(自动生成新 UUID,避免冲突
- 注册新虚拟机到 ESXi 库


附件:自动化克隆脚本
#!/bin/sh
# ESXi VM 批量克隆 - 指定起始和结束编号版
# 用法示例:
# ./clone_vms.sh /vmfs/volumes/696858b1-... devops-1 devops 3 6
# → 克隆出 devops-3 devops-4 devops-5 devops-6
if [ $# -ne 5 ]; then
echo "用法: $0 <datastore_path> <source_vm_name> <target_prefix> <start_num> <end_num>"
echo "示例:"
echo " $0 /vmfs/volumes/696858b1-809ba051-0a8c-000c29018345 devops-1 devops 3 6"
echo " → 生成 devops-3 到 devops-6"
exit 1
fi
DATASTORE_PATH="$1"
SOURCE_VM="$2"
TARGET_PREFIX="$3"
START_NUM="$4"
END_NUM="$5"
cd "$DATASTORE_PATH" || { echo "无法进入 $DATASTORE_PATH"; exit 1; }
[ -d "$SOURCE_VM" ] || { echo "源目录 $SOURCE_VM 不存在"; exit 1; }
for i in $(seq "$START_NUM" "$END_NUM"); do
TARGET_VM="${TARGET_PREFIX}-${i}"
echo "正在克隆: $SOURCE_VM → $TARGET_VM"
mkdir -p "$TARGET_VM" || { echo "创建 $TARGET_VM 失败"; continue; }
cp "$SOURCE_VM/$SOURCE_VM.vmx" "$TARGET_VM/$TARGET_VM.vmx" || { echo "复制 vmx 失败"; continue; }
vmkfstools -i "$SOURCE_VM/$SOURCE_VM.vmdk" "$TARGET_VM/$TARGET_VM.vmdk" || { echo "克隆磁盘失败"; continue; }
# 替换 vmx 内容
sed -i "s/${SOURCE_VM}/${TARGET_VM}/g" "$TARGET_VM/$TARGET_VM.vmx"
sed -i '/ethernet.*addressType/d' "$TARGET_VM/$TARGET_VM.vmx" 2>/dev/null
sed -i '/ethernet.*generatedAddress/d' "$TARGET_VM/$TARGET_VM.vmx" 2>/dev/null
sed -i '/uuid/d' "$TARGET_VM/$TARGET_VM.vmx" 2>/dev/null
echo "完成: $TARGET_VM (已替换内容)"
done
echo ""
echo "全部克隆完成。"
echo "下一步:对每个新 VM 执行注册,例如:"
echo "vim-cmd solo/registervm ${DATASTORE_PATH}/devops-3/devops-3.vmx"