前言:

kvm通常是现在的云平台的底层架构,因此,kvm是需要好好学习的。那么,如何在vm的Linux虚拟机里练习安装kvm虚拟机呢(这里,可能很多同学有点疑惑了,简单来说,就是在vm里安装的虚拟机里配置好kvm环境,然后在制作一个可以随意分发的Windows虚拟机,简称俄罗斯套娃)?

实验目的:

通过在vm虚拟机里安装kvm虚拟机,熟悉kvm的运作机制,并制作出可供云平台比如OpenStack平台使用的虚拟机镜像。

实验环境:

宿主机是Windows7旗舰版,vmware的版本是12pro,vm里安装的操作系统为centos7.6。

计划在centos7.6这个虚拟机里搭建一个完整的kvm环境,制作一个可联网的kvm虚拟机,该虚拟机版本为Windows7旗舰版。

宿主机的配置:

kvm安装Windows7旗舰版_云原生

vm的版本:

kvm安装Windows7旗舰版_云原生_02

需要用到的Windows安装包和驱动:

这里啰嗦两句了,ISO文件必须是Windows的纯净版,如果是deep,萝卜什么的定制ISO,虚拟机不会也不能引导成功。

链接:https://pan.baidu.com/s/1HoHhb8tWlB8dL2GVwiiLRg 
提取码:kvms 

 

kvm安装Windows7旗舰版_云原生_03

一,kvm环境搭建

Linux虚拟机需要安装桌面和libvirt服务,kvm是每个centos自带的,内核完全支持,就不说了。虚拟机的CPU需要开启虚拟化。如下图:

kvm安装Windows7旗舰版_云原生_04

Linux启动后,配置好本地仓库和virt源仓库,仓库文件内容应该如下,本地仓库的搭建见本人博客,这里就不解释了----Linux的完全本地仓库搭建指南(科普扫盲贴)_zsk_john的博客-博客_linux仓库

[kvm]
name=kvm
baseurl=https://mirrors.aliyun.com/centos/7.9.2009/virt/x86_64/kvm-common/
enable=1
gpgcheck=0

 仓库配置好后,执行以下命令安装桌面和kvm环境:

yum -y install qemu-kvm libvirt virt-install bridge-utils virt-manager
yum groupinstall " GNOME Desktop" -y

这里稍微做一个科普,kvm环境主要是由两个命令族组成(命令族的意思是一系列基本相同的命令,比如,ip 族命令,net族命令),一个是qemu族,一个是virt族。

[root@slave1 opt]# ip
ip                    ipa-client-automount  ipcalc                iprdbg                ipset                 iptunnel
ip6tables             ipa-client-install    ipcmk                 iprdump               iptables              
ip6tables-restore     ipa-getcert           ipcrm                 iprinit               iptables-restore      
ip6tables-save        ipa-getkeytab         ipcs                  iprsos                iptables-save         
ipa                   ipa-join              ipmaddr               iprupdate             iptables-xml          
ipa-certupdate        ipa-rmkeytab          iprconfig             ipsec                 iptc                  
[root@slave1 opt]# net
netaddr             netreport           netscsid            netstat             nettle-hash         nettle-lfib-stream 
[root@slave1 opt]# virt
virt-clone          virt-install        virtlogd            virt-pki-validate   virt-xml            
virt-host-validate  virtlockd           virt-manager        virt-what           virt-xml-validate
root@slave1 opt]# qemu-
qemu-ga         qemu-img        qemu-io         qemu-nbd        qemu-pr-helper

比如上面的net族,我们可以认为netaddr和netsta这两个命令是一个族的,ipa ,ipset ,ip等等命令是ip族的,当然,在kvm里常用的命令是virt-clone virt-install virt-xml virsh 这么几个命令,尤其是virsh,virt-install ,virt-clone 这三个命令非常常用。




以上软件安装完毕后,需要开启libvirt服务,开启服务命令为:

systemctl start libvirtd
systemctl enable libvirtd
systemctl status libvirtd

请确保服务应该是这个样子的:

