This how-to will help you setting-up a very powerful development environment on your workstation, using virtual machines all in a virtual local network.
But Why ?
You work on various projects, with specific requirements, with various technologies, diverse operating systems or cpu architectures, usually with a couple of services like databases or Web servers.
You would prefer not taking this whole family with you each time you start your machine.
Probably, you also want to upgrade your workstation to the last unstable eye-candy OS without compromising your projects dependencies and without reinstalling all this stuff, or you may want to restore the environment you had when you were working on this famous project a year ago.
You want your colleague to give you a hand, and would like to give him your whole project environment and dependencies quickly and effortlessly ? Your sysadmin put KVM on servers and you would like to push your local instances on production in a blink ?
The magic medicine exists, and is freely available :)
At the end, you are promised to enjoy :
- a GUI to manage your Virtual Machines (VM)
- a local domain to access your VMs by their name
- a fully integrated set of machines, accessible from each others
- movable and shareable virtual machines with automatic network configuration
We chose the Linux Kernel-based Virtualization System (KVM), since it is maintained along with the Linux kernel, and is thus fully integrated in the OS. However, this how-to is mainly networking oriented and would be useful for any virtualization system.
A Strict Minimum
A strict minimum is to install kvm and a set of commands to control it : libvirt. As a human being, you may want a GUI : virt-manager.
sudo apt-get install kvm libvirt-bin virt-manager
Virtual Machines Network
Make sure your VM networking is set to NAT. This will allow your VM to access your host network (LAN, Internet, etc.)
During your VM operating system installation, or after login into it, setup your VM network interface as automatic DHCP.
By default KVM creates a virtual network (virnet). Inspect its setup using ifconfig or virt-manager in Connection Details > Virtual Networks. Your VM and your host are thus accessible within this virtual network (probably 172.16.23.0).
A Local Network Domain
In order to access your VM by their name, we run a DNS daemon on main host. We chose bind :
sudo aptitude install bind9
Add a new master zone, for example sillywalk.loc in the file /etc/bind/named.conf.local :
zone "sillywalk.loc" { type master; file "/etc/bind/db.sillywalk.loc"; };
Define your DNS entries :
- Set the name server authority (SOA) to ns.sillywalk.loc (nameserver)
- Define a serial number like date+number (YYYYmmdd##)
- Associate ns.sillywalk.loc to the IP of your KVM virtual network (see above paragraph)
- Define an alias gw.sillywalk.loc so that you can refer to your host as gw (gateway) instead of ns.
- Define a couple of entries for your VM (e.g. myvm1, myvm2)
For bind, it would look like this (started from an existing file like ``/etc/bind/db.empty``) :
;/etc/bind/db.sillywalk.loc ; ; BIND data file for local loopback interface ; $TTL 604800 @ IN SOA ns.sillywalk.loc. root.ns.sillywalk.loc. ( 2011080301 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; @ IN NS ns.sillywalk.loc. @ IN A 172.16.23.1 ns IN A 172.16.23.1 gw IN CNAME ns.sillywalk.loc. myvm1 IN A 172.16.23.11 myvm2 IN A 172.16.23.12
Use your DNS
Use your Network Manager to set the search domain to sillywalk.loc and to add your local DNS server (127.0.0.1) in front of the other(s).
Apply and your /etc/resolv.conf could then look like this :
# Generated by NetworkManager search sillywalk.loc # search domain nameserver 127.0.0.1 # your local DNS server nameserver 192.168.1.254 # your FAI/company DNS nameserver 8.8.8.8 # Google public DNS
Test it !
Even if your VM are not running, you can at least test the name resolving and the default search domain :
~$ ping myvm1.sillywalk.loc
PING myvm1.sillywalk.loc (172.16.23.11) 56(84) bytes of data.
# (Ctrl+C)
~$ ping myvm2
PING myvm2.sillywalk.loc (172.16.23.12) 56(84) bytes of data.
# (Ctrl+C)
Dynamic Configuration
In order to make sure your VM always obtains the same IP adress when it boots, we setup a DHCP daemon on host.
We chose ISC DHCP server :
sudo aptitude install isc-dhcp-server
In the configuration file /etc/dhcp/dhcpd.conf, we specify :
- a domain name (sillywalk.loc)
- the name server to be configured on clients (ns.sillywalk.loc)
- the subnet and mask (matching the KVM virtual network)
- an IP range (e.g. from 172.16.23.10 to 172.16.23.100)
- the default gateway to be configured on clients (ns.sillywalk.loc)
- ... and two entries for myvm1 and myvm2 with their Mac addresses.
# /etc/dhcp/dhcpd.conf option domain-name "sillywalk.loc"; option domain-name-servers ns.sillywalk.loc; subnet 172.16.23.0 netmask 255.255.255.0 { range 172.16.23.10 172.16.23.100; option broadcast-address 172.16.23.255; option routers gw.sillywalk.loc; } # Entries host myvm1 { hardware ethernet 52:54:00:55:d1:80; fixed-address myvm1.sillywalk.loc; } host myvm2 { hardware ethernet 52:54:00:55:e1:66; fixed-address myvm2.sillywalk.loc; }
Test it !
Log you in on the VM.
- Configure its hostname (e.g. myvm1, myvm2)
root@myvm1:~# cat /etc/hostname
myvm1
root@myvm1:~# cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 myvm1.sillywalk.loc myvm1
- Make sure your VM network is set to DHCP automatic configuration
root@myvm1:~# cat /etc/network/interfaces
...
# The primary network interface
allow-hotplug eth0
iface eth0 inet dhcp
- Reboot it (or restart networking)
- Check that it caught the right network configuration (IP, domain, and nameserver)
root@myvm1:~# ifconfig
eth0 Link encap:Ethernet HWaddr 52:54:00:55:d1:80
inet addr:172.16.23.11 Bcast:172.16.23.255 Mask:255.255.255.0
...
root@myvm1:~# cat /etc/resolv.conf
domain sillywalk.loc
search sillywalk.loc
nameserver 172.16.23.1
Note
While your host is booting, the DHCP daemon usually starts before the KVM service, failing then at accessing the virtual network interface (virbr1, 172.16.23.0), not yet mounted.
A simple solution is to manually restart your DHCP daemon, once your machine's booted :
sudo /etc/init.d/isc-dhcp-server restart
Checklist to add a new VM
- Get its Mac address (with virt-manager : Virtual machine details > Virtual network interface > Mac Address)
- Add it to your DHCP configuration (/etc/dhcp/dhcpd.conf)
- Add an IP for this entry in your DNS zone (/etc/bind/db.sillywalk.loc) and increment the serial.
- Restart DHCP service and reload DNS configuration
sudo /etc/init.d/isc-dhcp-server restart
sudo /etc/init.d/bind9 reload
If you do that all day, you'll quickly find it relevant to write a script...
Note on cloning
Cloning your VM with virt-manager is a piece-of-cake.
However, during cloning, KVM assigns a new Mac address to the clone. For debian-based virtual machines (+Ubuntu), log you in on the clone, and reinitialize network interfaces names :
sudo rm /etc/udev/rules.d/70-persistent-net.rules
sudo reboot
Conclusion
Your virtual machines can :
- access your network (LAN, Internet) and your host (at ns.sillywalk.loc)
- be accessed at user@hostname (from host or from other VMs)
- be moved to any host set up likewise (since VM networking is fully automatic)
- be cloned easily
Read again "But Why ?" and enjoy your new life !
#network, #kvm, #virtualization, #howto - Posted in the Sys category