前言:
kvm通常是现在的云平台的底层架构,因此,kvm是需要好好学习的。那么,如何在vm的Linux虚拟机里练习安装kvm虚拟机呢(这里,可能很多同学有点疑惑了,简单来说,就是在vm里安装的虚拟机里配置好kvm环境,然后在制作一个可以随意分发的Windows虚拟机,简称俄罗斯套娃)?
实验目的:
通过在vm虚拟机里安装kvm虚拟机,熟悉kvm的运作机制,并制作出可供云平台比如OpenStack平台使用的虚拟机镜像。
实验环境:
宿主机是Windows7旗舰版,vmware的版本是12pro,vm里安装的操作系统为centos7.6。
计划在centos7.6这个虚拟机里搭建一个完整的kvm环境,制作一个可联网的kvm虚拟机,该虚拟机版本为Windows7旗舰版。
宿主机的配置:
vm的版本:
需要用到的Windows安装包和驱动:
这里啰嗦两句了,ISO文件必须是Windows的纯净版,如果是deep,萝卜什么的定制ISO,虚拟机不会也不能引导成功。
链接:https://pan.baidu.com/s/1HoHhb8tWlB8dL2GVwiiLRg? 提取码:kvms? ?
一,kvm环境搭建
Linux虚拟机需要安装桌面和libvirt服务,kvm是每个centos自带的,内核完全支持,就不说了。虚拟机的CPU需要开启虚拟化。如下图:
Linux启动后,配置好本地仓库和virt源仓库,仓库文件内容应该如下,本地仓库的搭建见本人博客,这里就不解释了----Linux的完全本地仓库搭建指南(科普扫盲贴)_zsk_john的博客-CSDN博客_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虚拟机是这样的:
?
二,
设置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的安装
?
?
?
大概等待20分钟,期间重启一次就可以了。
?剩下的就是下一步了,过于简单就不讲解了。
?在第二个光盘里,找到w7下的amd64文件夹,具体路径为
这就安装完成了,也可以连接外网了。
那么,整个安装完毕后,我们有得到了一个文件,这个文件名字为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
|