KVM虚拟机克隆

一、 完整克隆

1. 自动克隆

新建磁盘文件自动保留在被克隆磁盘的文件的通缉目录下;

virt-clone -o 被克隆虚拟机名称 -n 克隆虚拟机名称 --auto-clone #完整克隆(被克隆虚拟机须处于暂停或关闭状态)
#错误演示
[root@kvm01 ~]# virt-clone -o centos7-web01 -n db01 
ERROR    Either --auto-clone or --file is required, use '--auto-clone or --file' and try again.
[root@kvm01 ~]# virt-clone -o centos7-web01 -n db01 --auto-clone
ERROR    Domain with devices to clone must be paused or shutoff.

#完整克隆
[root@kvm01 ~]# virsh suspend centos7-web01
Domain centos7-web01 suspended

[root@kvm01 ~]# virt-clone -o centos7-web01 -n db01 --auto-clone
WARNING  Setting the graphics device port to autoport, in order to avoid conflicting.
Allocating 'db01.qcow2'                                                                          |  10 GB  00:00:31     

Clone 'db01' created successfully.
[root@kvm01 ~]# virsh resume centos7-web01 
Domain centos7-web01 resumed

[root@kvm01 ~]# virsh list --all
 Id    Name                           State
----------------------------------------------------
 1     centos7-web01                  running
 -     db01                           shut off

2. 手动克隆

step 01 复制磁盘文件

cp /目录/磁盘文件 /目录/新磁盘文件 #复制磁盘文件(被复制磁盘文件不能含有快照)
如果被复制的磁盘文件含有快照,则复制文件无法完成虚拟机启动;如果需要复制磁盘文件,须先删除磁盘文件中的快照;
[root@kvm01 ~]# virsh snapshot-list db01 
 Name                 Creation Time             State
------------------------------------------------------------

[root@kvm01 ~]# cp /opt/db01.qcow2 /opt/db02.qcow2
[root@kvm01 ~]# ll /opt/db* -h
-rw------- 1 root root 1.5G Mar 23 10:01 /opt/db01.qcow2
-rw------- 1 root root 1.5G Mar 23 11:25 /opt/db02.qcow2

step 02 备份配置文件

virsh dumpxml 虚拟机名称 >/目录/配置文件 #备份虚拟机配置文件
[root@kvm01 ~]# virsh dumpxml db01 >db02.xml
[root@kvm01 ~]# ll -h 
total 20K
-rw-------. 1 root root 1.8K May 11  2019 anaconda-ks.cfg
-rw-r--r--  1 root root 5.2K Mar 21 21:19 centos7.xml
-rw-r--r--  1 root root 4.3K Mar 23 11:26 db02.xml

step 03 编辑配置文件

vim /目录/配置文件 #编辑配置文件
1.修改虚拟机名称
2.删除UUID
3.修改磁盘路径
4.删除mac addr
[root@kvm01 ~]# vim db02.xml 
[root@kvm01 ~]# egrep 'db|uuid|mac addr' db02.xml 
  <name>db02</name>
      <source file='/opt/db02.qcow2'/>

step05 导入配置文件

virsh define /目录/配置文件 #导入虚拟机配置文件
[root@kvm01 ~]# virsh define db02.xml 
Domain db02 defined from db02.xml

[root@kvm01 ~]# virsh list --all
 Id    Name                           State
----------------------------------------------------
 1     centos7-web01                  running
 -     db01                           shut off
 -     db02                           shut off

step04 验证克隆

virsh start 虚拟机 #开启克隆虚拟机
virsh console 虚拟机 #console控制台登录虚拟机(未修改的虚拟机内核无法通过console控制台登录)
[root@kvm01 ~]# virsh start db02
Domain db02 started

[root@kvm01 ~]# virsh console db02 
Connected to domain db02
Escape character is ^]

CentOS Linux 7 (Core)
Kernel 3.10.0-1160.el7.x86_64 on an x86_64

localhost login: 

二、 链接克隆

raw 不支持链接克隆;

step 01 生成虚拟机磁盘文件

qemu-img create -f qcow2 -b 被克隆磁盘文件 磁盘文件 #生成虚拟机磁盘引用文件
[root@kvm01 ~]# qemu-img create -f qcow2 -b /opt/db02.qcow2 /opt/db03.qcow2
Formatting '/opt/db03.qcow2', fmt=qcow2 size=10737418240 backing_file='/opt/db02.qcow2' encryption=off cluster_size=65536 lazy_refcounts=off 
[root@kvm01 ~]# qemu-img info /opt/db03.qcow2 
image: /opt/db03.qcow2
file format: qcow2
virtual size: 10G (10737418240 bytes)
disk size: 196K
cluster_size: 65536
backing file: /opt/db02.qcow2
Format specific information:
    compat: 1.1
    lazy refcounts: false

step 02 备份配置文件

