近一年多,一直在从事Windows Server的运维工作,但是公司未提供方便的测试环境,于是一直在自己的戴尔小本上折腾虚拟环境。由于Windows与Linux系统底层的巨大差异,前者资源需求要远大于后者,因此windows 10 + Vmware Workstation 的模式下,我的笔记本已经不能满测试环境需求,因此在多半前,使用了Linux (Manjaro Linux) + KVM的模式至今,但是现在新的问题出现了,由于Windows Server运维工作的深入,测试环境所需的虚机也更多,Window Failover群集的测试可能会同时用到3台虚机或更多(以我的小本的性能,使用基于Windows的虚拟化是不可能实现的),因此磁盘出现不足的情况,本文将展示如何创建基于KVM的Windows 系统的模板以及使用模板和克隆的精简模式来快速部署Windows虚机。
实验环境
- 宿主机版本以及性能配置
[peter@peter ~]$ screenfetch
██████████████████ ████████ peter@peter
██████████████████ ████████ OS: Manjaro 20.2.1 Nibia
██████████████████ ████████ Kernel: x86_64 Linux 5.10.2-2-MANJARO
██████████████████ ████████ Uptime: 1d 23h 4m
████████ ████████ Packages: 1413
████████ ████████ ████████ Shell: bash 5.1.0
████████ ████████ ████████ Resolution: 1920x1080
████████ ████████ ████████ DE: Xfce4
████████ ████████ ████████ WM: Xfwm4
████████ ████████ ████████ WM Theme: Matcha-sea
████████ ████████ ████████ GTK Theme: Arc [GTK2]
████████ ████████ ████████ Icon Theme: Sea
████████ ████████ ████████ Font: WenQuanYi Micro Hei 10
████████ ████████ ████████ Disk: 83G / 229G (39%)
CPU: Intel Core i5-4210U @ 4x 2.7GHz [60.0°C]
GPU: Mesa DRI Intel(R) HD Graphics 4400 (HSW GT2)
RAM: 7015MiB / 7839MiB
- KVM 版本信息
[peter@peter ~]$ pacman -Ss qemu* | grep installed
extra/qemu 5.2.0-2 [installed]
extra/vde2 2.3.2-16 [installed]
community/libvirt 1:6.5.0-3 [installed]
[peter@peter ~]$ pacman -Ss virt-manager | grep installed
community/virt-manager 3.2.0-1 [installed]
-
Windows 模板源(Windows 10)
image.png
概念(个人理解总结,如有不精确之处,请指正)
- KVM基于模板和克隆的虚机快速部署,其根本原理是以当前部署好的一台预装系统虚机(本文中为windows10)作为目标机,将其特有信息剥离(MAC、SID等信息),然后将剥离后的磁盘和配置文件(XML文件)作为模板。模板创建完成后,我们将得到磁盘模板和配置文件模板(XML文件),当需要部署新虚机时,需要为之创建磁盘,这块磁盘将与模板磁盘建立特殊关联(后面会有创建流程,请读者勿急),磁盘创建完成后,在为新机拷贝一份配置文件(XML)文件,就可以正常启动了。由于虚机磁盘与模板磁盘的特殊关联,所有新创建的虚机均会只读方式读取模板磁盘的数据(也就是剔除系统个性设置信息的纯净系统),而所有新虚机创建完成并正常启动以及后续虚机产生的所有变更信息,将会被存储在当前续集挂在的新建磁盘中,而不会将新变更数据写入模板磁盘。因此,如果我们想将当前续集恢复到最出状态,我们只需把虚机所挂在的磁盘删除掉,再新建一块与模板磁盘有联系的空白磁盘并挂载即可。
我们可以将磁盘模板当作虚机的一次快照,新建磁盘中的数据将是以这次快照为起始点到目前虚机状态的所有增量变化。 - KVM 克隆模式
精简模式克隆(Thin Method)
虚机部署时,以只读模式的模板镜像为基础,新建的用于存储变更数据的磁盘与之关联。这种模式要求所有虚机必须有权限访问模板镜像
完整克隆(Clone Method)
虚机部署时,将使用完全克隆模式,将复制一整份(磁盘与配置)模板,缺点是会占用大量磁盘空间。
创建Windows 10 虚机模板
本文只涉及Window虚机部署相关内容,因为Linux有专用的命令行工具(virt-sysprep)处理(剔除个性化信息)和管理(个性化虚机设置,例如添加SSH kes,users或Logo等)模板,但是该命令不能用于WIndows模板制作。
- 创建一台装有Windows 10的虚拟机(请自行百度或谷歌)
- 以步骤1创建的虚机为目标生成模板
- 以管理员身份登录Windows 10,打开注册表编辑器
- 定位到
HKEY_LOCAL_MACHINE\SYSTEM\SETUP - 新建一条类型为字符串值,名为
UnattendFile的键,值为a:\sysprep.inf
image.png
image.png
或使用powershell
image.png
- 运行c:\Windows\System32\sysprep\sysprep.exe,在系统清理操作下拉菜单中选择进入系统全新体验(OOBE),勾选通用复选框(更改系统SID),关机选项选择关机。
实验过程中,出现下图报错
image.png
查看报错日志是需要卸载一个应用商店已安装的包
image.png
将包删除掉
image.png
正常情况如下,执行完清理工作后,将会自动关机