最后一段说的是我有一个虚拟机在运行,名字是win7。

[root@slave1 opt]# systemctl status libvirtd
● libvirtd.service - Virtualization daemon
   Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2022-05-03 17:48:06 CST; 5h 3min ago
     Docs: man:libvirtd(8)
           https://libvirt.org
 Main PID: 27166 (libvirtd)
    Tasks: 20 (limit: 32768)
   CGroup: /system.slice/libvirtd.service
           ├─27166 /usr/sbin/libvirtd
           ├─27279 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelp...
           └─27280 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelp...

May 03 18:30:51 slave1 dnsmasq-dhcp[27279]: DHCPREQUEST(virbr0) 192.168.122.60 52:54:00:f9:56:56
May 03 18:30:51 slave1 dnsmasq-dhcp[27279]: DHCPACK(virbr0) 192.168.122.60 52:54:00:f9:56:56 zsk-PC
May 03 18:30:56 slave1 dnsmasq-dhcp[27279]: DHCPINFORM(virbr0) 192.168.122.60 52:54:00:f9:56:56
May 03 18:30:56 slave1 dnsmasq-dhcp[27279]: DHCPACK(virbr0) 192.168.122.60 52:54:00:f9:56:56 zsk-PC
May 03 18:34:46 slave1 libvirtd[27166]: 2022-05-03 10:34:46.569+0000: 27166: error : qemuMonitorIO:718 : internal error: End of file from qemu monitor
May 03 22:00:47 slave1 dnsmasq[27279]: no servers found in /etc/resolv.conf, will retry
May 03 22:02:53 slave1 dnsmasq[27279]: reading /etc/resolv.conf
May 03 22:02:53 slave1 dnsmasq[27279]: using nameserver 61.128.114.166#53
May 03 22:02:53 slave1 dnsmasq[27279]: using nameserver 8.8.8.8#53
May 03 22:05:17 slave1 libvirtd[27166]: 2022-05-03 14:05:17.175+0000: 27171: warning : qemuDomainObjTaint:7564 : Domain id=4 name='win7' uu...host-cpu
Hint: Some lines were ellipsized, use -l to show in full.

安装好的虚拟机里的kvm虚拟机是这样的:

kvm安装Windows7旗舰版_运维_05

 

kvm安装Windows7旗舰版_云原生_06

二,

设置Linux虚拟机网卡桥接模式,以使得kvm虚拟机能够正常上网。

Linux虚拟机的网卡名称是ens33,修改这个网卡的配置文件,内容如下(原先的关于ip地址和netmask,gateway,dns这些的都删除掉,添加一个BRIDGE="br0",DEVICE和NAME都是ens33):

TYPE="Ethernet"
BRIDGE="br0"
BOOTPROTO="static"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
NAME="ens33"
UUID="d4876b9f-42d8-446c-b0ae-546e812bc954"
DEVICE="ens33"
ONBOOT="yes"

新建一个虚拟网卡配置文件,该网卡命名为br0,这个网卡的配置文件如下(ens33原来的关于ip地址和netmask,gateway,dns写到这个文件里,DEVICE和NAME都是br0,TYPE修改成Bridge):

TYPE="Bridge"
NAME="br0"
BOOTPROTO="static"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
UUID="a276650e-af08-4270-8bac-08aa6197f2bc"
DEVICE="br0"
ONBOOT="yes"
PREFIX="24"
IPADDR=192.168.0.17
NETMASK=255.255.255.0
GATEWAY=192.168.0.1
DNS1=61.128.114.166
DNS2=8.8.8.8

 重启网络服务后,该Linux虚拟机仍可正常上网,并且查看网卡可以看到两个网卡的mac地址是一样的,这样就算桥接网卡成功啦(两个00:0c:29:e9:9e:89)。

重启网络服务命令是:

systemctl restart network

网卡信息如下: 

[root@slave1 network-scripts]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UNKNOWN qlen 1000
    link/ether 00:0c:29:e9:9e:89 brd ff:ff:ff:ff:ff:ff
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 00:0c:29:e9:9e:89 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.17/24 brd 192.168.0.255 scope global br0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fee9:9e89/64 scope link 
       valid_lft forever preferred_lft forever