virsh dumpxml 虚拟机名称 >/目录/配置文件 #备份虚拟机配置文件
[root@kvm01 ~]# virsh dumpxml db02 > db03.xml
[root@kvm01 ~]# ll -h db03.xml 
-rw-r--r-- 1 root root 5.2K Mar 23 11:53 db03.xml

step 03 编辑配置文件

vim /目录/配置文件 #编辑配置文件
1.修改虚拟机名称
2.删除UUID
3.修改磁盘路径
4.删除mac addr
[root@kvm01 ~]# vim db03.xml 
[root@kvm01 ~]# egrep 'db|uuid|mac addr' db03.xml 
  <name>db03</name>
      <source file='/opt/db03.qcow2'/>
      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-2-db02/org.qemu.guest_agent.0'/>

step05 导入配置文件

virsh define /目录/配置文件 #导入虚拟机配置文件
[root@kvm01 ~]# virsh define db03.xml 
Domain db03 defined from db03.xml

[root@kvm01 ~]# virsh list --all
 Id    Name                           State
----------------------------------------------------
 1     centos7-web01                  running
 2     db02                           running
 -     db01                           shut off
 -     db03                           shut off

[root@kvm01 ~]# virsh dumpxml db03 | grep qcow2
      <driver name='qemu' type='qcow2'/>
      <source file='/opt/db03.qcow2'/>
        <source file='/opt/db02.qcow2'/>
[root@kvm01 ~]# virsh dumpxml db02 | grep qcow2
      <driver name='qemu' type='qcow2'/>
      <source file='/opt/db02.qcow2'/>

step04 验证克隆

virsh start 虚拟机 #开启克隆虚拟机
virsh console 虚拟机 #console控制台登录虚拟机(未修改的虚拟机内核无法通过console控制台登录)
[root@kvm01 ~]# virsh start db03 
Domain db03 started

[root@kvm01 ~]# virsh console db03 
Connected to domain db03
Escape character is ^]

CentOS Linux 7 (Core)
Kernel 3.10.0-1160.el7.x86_64 on an x86_64

localhost login: 
[root@kvm01 ~]# virsh list --all
 Id    Name                           State
----------------------------------------------------
 1     centos7-web01                  running
 2     db02                           running
 3     db03                           running
 -     db01                           shut off

[root@kvm01 ~]# free -h 
              total        used        free      shared  buff/cache   available
Mem:           7.8G        1.4G        1.3G         11M        5.1G        6.1G
Swap:          1.0G          0B        1.0G

三、 自动链接克隆脚本

1. 固定克隆

#创建db02的链接克隆db06
[root@kvm01 /server/scripts]# sh auto_linkclone_v1.sh 
KVM Machine db06 Link-Clone Successfully.
[root@kvm01 /server/scripts]# virsh start db06 
Domain db06 started

[root@kvm01 /server/scripts]# virsh console db06 
Connected to domain db06
Escape character is ^]

CentOS Linux 7 (Core)
Kernel 3.10.0-1160.el7.x86_64 on an x86_64

localhost login: 
#!/bin/bash
Disk_Path='/opt'
Disk_File='db02.qcow2'
Target_File='db06.qcow2'

Copy_Disk_File() {
qemu-img create -f qcow2 -b ${Disk_Path}/${Disk_File} ${Disk_Path}/${Target_File} &>/dev/null
}

Adjust_Config_File() {
virsh dumpxml ${Disk_File%%.*} >/tmp/${Target_File%%.*}.xml
sed -i '/<uuid>/d' /tmp/${Target_File%%.*}.xml
sed -i '/<mac address=/d' /tmp/${Target_File%%.*}.xml
sed -ri 's#(<name>)(.*)(</name>)$#\1'"${Target_File%%.*}"'\3#' /tmp/${Target_File%%.*}.xml
sed -ri 's#(<source file=.)(.*)(./>)$#\1'"${Disk_Path}/${Target_File}"'\3#' /tmp/${Target_File%%.*}.xml
}

Import_KVM_Machine() {
virsh define /tmp/${Target_File%%.*}.xml &>/dev/null
if [ $? -eq 0 ];then
  echo "KVM Machine ${Target_File%%.*} Link-Clone Successfully."
else
  echo "KVM Machine ${Target_File%%.*} Link-Clone Failed."
fi
rm -rf /tmp/${Target_File%%.*}.xml &>/dev/null
}

Main_Function() {
Copy_Disk_File
Adjust_Config_File 
Import_KVM_Machine
}

Main_Function

2. 固定克隆,支持传参(自定义克隆虚拟机的名字)

#创建db02的链接克隆
[root@kvm01 /server/scripts]# sh auto_linkclone_v2.sh 
Please Input New KVM Machine Name.
[root@kvm01 /server/scripts]# sh auto_linkclone_v2.sh db07
KVM Machine db07 Link-Clone Successfully.
[root@kvm01 /server/scripts]# virsh console db07
Connected to domain db07
Escape character is ^]

