It’s summer, it’s hot as hell, I am back home from mountains and I’ve plenty of free time.
Between a barbecue and the next one I spend my time playing with and learning new stuff: this week new stuff is called QEMU-KVM.
Yesterday I also tried XenServer but to be honest I wasn’t impressed, it just look like to be an old version of CentOS minimal install with some custom repos and a fancy GUI.
I played with it for just a bunch of hours, but the thing that just performing an installation on a software RAID-1 turned out to be a PITA to say the least is a clear sign that it’s not the best tool for my needs.
I swapped a couple of HDDs and in 2 minutes I went back to the already installed CentOS 6.4 with QEMU+KVM.
The client machine, for what it matters, is my Fedora 19 x86_64 workstation, virsh and virt-manager the tools I use for remote administration tasks.
Installing QEMU-KVM is just a matter of typing “yum install libvirtd qemu-kvm bla bla bla”, “chkconfig libvirtd on” and doing a system reboot (better safe than sorry).
The tricky part at least for me was setting up a damn bridged network interface, luckily I found this great writeup.
I am going to report here what I did to setup a couple of bridged network interfaces on my setup.
.:. Host side configuration
Here’s the desired setup:
eth0 192.168.0.254 which is the network interface/IP of the physical machine eth0:0 192.168.0.252 which is mapped to VM-1 192.168.0.2 eth0:1 192.168.0.253 which is mapped to VM-2 192.168.0.3
First of all, on the physical machine, create 2 files in “/etc/sysconfig/network-scripts/”:
# FILE NAME: ifcfg-eth0:0 DEVICE=eth0:0 BOOTPROTO=static ONBOOT=yes IPADDR=192.168.0.252 NETMASK=255.255.255.0
# FILE NAME: ifcfg-eth0:1 DEVICE=eth0:1 BOOTPROTO=static ONBOOT=yes IPADDR=192.168.0.253 NETMASK=255.255.255.0
Once done creating the two files restart the network service…
service network restart
…and add a couple of iptables rules:
iptables -A PREROUTING -d 192.168.0.252 -i eth0 -p tcp -j DNAT --to-destination 192.168.0.2 iptables -A PREROUTING -d 192.168.0.253 -i eth0 -p tcp -j DNAT --to-destination 192.168.0.3 service iptables save && service iptables restart
Since every time libvirtd service starts it overwrite the iptables rules to make the settings permanent we have to create a new service to be runned after libvirtd startup or edit the file /etc/rc.local.
I edited rc.local adding what follow:
touch /var/lock/subsys/local iptables -I FORWARD -i eth0 -o virbr0 -p tcp -m state --state NEW -j ACCEPT iptables -I FORWARD -i eth0 -o virbr1 -p tcp -m state --state NEW -j ACCEPT
Do another full restart (better safe than sorry :: 2) and everything should work.
Last thing to do is tell the VMs to use the bridged network adapter; to do it from virt-manager, select a virtual machine, edit -> Virtual Machine Details, NIC and select the preferred “eth0:x : macvtap” device from the drop down menu.
In the same page, as “Device model” select “virtio”, this way after the next shutdown (not reboot) the virtual machine will be executed with the extra parameter “vhost=on” which will boost network performance.
Check that “vhost_net” module is correctly loaded with the command:
[root@server ~]# lsmod | grep vhost vhost_net 30520 1 macvtap 9948 3 vhost_net tun 17063 2 vhost_net
If “vhost_net” module is loaded, check if it’s actually used for the VMs with:
[root@server ~]# ps -ef | grep vhost qemu 4721 1 4 17:51 ? 00:03:03 /usr/libexec/qemu-kvm -name torrent -S -M rhel6.4.0 -enable-kvm -m 256 -smp 1,sockets=1,cores=1,threads=1 -uuid e32dbfd9-fe79-fd4a-b7a8-58697db41a56 -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/torrent.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -drive file=/home/virtual-machines/torrent.img,if=none,id=drive-virtio-disk0,format=raw -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 -drive if=none,media=cdrom,id=drive-ide0-1-0,readonly=on,format=raw -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 -netdev tap,fd=23,id=hostnet0,vhost=on,vhostfd=24 -device virtio-net-pci,__com_redhat_macvtap_compat=on,netdev=hostnet0,id=net0,mac=52:54:00:62:52:18,bus=pci.0,addr=0x3 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -device usb-tablet,id=input0 -vnc 127.0.0.1:0 -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5 root 4723 2 1 17:51 ? 00:00:47 [vhost-4721] root 5746 3701 0 18:56 pts/0 00:00:00 grep vhost
The string paramater “vhost=on” should be present in every QEMU-KVM related process (in my case the one with PID 4721).
.:. Guest side configuration :: static IP address
First of all, my virtual machines are all based on CentOS 6.4 minimal netinstall.
I like them to have a static IP address (VM-1 192.168.0.2 and VM-2 192.168.0.3), which is a pretty easy task.
[root@VM-1 ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth2 # add/edit the following lines and comment BOOTPROTO="dhcp" if present IPADDR=192.168.0.2 GATEWAY=192.168.0.1 NETMASK=255.255.255.0 [root@VM-1 ~]# service network restart
Now the VM-1 should have a static IP address.
.:. Guest side configuration :: troubleshooting
If you happen to had deleted the virtual network adapter from virt-manager, when you add a new one it will have a different random MAC address and the guest OS will not see it anymore (CentOS prints an error during bootup).
The solution consists of two steps:
1. edit the file “/etc/sysconfig/network-scripts/ifcfg-eth*” with the new MAC address (the one shown in virt-manager) and the new device name (if it was eth0, write eth1, if it was eth1, write eth2).
There should be a way to force the new virtual network adapter to the use good old eth0, but I don’t know how to do it.
2. delete the file “/etc/udev/rules.d/70-persistent-net.rules”.
3. ok, I lied, the third step is restart the virtual machine.
This is it