image.png
- 导模板机器的配置文件,以供部署虚机时调用
[peter@peter images]$ sudo virsh list --all
[sudo] password for peter:
Id Name State
----------------------------
11 DC running
- centos6.5 shut off
- node1 shut off
- node2 shut off
- win10 shut off
[peter@peter images]$ sudo virsh dumpxml win10 > /vms/win10.xml
[peter@peter images]$ ls -l /vms/win10.xml
-rw-r--r-- 1 peter peter 5612 1月 21 13:29 /vms/win10.xml
- 查看模板磁盘镜像,并取消模板目标机定义,取消后,
virsh-manager或者virsh list --all将不会再显示它
[peter@peter images]$ sudo virsh domblklist win10
[sudo] password for peter:
Target Source
-----------------------------------------------------------------------------------------------------
sda /var/lib/libvirt/images/win10.qcow2
sdb /var/lib/libvirt/images/cn_windows_10_business_editions_version_1909_x64_dvd_0ca83907.iso
[peter@peter images]$ sudo virsh undefine win10
Domain win10 has been undefined
[peter@peter images]$ sudo virsh list --all
Id Name State
----------------------------
11 DC running
- centos6.5 shut off
- node1 shut off
- node2 shut off
从模板部署新机器
前面准备工作已经做好,下面可以部署新虚机了,我们将使用下面的脚本来部署续集
[peter@peter ~]$ cat win_clone.sh
#!/bin/bash
# 请输入所需创建的虚机名字
echo "Please input the name of new VM:"
read NEW_GUEST_DOMAIN
# 定义模板磁盘路径
BASE_GUEST_DISK="/var/lib/libvirt/images/win10.qcow2"
# 定义新虚拟机存放路径
NEW_GUEST_FOLDER="/vms/$NEW_GUEST_DOMAIN"
# 定义新虚机磁盘路径
NEW_GUEST_DISK="`echo $NEW_GUEST_FOLDER`/`echo $NEW_GUEST_DOMAIN`.qcow2"
# 定义新虚拟机配置文件存放路径
NEW_GUEST_XML_PATH="`echo $NEW_GUEST_FOLDER`/`echo $NEW_GUEST_DOMAIN`.xml"
# 创建新虚拟机存放路径
mkdir -p $NEW_GUEST_FOLDER
# 为新虚机创建磁盘文件
sudo qemu-img create \
-f qcow2 \
-b $BASE_GUEST_DISK \
$NEW_GUEST_DISK
# 为新建虚机提供配置文件
cp /vms/win10.xml $NEW_GUEST_XML_PATH
# 创建新虚机
sudo virt-clone \
--original-xml=$NEW_GUEST_XML_PATH \
-n $NEW_GUEST_DOMAIN \
-f $NEW_GUEST_DISK \
--preserve-data
创建并启动 ts1 ts2
[peter@peter ~]$ sudo ./win10_clone.sh
[sudo] password for peter:
Please input your VM's name:
ts1
qemu-img: warning: Deprecated use of backing file without explicit backing format (detected format of qcow2)
Formatting '/vms/ts1/ts1.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=64424509440 backing_file=/var/lib/libvirt/images/win10.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
Clone 'ts1' created successfully.
[peter@peter ~]$ sudo ./win10_clone.sh
Please input your VM's name:
ts2
qemu-img: warning: Deprecated use of backing file without explicit backing format (detected format of qcow2)
Formatting '/vms/ts2/ts2.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=64424509440 backing_file=/var/lib/libvirt/images/win10.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
Clone 'ts2' created successfully.
[peter@peter ~]$ sudo virsh list --all
Id Name State
----------------------------
11 DC running
- centos6.5 shut off
- node1 shut off
- node2 shut off
- ts1 shut off
- ts2 shut off
[peter@peter ~]$ sudo virsh start ts2
[sudo] password for peter:
Domain ts2 started

image.png
查看两台虚机磁盘所占磁盘空间,可以看到两台虚机磁盘大小均不超个1G,至此结束。
[peter@peter ~]$ ls -lh /var/lib/libvirt/images/win10.qcow2
-rw-r--r-- 1 nobody kvm 61G 1月 21 13:25 /var/lib/libvirt/images/win10.qcow2
[peter@peter ~]$ ls -lh /vms/ts1/ts1.qcow2
-rw-r--r-- 1 nobody kvm 645M 1月 21 14:33 /vms/ts1/ts1.qcow2
[peter@peter ~]$ ls -lh /vms/ts2/ts2.qcow2
-rw-r--r-- 1 nobody kvm 529M 1月 21 14:34 /vms/ts2/ts2.qcow2