CentOS Linux 7 (Core)
Kernel 3.10.0-1160.el7.x86_64 on an x86_64

localhost login: 
#!/bin/bash
Disk_Path='/opt'
Source_KVM='db02'
Target_KVM=$1

Condition_Statement() {
if [ -z $Target_KVM ];then
    echo "Please Input New KVM Machine Name."
    exit
fi
}

Copy_Disk_File() {
qemu-img create -f qcow2 -b ${Disk_Path}/${Source_KVM}.qcow2 ${Disk_Path}/${Target_KVM}.qcow2 &>/dev/null
}

Adjust_Config_File() {
virsh dumpxml ${Source_KVM} >/tmp/${Target_KVM}.xml
sed -i '/<uuid>/d' /tmp/${Target_KVM}.xml
sed -i '/<mac address=/d' /tmp/${Target_KVM}.xml
sed -ri "s#(<name>)(.*)(</name>)#\1${Target_KVM}\3#" /tmp/${Target_KVM}.xml
sed -ri "s#(<source file=.)(.*)(./>)#\1${Disk_Path}/${Target_KVM}.qcow2\3#" /tmp/${Target_KVM}.xml
}

Import_KVM_Machine() {
virsh define /tmp/${Target_KVM}.xml &>/dev/null
rm -rf /tmp/${Target_KVM}.xml &>/dev/null
}

Auto_Start_KVM() {
virsh autostart ${Target_KVM} &>/dev/null
virsh start ${Target_KVM} &>/dev/null
if [ $? -eq 0 ];then
  echo "KVM Machine ${Target_KVM} Link-Clone Successfully."
else
  echo "KVM Machine ${Target_KVM} Link-Clone Failed."
fi
}

Main_Function() {
Condition_Statement
Copy_Disk_File
Adjust_Config_File 
Import_KVM_Machine
Auto_Start_KVM
}

Main_Function

3. 支持自定义与传参

#基于任意已存在的虚拟机进行克隆
[root@kvm01 /server/scripts]# sh auto_linkclone_v3.sh db05
Source KVM Machine not exist.
[root@kvm01 /server/scripts]# sh auto_linkclone_v3.sh db02
Please Input New KVM Machine Name.
[root@kvm01 /server/scripts]# sh auto_linkclone_v3.sh db02 db08
KVM Machine db08 Link-Clone Successfully.
[root@kvm01 /server/scripts]# virsh console db08
Connected to domain db08
Escape character is ^]

CentOS Linux 7 (Core)
Kernel 3.10.0-1160.el7.x86_64 on an x86_64

localhost login: 
#!/bin/bash
Source_KVM=$1
Target_KVM=$2

Condition_Statement() {
if [ -z "$Source_KVM" ];then
    echo "Please Input Source KVM Machine Name."
    exit
else
    virsh list --all | grep -w "$Source_KVM" &>/dev/null
    res=$?
        if [ $res -eq 0 ];then
           Disk_File=`virsh dumpxml ${Source_KVM} | sed -nr 's#(<source file=.)(.*)(./>)$#\2#gp'|tr -d ' ' 2>/dev/null` 
           Disk_Path=`dirname ${Disk_File%}`
           if [ -z "$Target_KVM" ];then
               echo "Please Input New KVM Machine Name."
               exit
           fi
        else
           echo "Source KVM Machine not exist."
           exit
    fi
fi
}
Copy_Disk_File() {
qemu-img create -f qcow2 -b ${Disk_File} ${Disk_Path}/${Target_KVM}.qcow2 &>/dev/null
}

Adjust_Config_File() {
virsh dumpxml ${Source_KVM} >/tmp/${Target_KVM}.xml
sed -i '/<uuid>/d' /tmp/${Target_KVM}.xml
sed -i '/<mac address=/d' /tmp/${Target_KVM}.xml
sed -ri "s#(<name>)(.*)(</name>)#\1${Target_KVM}\3#" /tmp/${Target_KVM}.xml
sed -ri "s#(<source file=.)(.*)(./>)#\1${Disk_Path}/${Target_KVM}.qcow2\3#" /tmp/${Target_KVM}.xml
}

Import_KVM_Machine() {
virsh define /tmp/${Target_KVM}.xml &>/dev/null
rm -rf /tmp/${Target_KVM}.xml &>/dev/null
}

Auto_Start_KVM() {
virsh autostart ${Target_KVM} &>/dev/null
virsh start ${Target_KVM} &>/dev/null
if [ $? -eq 0 ];then
  echo "KVM Machine ${Target_KVM} Link-Clone Successfully."
else
  echo "KVM Machine ${Target_KVM} Link-Clone Failed."
fi
}

Main_Function() {
     Condition_Statement
     Copy_Disk_File
     Adjust_Config_File 
     Import_KVM_Machine
     Auto_Start_KVM
}

Main_Function