Installing KVM on Debian 8 (Jessie)

I recently bought a HP MicroServer gen8, and part of my plan for it was to use it as a host for virtual machines. After some research, I chose to use KVM as my hypervisor as it would allow me to store the VM disk/mounts on a software RAID array, something that's not (easily) possible using VMware ESXi.

My setup tries to modify as little of the out-of-the-box Debian 8 configuration as possible. I enable public bridging so that all of my VMs are accessible from my wider LAN, but a private bridge could be added later.

Let's go

Make yourself comfortable

sudo apt-get install tmux vim  

Install KVM and tools

Install KVM, CLI tools (including virsh) and tunctl utility (required for setting up public bridging):

sudo apt-get install qemu-kvm libvirt-bin uml-utilities  
sudo adduser <user> kvm  
sudo adduser <user> libvirt  

This should now work (no VMs listed):

virsh --connect qemu:///system list --all  

Set up bridge networking

Add a bridge adapter. This will wrap the existing eth0 interface, which I'm using DHCP on (as I use address reservation on my home router to gain a "static" address). Debian 8 uses NetworkManager to configure networking, so in /etc/network/interfaces no adapters (besides loopback) will be listed.

Add the following to /etc/networking/interfaces:

# Bridge for KVM
auto br0  
iface br0 inet dhcp  
    bridge_ports eth0
    bridge_stp off
    bridge_maxwait 0
    bridge_fd 0

NetworkManager will stop managing any devices listed in /etc/networking/interfaces.

Reboot to ensure network changes have taken effect (restarting networking using the init script wasn't enough):

sudo reboot  

You should now be able to see the network bridge containing eth0 (bridge id redacted):

$ sudo brctl show
bridge name    bridge id       STP enabled interfaces  
br0        8000.xxxxxxxxxxxx   no      eth0  

And ip addr should show that the bridge adapter br0 has received an IP address via DHCP, and that eth0 no longer does:

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default  
    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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP group default qlen 1000  
    link/ether [redacted MAC] brd ff:ff:ff:ff:ff:ff
3: eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000  
    link/ether [redacted MAC] brd ff:ff:ff:ff:ff:ff
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default  
    link/ether [redacted MAC] brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.XX/24 brd 192.168.0.255 scope global br0
       valid_lft forever preferred_lft forever
    inet6 [redacted MAC]/64 scope global mngtmpaddr dynamic
       valid_lft 6917sec preferred_lft 3316sec
    inet6 [redacted MAC]/64 scope global mngtmpaddr dynamic
       valid_lft forever preferred_lft forever
    inet6 [redacted MAC]/64 scope link
       valid_lft forever preferred_lft forever

I haven't tested this setup, but I believe it should be complete. Next step is to install Docker, on which I will install a container for the Kimchi KVM management tool.