kvm虚拟机克隆
- 链接克隆和完整克隆的区别
- 完整克隆
- 自动完整克隆
- 手动克隆的步骤
- 1.复制模板vm磁盘为新vm的磁盘
- 2.复制模板vm配置文件为新vm的配置文件
- 3.修改新vm配置文件中的信息为新vm的信息
- 4.导入新vm的配置文件
- 5.启动新vm
- 链接克隆
- 1.生成链接克隆虚拟机磁盘文件
- 2.后续流程与手动克隆一致
- kvm虚拟机自动链接克隆
- 自动链接克隆脚本1
- 自动连接克隆脚本2
- 自动链接克隆脚本3
链接克隆和完整克隆的区别
完整克隆
完整克隆是将当前虚拟机的磁盘文件完全复制一份。
自动完整克隆
# 自动完整克隆
## -o 源虚拟机
## -n new新的虚拟机
virt-clone --auto-clone -o vm1 -n vm2
克隆时虚拟机必需处于**挂起**
或**关机**
状态。
手动克隆的步骤
手动克隆的步骤如下:
1.复制模板vm磁盘为新vm的磁盘
# 复制模板vm磁盘为新vm的磁盘
cp centos7-clone.qcow2 app2.qcow2
2.复制模板vm配置文件为新vm的配置文件
# 复制模板vm配置文件为新vm的配置文件
virsh dumpxml centos7-clone > app2.xml
3.修改新vm配置文件中的信息为新vm的信息
# 修改新vm配置文件的name/UUID/磁盘/mac地址
vim app2.xml
- 修改vm的name
- 删除vm的uuid
- 删除vm的mac地址
- 修改vm的磁盘路径
4.导入新vm的配置文件
# 导入新vm的配置文件
virsh define app2.xml
5.启动新vm
# 启动新vm
virsh start app2
链接克隆
链接克隆占用磁盘空间较小,但是前置条件是源虚拟机文件要存在
;
也就是说,如果把源虚拟机
删除了,链接克隆后的虚拟机就不能用
了。
1.生成链接克隆虚拟机磁盘文件
# 创建链接克隆磁盘
## 创建链接克隆磁盘要指定-f 为qcow2
## -b 创建链接克隆磁盘
qemu-img create -f qcow2 -b 源磁盘 新磁盘
# 查看链接克隆磁盘
qemu-img info 新磁盘
## backing file 基于这个磁盘文件做的链接克隆
2.后续流程与手动克隆一致
- 复制vm配置文件为新vm
- 修改vm配置文件中的信息为新vm的信息
- 修改vm的name
- 删除vm的uuid
- 删除vm的mac地址
- 修改vm的磁盘路径
- 导入新vm的配置文件
- 启动新vm
kvm虚拟机自动链接克隆
kvm没有官方的自动链接克隆
工具.
下面是3个自动链接克隆脚本,全都没有在生产环境下测试过
,总有一款适合你。
#!/usr/bin/env bash
echo "本脚本未做过任何测试"
# 将获取源vm实例、新vm实例名称
function parse_arguments() {
# 如果没有传入足够的参数,输出使用说明并退出
if [[ $# -lt 2 ]]; then
echo "Usage: $0 <src_vm_name> <new_vm_name>"
exit 1
fi
# 获取源vm实例名称,赋值给全局变量 $src_vm_name
src_vm_name=$1
# 获取新vm实例名称,赋值给全局变量 $new_vm_name
new_vm_name=$2
# 设置新vm实例配置文件的路径和文件名,赋值给全局变量 $new_vm_xml
new_vm_xml="/tmp/${new_vm_name}.xml"
# 生成新vm实例的uuid,赋值给全局变量 $new_vm_uuid
new_vm_uuid=$(uuidgen)
}
# 将从源vm实例导出配置到新vm实例配置文件的代码封装为函数
function export_vm_config() {
# 从源vm实例导出配置到新vm实例配置文件
virsh dumpxml "$src_vm_name" >"$new_vm_xml"
}
# 将从新vm实例配置文件中过滤出磁盘完整路径的代码封装为函数
function get_vm_disk_path() {
# 从新vm实例配置文件中过滤出磁盘完整路径
src_vm_name_disk=$(grep qcow2 "$new_vm_xml" | awk -F "'" '/source file/{print $2}')
# 读取src_disk所在的目录
src_disk_dir=$(dirname "$src_vm_name_disk")
# 拼接出新vm实例的磁盘完整路径,赋值给全局变量 $new_vm_disk
new_vm_disk=${src_disk_dir}/${new_vm_name}.qcow2
}
# 将创建基于链接克隆的虚拟磁盘文件的代码封装为函数
function clone_vm_disk() {
# 创建基于链接克隆的虚拟磁盘文件
qemu-img create -f qcow2 -b "$src_vm_name_disk" "$new_vm_disk"
}
# 将修改新虚拟机的xml配置文件的代码封装为函数
function modify_vm_config() {
# 修改新虚拟机的xml配置文件
sed -i 's/vmname/'"$new_vm_xml"'/' "$new_vm_xml"
sed -i 's/vmuuid/'"$new_vm_uuid"'/' "$new_vm_xml"
sed -i '/mac address/d' "$new_vm_xml"
sed -i '2s#'"$src_vm_name"'#'"$new_vm_name"'#' "$new_vm_xml"
sed -i 's#'"$src_vm_name_disk"'#'"$new_vm_disk"'#g' "$new_vm_xml"
sed -i '/\/var\/lib\/libvirt\/qemu\/channel\/target/d' "$new_vm_xml"
}
# 将导入新vm实例的虚拟机配置文件的代码封装为函数
function import_vm_config() {
# 导入新vm实例的虚拟机配置文件
virsh define "$new_vm_xml"
}
# 将测试启动新vm实例的代码封装为函数
function start_vm() {
# 测试启动新vm实例
virsh start "$new_vm_name"
}
# 主函数,调用上述函数组合实现整个脚本的功能
function main() {
echo "本脚本只在Centos7测试过"
# 解析命令行参数
parse_arguments "$@"
# 导出源vm实例的配置到新vm实例的配置文件
export_vm_config
# 获取源vm实例的磁盘路径并生成新vm实例的磁盘路径
get_vm_disk_path
# 创建基于链接克隆的虚拟磁盘文件
clone_vm_disk
# 修改新vm实例的xml配置文件
modify_vm_config
# 导入新vm实例的虚拟机配置文件
import_vm_config
# 测试启动新vm实例
start_vm
}
# 调用主函数
main "$@"
自动连接克隆脚本2
#!/usr/bin/env bash
# 以时间格式生成VM_NAME
function generate_vm_name() {
# 定义虚拟机名称的前缀
local VM_NAME_PREFIX="vm"
# 获取当前时间,精确到纳秒
NEWVM="${VM_NAME_PREFIX}$(date +%Y%m%d%H%M%S%N)"
# 返回生成的随机虚拟机名称
echo "${NEWVM}"
}
# 定义函数,用于检查虚拟机磁盘镜像是否已经存在
function check_vm_image() {
# 检查新虚拟机的磁盘镜像是否已经存在,如果存在则输出错误消息并退出
if [ -e "${IMG_DIR}/${NEWVM}.img" ]; then
echo "File exists."
exit 68
fi
}
# 定义函数,用于创建新虚拟机的磁盘镜像
function create_vm_image() {
# 创建新的虚拟机磁盘镜像,并提示创建结果
echo -en "创建虚拟机磁盘映像......\t"
# -f qcow2:指定新磁盘镜像的格式为 qcow2。
# -b "${IMG_DIR}/${BASEVM}.img":指定新磁盘镜像基于的现有磁盘镜像
# ${IMG_DIR}/${NEWVM}.img 是新磁盘镜像的路径和文件名。
# &> /dev/null:将命令的标准输出和标准错误输出都重定向到 /dev/null,即丢弃输出。
qemu-img create -f qcow2 -b "${IMG_DIR}/${BASEVM}.img" "${IMG_DIR}/${NEWVM}.img" &> /dev/null
# 打印绿色的OK
echo -e "\e[32;1m[OK]\e[0m"
}
# 定义函数,用于修改虚拟机配置文件
function modify_vm_config() {
# 读取默认的虚拟机配置文件,并将其拷贝到临时文件中
cat "${IMG_DIR}/.rhel7.xml" > /tmp/myvm.xml
# 将虚拟机配置文件中所有出现的BASEVM替换为NEWVM
sed -i "s/${BASEVM}/${NEWVM}/g" /tmp/myvm.xml
# 生成一个新的UUID,并将虚拟机配置文件中的UUID替换为新的UUID
sed -i "s/<uuid>.*<\/uuid>/<uuid>$(uuidgen)<\/uuid>/g" /tmp/myvm.xml
# 将虚拟机配置文件中所有出现的BASEVM.img替换为NEWVM.img
sed -i "s/${BASEVM}\.img/${NEWVM}\.img/g" /tmp/myvm.xml
# 将虚拟机配置文件中的MAC地址从a1修改为0c
sed -i "s/a1/0c/g" /tmp/myvm.xml # 修改 MAC 地址
}
# 定义函数,用于定义新虚拟机并启动
function define_vm() {
# 将新虚拟机的配置文件定义为一个新的虚拟机,并提示定义结果
echo -en "定义新的虚拟机......\t\t"
virsh define /tmp/myvm.xml &> /dev/null
# 输出一个绿色的"[OK]"
echo -e "\e[32;1m[OK]\e[0m"
}
# 定义函数,用于创建新虚拟机
function main() {
# 1. 以时间格式生成VM_NAME
generate_vm_name
# 2.调用check_vm_image函数来检查新虚拟机的磁盘镜像是否已经存在
check_vm_image
# 3.调用create_vm_image函数来创建新的虚拟机磁盘镜像
create_vm_image
# 4.调用modify_vm_config函数来修改新虚拟机的配置文件
modify_vm_config
# 5.调用define_vm函数来定义新虚拟机并启动
define_vm
}
####################################################
# 设置变量,指定新虚拟机的磁盘镜像目录和基础虚拟机名称
IMG_DIR=/var/lib/libvirt/images
BASEVM=rh7_template
# 调用函数来创建新的虚拟机
create_vm
# 退出码:
# 65 -> 用户未输入任何内容
# 66 -> 用户输入的不是数字
# 67 -> 用户输入的数字超出范围
# 68 -> 虚拟机磁盘镜像已经存在
自动链接克隆脚本3
#!/bin/bash
# 自动链接克隆 KVM 虚拟机的脚本,适用于生产环境
# 开启debug
set -ex
# 配置
vm_name="myvm" # 源虚拟机的名称
clone_prefix="clone-" # 克隆虚拟机名称的前缀
clone_count=5 # 要创建的克隆虚拟机的数量
clone_memory="4G" # 每个克隆虚拟机的内存大小(例如 "2G"、"4096")
clone_vcpus=2 # 每个克隆虚拟机的虚拟 CPU 数量
clone_disk_size="20G" # 每个克隆虚拟机的磁盘镜像文件大小(例如 "10G"、"100GiB")
# 获取源虚拟机的磁盘镜像文件名和目录
function get_source_disk() {
src_vm_name_disk=$(virsh dumpxml "$vm_name" | grep 'source file' | awk -F "'" '{print $2}')
src_disk_dir=$(dirname "$src_vm_name_disk")
}
# 创建一个克隆虚拟机
function create_clone_vm() {
# 克隆磁盘镜像文件
qemu-img create -f qcow2 -b "$src_vm_name_disk" -o size="$clone_disk_size" "$clone_vm_disk"
# 为克隆虚拟机生成新的 XML 配置文件
clone_vm_xml=$(mktemp)
virsh dumpxml "$vm_name" | sed "s/<name>$vm_name<\/name>/<name>$clone_name<\/name>/" > "$clone_vm_xml"
# 修改克隆虚拟机的 XML 配置文件
sed -i "s/<uuid>.*<\/uuid>/<uuid>$(uuidgen)<\/uuid>/" "$clone_vm_xml"
sed -i "s/<memory unit='KiB'>.*<\/memory>/<memory unit='GiB'>$clone_memory<\/memory>/" "$clone_vm_xml"
sed -i "s/<currentMemory unit='KiB'>.*<\/currentMemory>/<currentMemory unit='GiB'>$clone_memory<\/currentMemory>/" "$clone_vm_xml"
sed -i "s/<vcpu placement='static'>.*<\/vcpu>/<vcpu placement='static'>$clone_vcpus<\/vcpu>/" "$clone_vm_xml"
sed -i "s/<source file='.*.qcow2'\/>/<source file='$clone_vm_disk'\/>/" "$clone_vm_xml"
sed -i "s/<target dev='vda' bus='virtio'\/>/<target dev='vda' bus='virtio'\/><address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'\/>/" "$clone_vm_xml"
# 使用修改后的 XML 配置文件定义克隆虚拟机
virsh define "$clone_vm_xml"
echo "已完成克隆虚拟机 '$vm_name' 为 '$clone_name' 的创建。"
}
# 创建多个克隆虚拟机
function create_multiple_clones() {
# 循环创建指定数量的克隆虚拟机
for ((i=1; i<=clone_count; i++)); do
clone_name="${clone_prefix}${i}"
clone_vm_disk=${src_disk_dir}/${clone_name}.qcow2
create_clone_vm
done
}
# 调用函数创建克隆虚拟机
get_source_disk
create_multiple_clones
# 这个脚本从指定的源虚拟机中克隆指定数量的虚拟机,并为每个虚拟机生成新的 XML 配置文件。虚拟机的名称、内存大小、CPU 数量和磁盘镜像大小都可以在脚本中进行配置