KVM（Kernel-based Virtual Machine的英文缩写）是内核内建的虚拟机。有点类似于 Xen ，但更追求更简便的运作，比如运行此虚拟机，仅需要加载相应的
kvm 模块即可后台待命。和 Xen 的完整模拟不同的是，KVM 需要芯片支持虚拟化技术（英特尔的 VT 扩展或者 AMD 的 AMD-V 扩展）。
KVM, Xen, VMware, 和 QEMU 的不同，请看这里KVM FAQ.
$ grep -E "(vmx|svm)" --color=always /proc/cpuinfo
如果你的内核是用 CONFIG_IKCONFIG_PROC 这个选项编译的话，你可以通过以下命令来检查你的内核是否已经包含了支持虚拟化所必须的模块（
$ zgrep KVM /proc/config.gz
Para-virtualization provides a fast and efficient means of communication for guests to use devices on the host machine. KVM provides para-virtualized devices to virtual machines using the Virtio API as a layer between the hypervisor and guest.
All virtio devices have two parts: the host device and the guest driver.
Use the following command to check if needed modules are available:
$ zgrep VIRTIO /proc/config.gz
Loading kernel modules
First, check if the kernel modules are automatically loaded. This should be the case with recent versions of udev.
$ lsmod | grep kvm $ lsmod | grep virtio
In case the above commands return nothing, you need to load kernel modules.
List of para-virtualized devices
- network device (virtio-net)
- block device (virtio-blk)
- controller device (virtio-scsi)
- serial device (virtio-serial)
- balloon device (virtio-balloon)
# modprobe -r kvm_intel # modprobe kvm_intel nested=1
使嵌套虚拟化永久生效（请参考Kernel modules#Setting module options）：
options kvm_intel nested=1
$ systool -m kvm_intel -v | grep nested
nested = "Y"
$ qemu-system-x86_64 -enable-kvm -cpu host
$ grep vmx /proc/cpuinfo
A feature called external snapshotting allows one to take a live snapshot of a virtual machine without turning it off. Currently it only works with qcow2 and raw file based images.
Once a snapshot is created, KVM attaches that new snapshotted image to virtual machine that is used as its new block device, storing any new data directly to it while the original disk image is taken offline which you can easily copy or backup. After that you can merge the snapshotted image to the original image, again without shutting down your virtual machine.
Here's how it works.
Current running vm
# virsh list --all Id Name State ---------------------------------------------------- 3 archey running
List all its current images
# virsh domblklist archey Target Source ------------------------------------------------ vda /vms/archey.img
Notice the image file properties
# qemu-img info /vms/archey.img image: /vms/archey.img file format: qcow2 virtual size: 50G (53687091200 bytes) disk size: 2.1G cluster_size: 65536
Create a disk-only snapshot. The switch
--atomic makes sure that the VM is not modified if snapshot creation fails.
# virsh snapshot-create-as archey snapshot1 --disk-only --atomic
List if you want to see the snapshots
# virsh snapshot-list archey Name Creation Time State ------------------------------------------------------------ snapshot1 2012-10-21 17:12:57 -0700 disk-snapshot
Notice the new snapshot image created by virsh and its image properties. It weighs just a few MiBs and is linked to its original "backing image/chain".
# qemu-img info /vms/archey.snapshot1 image: /vms/archey.snapshot1 file format: qcow2 virtual size: 50G (53687091200 bytes) disk size: 18M cluster_size: 65536 backing file: /vms/archey.img
At this point, you can go ahead and copy the original image with
cp -sparse=true or
Then you can merge the original image back into the snapshot.
# virsh blockpull --domain archey --path /vms/archey.snapshot1
Now that you have pulled the blocks out of original image, the file
/vms/archey.snapshot1 becomes the new disk image. Check its disk size to see what it means. After that is done, the original image
/vms/archey.img and the snapshot metadata can be deleted safely. The
virsh blockcommit would work opposite to
blockpull but it seems to be currently under development in qemu-kvm 1.3 (including snapshot-revert feature), scheduled to be released sometime next year.
This new feature of KVM will certainly come handy to the people who like to take frequent live backups without risking corruption of the file system.
Poor Man's Networking
Setting up bridged networking can be a bit of a hassle sometimes. If the sole purpose of the VM is experimentation, one strategy to connect the host and the guests is to use SSH tunneling.
The basic steps are as follows:
- Setup an SSH server in the host OS
- (optional) Create a designated user used for the tunneling (e.g. tunneluser)
- Install SSH in the VM
- Setup authentication
When using the default user network stack, the host is reachable at address 10.0.2.2.
If everything works and you can SSH into the host, simply add something like the following to your
# Local SSH Server echo "Starting SSH tunnel" sudo -u vmuser ssh firstname.lastname@example.org -N -R 2213:127.0.0.1:22 -f # Random remote port (e.g. from another VM) echo "Starting random tunnel" sudo -u vmuser ssh email@example.com -N -L 2345:127.0.0.1:2345 -f
In this example a tunnel is created to the SSH server of the VM and an arbitrary port of the host is pulled into the VM.
This is a quite basic strategy to do networking with VMs. However, it is very robust and should be quite sufficient most of the time.
Enabling huge pages
You may also want to enable hugepages to improve the performance of your virtual machine.
With an up to date Arch Linux and a running KVM you probably already have everything you need. Check if you have the directory
/dev/hugepages. If not create it.
Now we need the right permissions to use this directory. Check if the group
kvm exist and if you are member of this group. This should be the case if you already have a running virtual machine.
$ getent group kvm
Add to your
hugetlbfs /dev/hugepages hugetlbfs mode=1770,gid=78 0 0
Of course the gid must match that of the
kvm group. The mode of
1770 allows anyone in the group to create files but not unlink or rename each other's files. Make sure
/dev/hugepages is mounted properly:
# umount /dev/hugepages # mount /dev/hugepages $ mount | grep huge
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime,mode=1770,gid=78)
Now you can calculate how many hugepages you need. Check how large your hugepages are:
$ cat /proc/meminfo | grep Hugepagesize
Normally that should be 2048 kB ≙ 2 MB. Let's say you want to run your virtual machine with 1024 MB. 1024 / 2 = 512. Add a few extra so we can round this up to 550. Now tell your machine how many hugepages you want:
# echo 550 > /proc/sys/vm/nr_hugepages
If you had enough free memory you should see:
$ cat /proc/meminfo | grep HugePages_Total
If the number is smaller, close some applications or start your virtual machine with less memory (number_of_pages x 2):
$ qemu-system-x86_64 -enable-kvm -m 1024 -mem-path /dev/hugepages -hda <disk_image> [...]
-mem-path parameter. This will make use of the hugepages.
Now you can check, while your virtual machine is running, how many pages are used:
$ cat /proc/meminfo | grep HugePages
HugePages_Total: 550 HugePages_Free: 48 HugePages_Rsvd: 6 HugePages_Surp: 0
Now that everything seems to work you can enable hugepages by default if you like. Add to your
vm.nr_hugepages = 550