4: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN qlen 1000
    link/ether 52:54:00:4a:0d:60 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
5: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN qlen 1000
    link/ether 52:54:00:4a:0d:60 brd ff:ff:ff:ff:ff:ff
7: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UNKNOWN qlen 1000
    link/ether fe:54:00:fc:03:6f brd ff:ff:ff:ff:ff:ff
    inet6 fe80::fc54:ff:fefc:36f/64 scope link 
       valid_lft forever preferred_lft forever



三,

上述环境搭建完毕后,就可以正式的安装啦。

(1),

生成一个img文件,该文件格式为qcow2,命令为:

qemu-img create -f qcow2 win7.img 30G

此命令会生成一个img文件,该文件格式是qcow2,一会将会把Windows系统安装到这个文件内。文件存放位置为当前路径下,最好是移动到/opt目录下,如果是root目录下,会有权限问题。

(2),

Windows7纯净版ISO文件和virt驱动文件也在/opt目录下

[root@slave1 opt]# pwd
/opt
[root@slave1 opt]# ll
total 13423720
-rw-r--r-- 1 qemu qemu  3419052032 May  3 21:53 cn_windows_7_ultimate_with_sp1_x64_dvd_618537(1).iso
drwxr-xr-x 2 root root           6 Mar 26  2015 rh
-rw-r--r-- 1 qemu qemu   160755712 May  3 21:51 virtio-win-0.1.102.iso

(3)

正式的安装命令,该命令将会启动一个服务,此服务可以通过vnc连接。端口定义为5922

virt-install --name win7 --os-variant=win7 --ram 512 --vcpus=1 --disk path=/opt/win7.img,size=30,format=qcow2,bus=ide --accelerate --disk device=cdrom,path=/opt/cn_windows_7_ultimate_with_sp1_x64_dvd_618537\(1\).iso --disk device=cdrom,path=/opt/virtio-win-0.1.102.iso --vnc --vncport=5922 --vnclisten=0.0.0.0 --network bridge=br0,model=virtio --noautoconsole

(4)

这里需要注意了,由于是虚拟机套虚拟机,因此,安装的时候需要将CPU定义为映射。定义的方法为:首先先在host上执行virsh -c qemu:///system进入libvirt的shell。然后edit {你的虚拟机名字}。这里由于上面的定义名称是win7,因此,是edit win7 即可,此时就会打开/etc/libvirt/qemu/下的一个名为win7的xml文件。

那么,我们直接打开这个文件然后修改可以吗?这样的修改是不可以的,必须是libvirt的shell修改才会即时生效的哦。这里要注意了。~!!!!!!!!!!

这个文件的内容应该是这样的:

<!--
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:
  virsh edit win7
or other application using the libvirt API.
-->

