说明:
Kernel-based Virtual Machine的简称,是一个开源的系统虚拟化模块,自Linux 2.6.20之后集成在Linux的各个主要发行版本中。它使用Linux自身的调度器进行管理,所以相对于Xen,其核心源码很少。KVM已成为学术界的主流VMM之一。
KVM的虚拟化需要硬件支持(如[Intel VT](https://baike.baidu.com/item/Intel VT)技术或者AMD V技术)。是基于硬件的完全虚拟化。而Xen早期则是基于软件模拟的Para-Virtualization,新版本则是基于硬件支持的完全虚拟化。但Xen本身有自己的进程调度器,存储管理模块等,所以代码较为庞大。广为流传的商业系统虚拟化软件VMware ESX系列是基于软件模拟的Full-Virtualization。
- 中文名:KVM虚拟机
- 解 释:一个开源的系统虚拟化模块
- 应 用:Linux自身的调度器进行管理
- 价 值:成为学术界的主流VMM之一
- 本文系统环境:Centos 7.0
安装KVM
- 使用egrep ‘(vmx|svm)’ /proc/cpuinfo 命令验证CPU是否支持KVM;如果结果中有vmx(Intel)或svm(AMD)字样,就说明CPU的支持的。
[root@localhost.localdomain:/root]
# egrep '(vmx|svm)' /proc/cpuinfo
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology tsc_reliable nonstop_tsc aperfmperf pni pclmulqdq vmx ssse3 cx16 sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes hypervisor lahf_lm ida arat epb dtherm tpr_shadow vnmi ept vpid tsc_adjust
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology tsc_reliable nonstop_tsc aperfmperf pni pclmulqdq vmx ssse3 cx16 sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes hypervisor lahf_lm ida arat epb dtherm tpr_shadow vnmi ept vpid tsc_adjust
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology tsc_reliable nonstop_tsc aperfmperf pni pclmulqdq vmx ssse3 cx16 sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes hypervisor lahf_lm ida arat epb dtherm tpr_shadow vnmi ept vpid tsc_adjust
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology tsc_reliable nonstop_tsc aperfmperf pni pclmulqdq vmx ssse3 cx16 sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes hypervisor lahf_lm ida arat epb dtherm tpr_shadow vnmi ept vpid tsc_adjust
- 关闭SELinux,将 /etc/sysconfig/selinux 中的 SELinux=enforcing 修改为 SELinux=disabled
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
- 因为我是刚安装好的CentOS,所以为了下面方便点,先把一些必要的工具安装下
yum install epel-release net-tools vim unzip zip wget -y
- 安装KVM及其依赖项
yum install qemu-kvm libvirt virt-install bridge-utils openssl -y
- 使用lsmod | grep kvm命令验证安装结果,下图说明已经成功安装了
[root@localhost.localdomain:/root]
# lsmod | grep kvm
kvm_intel 138567 0
kvm 441119 1 kvm_intel
- 开启kvm服务,并且设置其开机自动启动
[root@localhost.localdomain:/root]
# systemctl start libvirtd
[root@localhost.localdomain:/root]
# systemctl enable libvirtd
- 查看状态操作结果,如下图所示,说明运行情况良好
[root@localhost.localdomain:/root]
# systemctl status libvirtd
● libvirtd.service - Virtualization daemon
Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2020-04-13 21:50:59 CST; 54s ago
Docs: man:libvirtd(8)
https://libvirt.org
Main PID: 14134 (libvirtd)
CGroup: /system.slice/libvirtd.service
├─14134 /usr/sbin/libvirtd
├─14244 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper
└─14245 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper
Apr 13 21:50:59 localhost.localdomain libvirtd[14134]: 2020-04-13 13:50:59.333 0000: 14150: warning : virQEMUCapsInit:955 : Failed to get host CPU cache info
Apr 13 21:50:59 localhost.localdomain libvirtd[14134]: 2020-04-13 13:50:59.694 0000: 14150: warning : virLXCDriverCapsInit:82 : Failed to get host CPU cache info
Apr 13 21:51:00 localhost.localdomain dnsmasq[14244]: started, version 2.66 cachesize 150
Apr 13 21:51:00 localhost.localdomain dnsmasq[14244]: compile time options: IPv6 GNU-getopt DBus no-i18n IDN DHCP DHCPv6 no-Lua TFTP no-conntrack ipset auth
Apr 13 21:51:00 localhost.localdomain dnsmasq-dhcp[14244]: DHCP, IP range 192.168.122.2 -- 192.168.122.254, lease time 1h
Apr 13 21:51:00 localhost.localdomain dnsmasq[14244]: reading /etc/resolv.conf
Apr 13 21:51:00 localhost.localdomain dnsmasq[14244]: using nameserver 192.168.0.1#53
Apr 13 21:51:00 localhost.localdomain dnsmasq[14244]: read /etc/hosts - 2 addresses
Apr 13 21:51:00 localhost.localdomain dnsmasq[14244]: read /var/lib/libvirt/dnsmasq/default.addnhosts - 0 addresses
Apr 13 21:51:00 localhost.localdomain dnsmasq-dhcp[14244]: read /var/lib/libvirt/dnsmasq/default.hostsfile
- 在/etc/sysconfig/network-scripts/目录下创建ifcfg-br0文件,内容如下
[root@localhost.localdomain:/etc/sysconfig/network-scripts]
# vim ifcfg-br0
BOOTPROTO=static
DEVICE=br0
TYPE=Bridge
NM_CONTROLLED=no
IPADDR=192.168.0.145
NETMASK=255.255.255.0
GATEWAY=192.168.0.1
- 修改原网卡配置文件,内容如下(修改之前最好先备份一下)
[root@localhost.localdomain:/etc/sysconfig/network-scripts]
# vim ifcfg-eno16777736
BOOTPROTO=none
DEVICE=eno16777736
NM_CONTROLLED=no
ONBOOT=yes
BRIDGE=br0
- 重启网络服务,使用 ifconfig 验证操作结果,多了一块网卡br0,能访问网络表示成功。
[root@localhost.localdomain:/etc/sysconfig/network-scripts]
# systemctl restart network
[root@localhost.localdomain:/etc/sysconfig/network-scripts]
# ifconfig
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.145 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::20c:29ff:fe4f:dcdb prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:4f:dc:db txqueuelen 0 (Ethernet)
RX packets 30 bytes 4987 (4.8 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 28 bytes 4237 (4.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eno16777736: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::20c:29ff:fe4f:dcdb prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:4f:dc:db txqueuelen 1000 (Ethernet)
RX packets 53284 bytes 69822549 (66.5 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 36366 bytes 4039403 (3.8 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
RX packets 8 bytes 688 (688.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 688 (688.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255
ether 52:54:00:7c:b0:34 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 7 bytes 1111 (1.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
安装虚拟机
- 创建创建虚拟机文件存放的目录和iso文件存放目录,准备操作系统安装镜像文件,在本文中将使用和宿主环境一样的CentOS7.0,把该文件放到 /data/kvm/iso 目录下
[root@localhost.localdomain:/etc/sysconfig/network-scripts]
# mkdir -p /data/kvm {kvm-mv,iso}
[root@localhost.localdomain:/data/iso]
# scp CentOS-7.0-1406-x86_64-DVD.iso root@192.168.0.145:/data/kvm/iso <==我这里是从另外的机器上的镜像传过来的
- 使用 virt-install 创建虚拟机(virt-install命令详情请点击这里)
virt-install --vcpus=2 -n Centos7.0-1 -r 1024 --disk /data/kvm/kvm-mv/Centos7.0-1.img,format=qcow2,size=10 --network bridge=br0 --os-type=linux --os-variant=rhel7.0 --cdrom /data/kvm/iso/CentOS-7.0-1406-x86_64-DVD.iso --vnc --vncport=5910 --vnclisten=0.0.0.0
- 操作结果显示:
[root@localhost.localdomain:/data/kvm/iso]
# virt-install --vcpus=2 -n Centos7.0-1 -r 1024 --disk /data/kvm/kvm-mv/Centos7.0-1.img,format=qcow2,size=10 --network bridge=br0 --os-type=linux --os-variant=rhel7.0 --cdrom /data/kvm/iso/CentOS-7.0-1406-x86_64-DVD.iso --vnc --vncport=5910 --vnclisten=0.0.0.0
WARNING Unable to connect to graphical console: virt-viewer not installed. Please install the 'virt-viewer' package.
WARNING No console to launch for the guest, defaulting to --wait -1
Starting install...
Allocating 'Centos7.0-1.img' | 10 GB 00:00:00
Domain installation still in progress. Waiting for installation to complete.
- 打开防火墙上的5910端口
[root@localhost.localdomain:/root]
# firewall-cmd --zone=public --add-port=5910/tcp --permanent
success
[root@localhost.localdomain:/root]
# firewall-cmd --reload
success
- 使用VNC连接该虚拟机,进行虚拟机操作系统的安装,直接到VNC官网上下载最新版的VNC Viewer即可(这一步步骤请自行google)
- 装完CentOS,重启系统。使用virsh list --all命令查看虚拟机状态,显示虚拟机正在运行状态,虚拟机就创建成功了。
[root@localhost.localdomain:/data/kvm/iso]
# virsh list --all
Id Name State
----------------------------------------------------
2 Centos7.0-1 running
创建windows虚拟机命令
代码语言:javascript复制virt-install --vcpus=2 -n windows_2012 -r 2048 --disk /data/kvm/windows2012.qcow2,format=qcow2,size=20 --network bridge=br0 --os-type=windows --os-variant=win2k12r2 --cdrom /data/iso/cn_windows_server_2012_r2_x64_dvd_2707961.iso --disk path=/data/iso/virtio-win-1.7.4.iso,device=floppy --vnc --vncport=5910 --vnclisten=0.0.0.0
简单配置KVM虚拟机
- 使用vnc连接上虚拟机,进入虚拟机系统之后配置好网络(和物理机配置网络一样,这里就不描述了)
- 配置在宿主端登录虚拟机shell。编辑 /etc/default/grub 文件(建议先备份一份),内容如下:
[root@localhost.localdomain:/data/kvm/iso]
# vim /etc/default/grub
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL="console serial"
GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"
GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb"
GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0,115200"
GRUB_DISABLE_RECOVERY="true"
- 运行grub2-mkconfig -o /boot/grub2/grub.cfg 之后重启虚拟机 reboot
[root@localhost.localdomain:/data/kvm/iso]
# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-123.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-123.el7.x86_64.img
Warning: Please don't use old title `CentOS Linux, with Linux 3.10.0-123.el7.x86_64' for GRUB_DEFAULT, use `Advanced options for CentOS Linux>CentOS Linux, with Linux 3.10.0-123.el7.x86_64' (for versions before 2.00) or `gnulinux-advanced-ccd3b657-a799-4562-86ed-cee7a3eded92>gnulinux-3.10.0-123.el7.x86_64-advanced-ccd3b657-a799-4562-86ed-cee7a3eded92' (for 2.00 or later)
Found linux image: /boot/vmlinuz-0-rescue-bf745f5a0bdc47c99aaf11abcf6934f3
Found initrd image: /boot/initramfs-0-rescue-bf745f5a0bdc47c99aaf11abcf6934f3.img
done
[root@localhost default]# reboot
- 在宿主机上进入虚拟机控制台,想退出时使用 Ctrl 键 ] (左方括号)键退出。
[root@localhost.localdomain:/data/kvm/iso]
# virsh list --all
Id Name State
----------------------------------------------------
2 Centos7.0-1 running
[root@localhost.localdomain:/data/kvm/iso]
# virsh console Centos7.0-1
Connected to domain Centos7.0-1
Escape character is ^]
CentOS Linux 7 (Core)
Kernel 3.10.0-123.el7.x86_64 on an x86_64
localhost login:
迁移虚拟机
虚拟机建好后,最大的好处就是任由我们折腾,而不用担心重装系统的麻烦。所以一定要知道虚拟机怎么复制迁移,这里有两种情况,一种是本机上镜像复制,另一种是将本机镜像迁移到其他服务器上。
本机复制
- 先关闭虚拟机
[root@localhost.localdomain:/data/kvm/iso]
# virsh list --all
Id Name State
----------------------------------------------------
2 Centos7.0-1 running
[root@localhost.localdomain:/data/kvm/iso]
# virsh shutdown Centos7.0-1
Domain Centos7.0-1 is being shutdown
- 使用 virt-clone 克隆think8848-kvmbase为新的虚拟机
[root@localhost.localdomain:/data/kvm/iso]
# virt-clone -o Centos7.0-1 -n Centos7.0-1.bak -f /data/kvm/kvm-mv/Centos7.0-1.bak.img
WARNING Setting the graphics device port to autoport, in order to avoid conflicting.
Allocating 'Centos7.0-1.bak.img' | 10 GB 00:00:05
Clone 'Centos7.0-1.bak' created successfully.
- 使用 virsh list --all 查看
[root@localhost.localdomain:/data/kvm/iso]
# virsh list --all
Id Name State
----------------------------------------------------
- Centos7.0-1 shut off
- Centos7.0-1.bak shut off
- 开启Centos7.0-1.bak,然后修改IP地址、主机名等(步骤略过)这里就克隆完成了
将虚拟机镜像迁移到其他服务器上
- 关闭需要迁移的虚拟机
[root@localhost.localdomain:/data/kvm/iso]
# virsh shutdown Centos7.0-1.bak
Domain Centos7.0-1.bak is being shutdown
- 先将虚拟机的配置文件和镜像文件传到目标服务器上相应的位置(具体看目标服务器虚拟机配置文件和镜像文件存放位置。)
[root@localhost.localdomain:/etc/libvirt/qemu]
# cd /etc/libvirt/qemu
[root@localhost.localdomain:/etc/libvirt/qemu]
# scp Centos7.0-1.bak.xml root@192.168.0.169:/etc/libvirt/qemu
The authenticity of host '192.168.0.169 (192.168.0.169)' can't be established.
ECDSA key fingerprint is fa:15:d8:74:b1:46:44:2a:5b:9a:67:31:d6:68:0d:8f.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.0.169' (ECDSA) to the list of known hosts.
root@192.168.0.169's password:
Centos7.0-1.bak.xml 100% 4102 4.0KB/s 00:00
[root@localhost.localdomain:/etc/libvirt/qemu]
# cd /data/kvm/kvm-mv/
[root@localhost.localdomain:/data/kvm/kvm-mv]
# scp Centos7.0-1.bak.img root@192.168.0.169:/data/kvm
root@192.168.0.169's password:
Centos7.0-1.bak.img 100% 1057MB 39.2MB/s 00:27
- 编辑Centos7.0-1.bak.xml 更改虚拟机镜像文件.img的路径,然后把UUID换为新的(直接使用这个在线工具生成吧)
[root@localhost.localdomain:/etc/libvirt/qemu]
# vim Centos7.0-1.bak.xml
<!--
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 Centos7.0-1.bak
or other application using the libvirt API.
-->
<domain type='kvm'>
<name>Centos7.0-1.bak</name>
<uuid>fc7d1816-ceaf-40c5-947a-b293d4d734ef</uuid> <===重新生成的uuid
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
<vcpu placement='static'>2</vcpu>
<os>
<type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>
<boot dev='hd'/>
</os>
<features>
<acpi/>
<apic/>
</features>
<cpu mode='custom' match='exact' check='partial'>
<model fallback='allow'>Westmere</model>
</cpu>
<clock offset='utc'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>
</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='/data/kvm/Centos7.0-1.bak.img'/> <===镜像路径
<target dev='vda' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
- 定义新虚拟机并验证
[root@localhost.localdomain:/etc/libvirt/qemu]
# virsh define /etc/libvirt/qemu/Centos7.0-1.bak.xml
Domain Centos7.0-1.bak defined from /etc/libvirt/qemu/Centos7.0-1.bak.xml
[root@localhost.localdomain:/etc/libvirt/qemu]
# virsh list --all
Id Name State
----------------------------------------------------
- Centos7.0-1.bak shut off
[root@localhost.localdomain:/etc/libvirt/qemu]
# virsh start Centos7.0-1.bak
Domain Centos7.0-1.bak started
[root@localhost.localdomain:/etc/libvirt/qemu]
# virsh console Centos7.0-1.bak
Connected to domain Centos7.0-1.bak
Escape character is ^]
[root@localhost ~]#
- 测试ok,到此异地迁移虚拟机就完成了。
- 最后一个问题,如果在克隆或迁移后想使用VNC连接,那就需要重新指定VNC的端口号,将 /etc/libvirt/qemu/Centos7.0-1.bak.xml 中的VNC端口号修改你需要的值即可。注:改了之后需要重新定义虚拟机
<graphics type='vnc' port='10000' autoport='no' listen='0.0.0.0'>
<listen type='address' address='0.0.0.0'/>
</graphics
KVM管理
请产考kvm常用命令