This set of notes is based on the wiki page on the CentOS Wiki Page on KVM
Required Hardware (Ideally)
Intel or AMD based machine that supports virtualisation. On intel based machines you can check by
grep vmx /proc/cpuinfo
On and AMD based machine you can check by
grep svm /proc/cpuinfo
Your host machine should probably be multi-core if possible, and have at least 2gigs of ram, but more is preferred. Have the appropriate kernel module loaded.
If its Intel do
If it's AMD do
Required Software (What I used)
- The ScientificLinux 5.4 distro installed on my host system.
- The kmod-kvm package - it's apart of the SL repos as far as I know.
- The kvm package - it's apart of the SL repos as far as I know.
- The QEMU stack, which came with the kvm package.
- The kvm-qemu-img - it's apart of the SL repos as far as I know.
- The bridge-utils package to setup a bridged network.
- The tunctl package which is available from the epel repository.
KVM should be apart of recent linux kernel releases (since 2.6.20 according to the releasenotes).
Specifically these were the packages I used...
[root@duo ~]# rpm -qa | egrep 'kvm|bridge-utils|tunctl' kvm-83-105.el5_4.13.x86_64 kmod-kvm-83-105.el5_4.13.x86_64 kvm-tools-83-105.el5_4.13.x86_64 etherboot-zroms-kvm-5.4.4-10.el5.0.sl.x86_64 bridge-utils-1.1-2.x86_64 kvm-qemu-img-83-105.el5_4.13.x86_64 tunctl-1.5-2.el5.x86_64
Creating a Virtual Machine
First make sure the permissions for the KVM device node is correct
chown root:kvm /dev/kvm chmod 0660 /dev/kvm
and add yourself to the kvm group
usermod -G kvm -a jtang
The process is
- Create a disk image with qemu-img or use dd
- Boot the disk image with qemu-kvm with a valid install media
There are some choices to be made when creating the images, you can either use the raw format which will result in pretty big full sized disk images. Or else you can use the qcow2 format which is a sparse format where the disk image will grow to the maximum size that you have defined.
Create the disk image
qemu-img create -f qcow2 disk.img 5G
dd if=/dev/zero of=disk.img bs=1G count=5
Boot the image for an install
Note in Scientific linux the qemu-kvm binary is located in /usr/libexec/qemu-kvm, you could create a symlink for it if you wish.
/usr/libexec/qemu-kvm -hda disk.img -cdrom archlinux-2009.08-core-x86_64.iso -m 512 -boot d
Once it is booted up you can just follow the instructions on installing your guest OS.
Bridged Tap Networking and KVM
By default KVM supports NAT for its guests, it's not ideal for production environments. I would prefer to have a bridged network so my guests can appear on my network with a real IP address . Edit /etc/udev/rules.d/90-kvm-rules such that
KERNEL=="kvm", NAME="%k", GROUP="kvm", MODE="0660" KERNEL=="tun", NAME="net/%k", GROUP="kvm", MODE="0660"
or else do this in /etc/rc.local
chown root:kvm /dev/net/tun chmod 0660 /dev/net/tun
Now run these commands
brctl addbr br0 ifconfig eth0 0.0.0.0 brctl addif br0 eth0 dhclient br0 tunctl -b -u jtang ifconfig tap0 up brctl addif br0 tap0 iptables -I RH-Firewall-1-INPUT -i br0 -j ACCEPT qemu-kvm ~/win2k.img -m 512 -net nic -net tap,ifname=tap0,script=no
If you do not have a DHCP server to assign your NIC an address you could do this in place of the dhclient command assuming you are on a 192.168.1.0/24 network.
ifconfig br0 192.168.1.120 netmask 255.255.255.0 up route add -net 192.168.1.0 netmask 255.255.255.0 br0 route add default gw 192.168.1.1 br0
Attempting to run the Virtual Machine
There are some issues that I haven't addressed, such as monitoring the kvm guest.
/usr/libexec/qemu-kvm -hda disk.img -m 512 -net nic -net tap,ifname=tap0,script=no -nographic -daemonize
I should probably configure the guest to be accessible via a serial console as well.
Using virtio for the networking
/usr/libexec/qemu-kvm -hda disk.img -m 512 -net nic,model=virtio -net tap,ifname=tap0,script=no
Using virtio for the storage
/usr/libexec/qemu-kvm -drive file=disk.img,if=virtio,boot=on -m 512 -net nic,model=virtio -net tap,ifname=tap0,script=no
You will need to correct references to sda/hda to vda in grub and in your fstab, and also make sure your initrd has the virtio, virtio_blk and virtio_pci loaded up at boot. The best thing to do is to use disk labels or blkid's for fstab instead of device names.
Installing ScientificLinux 5.4 as a guest
Some notes on installing SL5.4 as a guest. There's probably more efficient ways of doing this.
First create a disk image, I chose to use qcow2 32gb is size.
qemu-img create -f qcow2 sl5x.img 32G
Then install the OS, I used the SL5.4 install dvd. I suppose you could do a network install if you wanted.
/usr/libexec/qemu-kvm -drive file=sl5x.img,if=virtio,boot=on,cache=writethrough -m 768 -cdrom SL.54.110309.DVD.x86_64.disc1.iso
Running the virtual machine
/usr/libexec/qemu-kvm -drive file=sl54-kvm.img,if=virtio,boot=on,cache=writethrough \ -net nic,macaddr=DE:AD:BE:EF:25:12,model=virtio \ -net tap,ifname=tap0,script=no -m 768 -nographic
I also enabled a serial console and made grub redirect its output to the serial console.
My grub.conf file is now something like this
default=0 timeout=5 splashimage=(hd0,0)/grub/splash.xpm.gz hiddenmenu serial --unit=0 --speed=9600 --word=8 --parity =no --stop=1 terminal --timeout=10 --dumb serial console title Scientific Linux (2.6.18-164.2.1.el5) root (hd0,0) kernel /vmlinuz-2.6.18-164.2.1.el5 ro root=/dev/VolGroup00/LogVol00 console=tty0 console=ttyS0,9600n8 initrd /initrd-2.6.18-164.2.1.el5.img
And in the inittab near the bottom,
# Run gettys in standard runlevels co:2345:respawn:/sbin/agetty ttyS0 57600 vt100-nav 1:2345:respawn:/sbin/mingetty tty1 2:2345:respawn:/sbin/mingetty tty2 3:2345:respawn:/sbin/mingetty tty3 4:2345:respawn:/sbin/mingetty tty4 5:2345:respawn:/sbin/mingetty tty5 6:2345:respawn:/sbin/mingetty tty6
The above changes lets me connect to the virtual machine without needing a graphical interface. This however fails to work if you daemonize the process. According to the man pages it is possible to redirect the virtual machine serial port to the hosts serial port in /dev/xxx somewhere, I didn't get this to work. However I did get the redirection to a pty to work and I was able to connect to it via minicom.
Enlarging a disk image
I found this online, its the quickest way to enlarge your disk image, note it must be a raw image (assuming you started with a 10gb image you will end up with a 20gb image with the following commands)
dd if=/dev/zero of=foo.img bs=1 count=1 seek=$(($(stat -c%s foo.img)+10*1024**3-1))
dd if=/dev/null of=foo.img bs=1b seek=20G count=0
or you could cat a file full of zeros and append it to your diskimage, its up to you.
Apparently the best method and the safest method is to do this...
qemu-img create -f raw morespace.raw <size> qemu-img convert -f qcow2 existing.img -O raw existing.raw cat morespace.raw >> existing.raw qemu-img convert -f raw existing.raw -O qcow2 existing-larger.img
I haven't tried any of the above yet to confirm which is the best method.
- If you find that bridged networking doesn't work, make sure the tap interface has been added to the bridge.