<domain type='kvm'>
  <name>win7</name>
  <uuid>03dc4185-7581-4c1e-9c13-f1f67cedba1f</uuid>
  <memory unit='KiB'>524288</memory>
  <currentMemory unit='KiB'>524288</currentMemory>
  <vcpu placement='static'>1</vcpu>
  <os>
    <type arch='x86_64' machine='pc-i440fx-rhel7.6.0'>hvm</type>
    <boot dev='hd'/>
    <bootmenu enable='yes'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <hyperv>
      <relaxed state='on'/>
      <vapic state='on'/>
      <spinlocks state='on' retries='8191'/>
    </hyperv>
  </features>
  <cpu mode='host-passthrough' check='partial'>
    <model fallback='allow'/>
  </cpu>
  <clock offset='localtime'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
    <timer name='hypervclock' present='yes'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <pm>
    <suspend-to-mem enabled='no'/>
    <suspend-to-disk enabled='no'/>
  </pm>
  <devices>
    <emulator>/usr/libexec/qemu-kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/opt/win7.img'/>
      <target dev='hda' bus='ide'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/opt/cn_windows_7_ultimate_with_sp1_x64_dvd_618537(1).iso'/>
      <target dev='hdb' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='0' target='0' unit='1'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/opt/virtio-win-0.1.102.iso'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='1' target='0' unit='0'/>
    </disk>
    <controller type='usb' index='0' model='ich9-ehci1'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x7'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci1'>
      <master startport='0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0' multifunction='on'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci2'>
      <master startport='2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x1'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci3'>
      <master startport='4'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x2'/>
    </controller>
    <controller type='pci' index='0' model='pci-root'/>
    <controller type='ide' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <interface type='bridge'>
      <mac address='52:54:00:87:6e:6b'/>
      <source bridge='br0'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target type='isa-serial' port='0'>
        <model name='isa-serial'/>
      </target>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <input type='tablet' bus='usb'>
      <address type='usb' bus='0' port='1'/>
    </input>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <graphics type='vnc' port='5922' autoport='no' listen='0.0.0.0'>
      <listen type='address' address='0.0.0.0'/>
    </graphics>
    <video>
      <model type='vga' vram='16384' heads='1' primary='yes'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
    </memballoon>
  </devices>
</domain>

其中<cpu mode='host-passthrough' check='partial'>   这个mode的原值是host-model,修改成host-passthrough映射模式。如果不修改,将会在安装的时候一直卡在startwindows那个界面。

这个配置文件里定义了上面那两个文件,也就是那两个ISO文件的存放路径,也就是类似这样的定义:

source file='/opt/cn_windows_7_ultimate_with_sp1_x64_dvd_618537(1).iso'

 这里又得注意了,三个设备,安装磁盘win7.img 和挂载的两个ISO光驱格式都是bus='ide',如果用别的格式,比如virt,那么,安装的时候第一次重启后,将会无法再开机的哦。

我们发现一个问题,这个时候还没有开始安装系统,但启动的时候是直接启动硬盘的,原因是有一个地方没有更改

<os>
    <type arch='x86_64' machine='pc-i440fx-rhel7.6.0'>hvm</type>
    <boot dev='hd'/>
  </os>

上述内容里,将hd更改为cdrom即可从cdrom启动啦。

(四)

Windows的安装

kvm安装Windows7旗舰版_云原生_07

 

kvm安装Windows7旗舰版_云原生_08

kvm安装Windows7旗舰版_centos_09

kvm安装Windows7旗舰版_运维_10

kvm安装Windows7旗舰版_linux_11

kvm安装Windows7旗舰版_云_12

kvm安装Windows7旗舰版_运维_13

 

kvm安装Windows7旗舰版_linux_14

kvm安装Windows7旗舰版_centos_15

 

kvm安装Windows7旗舰版_云_16

大概等待20分钟,期间重启一次就可以了。

kvm安装Windows7旗舰版_运维_17

 剩下的就是下一步了,过于简单就不讲解了。

kvm安装Windows7旗舰版_云_18

kvm安装Windows7旗舰版_centos_19

 在第二个光盘里,找到w7下的amd64文件夹,具体路径为

kvm安装Windows7旗舰版_云_20

这就安装完成了,也可以连接外网了。




那么,整个安装完毕后,我们有得到了一个文件,这个文件名字为win7.img, 也就是我们前面使用命令 qemu-img create -f qcow2 win7.img 30G建立的文件,这个文件移动到其他的带有kvm的环境的Linux服务器下就可以立即使用了。使用这个img文件的命令为:

virt-install --name test01 --ram 2048  --disk path=/opt/win7.img  --network=bridge:br0 --force --import --autostart

以上面的命令为例子,将要建立的虚拟机名称为test01,该虚拟机的内存大小为 2G,网络使用桥接的br0网卡。

此时,假设在其它的服务器上,运行了这个虚拟机,那么, 我们需要在桌面,使用virt-manager 命令查看并管理该虚拟机,这个虚拟机是不能通过vnc连接的哦。

[root@slave1 ~]# virsh list --all
 Id    Name                           State
----------------------------------------------------
 4     win7                       running