cn:ccr:virtualizzazione:documentazione:kvm_howto
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
cn:ccr:virtualizzazione:documentazione:kvm_howto [2010/04/19 12:32] – andrea.chierici@cnaf.infn.it | cn:ccr:virtualizzazione:documentazione:kvm_howto [2010/04/19 13:07] (current) – andrea.chierici@cnaf.infn.it | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ===== KVM Howto ===== | ||
+ | ==== Documentation ==== | ||
+ | //Before trying anything with KVM read the official Red Hat documentation on KVM:// | ||
+ | http:// | ||
+ | |||
+ | I really mean it, READ THE OFFICIAL DOCUMENTATION! | ||
+ | |||
+ | ==== Host installation ==== | ||
+ | To install a kvm host it's necessary to use SL>=5.4; the minimum required rpms are: | ||
+ | |||
+ | * kmod-kvm | ||
+ | * kvm | ||
+ | * etherboot-roms-kvm | ||
+ | * qemu-img | ||
+ | * vnc | ||
+ | |||
+ | If you're using yum, simply issue this command: | ||
+ | |||
+ | < | ||
+ | yum install kvm | ||
+ | </ | ||
+ | |||
+ | ==== Network Configuration ==== | ||
+ | To be able to use public IP within your VMs, you need to perform the actions described in this section. | ||
+ | Be careful because the operations described in this paragraph may put your network offline, be ready to access a physical console of the host you are configuring. | ||
+ | |||
+ | On your host add the file /// | ||
+ | |||
+ | < | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | |||
+ | After this edit the file /// | ||
+ | < | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | After this restart the network with ''' | ||
+ | To be sure, you can use this command: | ||
+ | < | ||
+ | # | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | If //eth0// is in the same line of //br0//, your configuration is ok, you can now install machines with public ip addresses. | ||
+ | |||
+ | ==== Libvirt ==== | ||
+ | It's highly suggested to use libvirt tools to install, launch and monitor VMs. | ||
+ | |||
+ | === VM installation with libvirt === | ||
+ | Here is an example of VM virt-install with a standard infn-t1 configuration: | ||
+ | < | ||
+ | | ||
+ | --connect qemu:/// | ||
+ | --name wn-test-kvm \ | ||
+ | --accelerate \ | ||
+ | --ram 2048 \ | ||
+ | --disk path=/ | ||
+ | --network bridge:br0 \ | ||
+ | --mac 00: | ||
+ | --arch x86_64 \ | ||
+ | --location http:// | ||
+ | --vnc \ | ||
+ | --extra-args ks=http:// | ||
+ | </ | ||
+ | This creates a VM named wn-test-kvm using kvm, with 2GB ram, a single virtual CPU, a 10GB disk, a network connected to the bridge sw0 to use public ip, and installs via network using os-server as a repository server, with a specific ks file. | ||
+ | For other options see virt-install man page | ||
+ | |||
+ | == Virtio installation == | ||
+ | To use virtio drivers it's necessary to have latest kernel from SL release on your ''' | ||
+ | < | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | If you want to install a machine with virtio drivers you should add these lines to your virt-install command: | ||
+ | < | ||
+ | --os-type=linux \ | ||
+ | --os-variant=virtio26 \ | ||
+ | </ | ||
+ | Using this command you enable the virtio drivers at install time (for both sl4 and sl5). Please remember that virtio disks are called vdX instead of hdX, and this has to be taken into account if you are installing a machine via kickstart, because the partitioning directives may break. | ||
+ | |||
+ | === VM management with libvirt === | ||
+ | After installing a machine with // | ||
+ | |||
+ | === VM management with virsh === | ||
+ | //virsh// allows you to issue several useful control commands to VMs (see on-line manual). In order to do that, you have to install a machine with virt-install or to add an already running machine to libvirt control (undocumented in this wiki). | ||
+ | When you have a machine under libvirt/ | ||
+ | If you know exactly what you are doing, you can edit directly the //xml// file to change some parameters like, for example enable virtio for network. After having edited the configuration, | ||
+ | < | ||
+ | virsh define <VM name> | ||
+ | </ | ||
+ | This will update the info of your VMs matching the definition in the xml file. It's very important to use this command while virt-manager is not running on the hypervisor and while the VM is not running, otherwise the changes done to the xml may not be taken into consideration and the xml overwritten. | ||
+ | |||
+ | === Serial Console === | ||
+ | To enable a serial console for every VM you need to do the following steps: | ||
+ | |||
+ | in /// | ||
+ | < | ||
+ | | ||
+ | </ | ||
+ | in /// | ||
+ | < | ||
+ | | ||
+ | </ | ||
+ | After this, while the machine is running, to access the console of your VM, you can use this command: | ||
+ | < | ||
+ | virsh console < | ||
+ | </ | ||
+ | To disconnect simply use the combination ''' | ||
+ | ---- | ||
+ | |||
+ | |||
+ | ==== Legacy ==== | ||
+ | Following is a section that has to be considered legacy. RedHat integration of kvm is rather stable; users should not need to use the base command line to control kvm VMs. | ||
+ | |||
+ | === Network Configuration === | ||
+ | If you did not configure your host with br0 as described before, or if you are on a legacy node, to be able to properly configure a tunnel for a public IP address you also need: | ||
+ | < | ||
+ | * bridge-utils | ||
+ | * tunctl | ||
+ | </ | ||
+ | To configure kvm service on host node you need to add a couple of scripts. | ||
+ | < | ||
+ | # | ||
+ | |||
+ | | ||
+ | / | ||
+ | / | ||
+ | </ | ||
+ | This has to be put in /// | ||
+ | |||
+ | The second script sets-up a bridge to be used when connecting VMs with a public ip address. | ||
+ | It can be accessed via the quattor template: http:// | ||
+ | |||
+ | |||
+ | === Disk image creation === | ||
+ | To create a file to be used as a disk image: | ||
+ | < | ||
+ | | ||
+ | </ | ||
+ | |||
+ | === Launching a machine === | ||
+ | To launch a machine: | ||
+ | < | ||
+ | | ||
+ | </ | ||
+ | This command line specifies a machine with these options: | ||
+ | * < | ||
+ | * e1000 network driver (suggested!) | ||
+ | * mac address 00: | ||
+ | * 2048 MB ram | ||
+ | * vnc configured on port 0. The console can be reached with '' | ||
+ | |||
+ | For other options, see the qemu-kvm manual. | ||
+ | |||
+ | ==== Appendix A: Converting a running machine from standard IO to virtio ==== | ||
+ | |||
+ | === Net Virtio === | ||
+ | In order to enable your virtual machine to use //virtio net driver// you need to add a line to the xml file defining your guest. | ||
+ | |||
+ | A section like this: | ||
+ | < | ||
+ | < | ||
+ | <mac address=' | ||
+ | <source bridge=' | ||
+ | </ | ||
+ | </ | ||
+ | must become: | ||
+ | < | ||
+ | < | ||
+ | <mac address=' | ||
+ | <source bridge=' | ||
+ | **<model type=' | ||
+ | </ | ||
+ | <// | ||
+ | If you don't know how to deal with the xml, read the section about libvirt. | ||
+ | After this operation, turn on the VM and follow the messages on the console. It may happen that the system does not recognize your new network card. In this case edit the modprobe.conf file adding this line: | ||
+ | < | ||
+ | alias eth0 virtio_net | ||
+ | </ | ||
+ | and possibly reboot. The node should use the new driver now. | ||
+ | |||
+ | |||
+ | === HD virtio === | ||
+ | Quite often you will want to install virtio drivers on the boot hd. This causes problems due to the missing virtio drivers inside the initrd used at boot time. A quick and dirty hack is to copy a initrd file for your kernel from a machine already using the virtio disk driver on the same kernel of the machine you want to convert. | ||
+ | Anyway, due to some differences that may be hidden in configuration, | ||
+ | < | ||
+ | | ||
+ | </ | ||
+ | If the output is correct, you can move the new initrd in /boot and link it in grub.conf for your kernel. | ||
+ | After this, you should make sure that grub.conf and fstab do not contain links to hdX (in case they do, you need to change them to vdX. After this is done, shut down the VM and change the xml file this way: | ||
+ | < | ||
+ | <disk type=' | ||
+ | <source file=' | ||
+ | **< | ||
+ | </ | ||
+ | |||
+ | <disk type=' | ||
+ | <source file=' | ||
+ | **< | ||
+ | </ | ||
+ | </ | ||
+ | You can now power on your machine again and virtio disk //should// work. | ||
+ | |||
+ | ---- | ||
+ | ==== Appendix B: Virtio using command line ==== | ||
+ | If you want to use virtio devices via command line, you should use something like this: | ||
+ | < | ||
+ | / | ||
+ | -net nic, | ||
+ | </ | ||
+ | |||
+ | ==== Appendix C: Migrating net driver from e1000 to virtio_net, using sl53_x86_64 ==== | ||
+ | **DISCLAIMER: | ||
+ | |||
+ | |||
+ | To switch a machine from e1000 driver to virtio (and vice versa) follow these steps: | ||
+ | |||
+ | * edit /// | ||
+ | * disable kudzu on boot: //chkconfig kudzu off// | ||
+ | * restart the machine | ||
+ | |||
+ | After rebooting if your machine is configured to get address via dhcp, it will load the new module and get the ip automatically. | ||
+ | |||
+ | An alternative approach is this: | ||
+ | < | ||
+ | * edit /// | ||
+ | * remove the file /// | ||
+ | </ | ||
+ | |||
+ | ==== Appendix D: Migrating net driver from e1000 to virtio_net, using slc4x_x86_64 ==== | ||
+ | **DISCLAIMER: | ||
+ | |||
+ | To switch a machine from e1000 driver to virtio (and vice versa) follow these steps: | ||
+ | |||
+ | * edit /// | ||
+ | * disable kudzu on boot: //chkconfig kudzu off// | ||
+ | * remove the line starting with HWADDR under /// | ||
+ | * restart the machine | ||
+ | |||
+ | After rebooting if your machine is configured to get address via dhcp, it will load the new module and get the ip automatically. | ||
+ | |||
+ | |||
+ | ===== KVM Howto Legacy ===== | ||
+ | ===== Repository ===== | ||
+ | The suggested repository to get latest RPMs for kvm is: | ||
+ | |||
+ | | ||
+ | |||
+ | ===== Requirements ===== | ||
+ | The hypervisor must be a sl 5.x node. | ||
+ | |||
+ | ===== Installation ===== | ||
+ | To install a kvm capable machine the minimum required rpms are: | ||
+ | |||
+ | * kmod-kvm | ||
+ | * kvm | ||
+ | * etherboot-roms-kvm | ||
+ | * qemu-img | ||
+ | * vnc | ||
+ | |||
+ | |||
+ | |||
+ | To be able to properly configure a tunnel for a public IP address you also need: | ||
+ | |||
+ | * bridge-utils | ||
+ | * tunctl | ||
+ | |||
+ | Since the kvm module is external to the standard SL kernel, while installing the // | ||
+ | |||
+ | ===== Configuration ===== | ||
+ | To configure kvm you need to add a couple of scripts. | ||
+ | < | ||
+ | # | ||
+ | |||
+ | | ||
+ | / | ||
+ | / | ||
+ | </ | ||
+ | This has to be put in / | ||
+ | |||
+ | The second script is a modification of the standard init script contained in kvm rpm: | ||
+ | < | ||
+ | #!/bin/sh | ||
+ | # kvm_cnaf init script | ||
+ | # | ||
+ | # chkconfig: - 99 01 | ||
+ | # description: | ||
+ | # Currently it starts a bridge and attached eth0 for it | ||
+ | |||
+ | dir=$(dirname " | ||
+ | |||
+ | ifnum=${ifnum: | ||
+ | ifnum=${ifnum: | ||
+ | switch=${sw0: | ||
+ | pif=${pif: | ||
+ | antispoof=${antispoof: | ||
+ | command=$1 | ||
+ | |||
+ | if [ -f / | ||
+ | . / | ||
+ | fi | ||
+ | |||
+ | #check for bonding link aggregation | ||
+ | bond_int=$(awk < / | ||
+ | if [ ${bond_int}" | ||
+ | pif=${bond_int} | ||
+ | fi | ||
+ | |||
+ | if [ -f / | ||
+ | . / | ||
+ | fi | ||
+ | |||
+ | get_ip_info() { | ||
+ | addr=`ip addr show dev $1 | egrep '^ *inet' | sed -e 's/ *inet //' -e 's/ .*//'` | ||
+ | gateway=$(ip route list | awk '/ | ||
+ | broadcast=$(/ | ||
+ | } | ||
+ | |||
+ | |||
+ | #When a bonding device link goes down, its slave interfaces | ||
+ | #are getting detached so they should be re-added | ||
+ | bond_link_up () { | ||
+ | dev=$1 | ||
+ | is_bonding=$(echo ${dev} | awk '/ | ||
+ | if [ ${is_bonding}" | ||
+ | for slave in `awk < / | ||
+ | ifenslave $dev $slave | ||
+ | done | ||
+ | fi | ||
+ | } | ||
+ | |||
+ | |||
+ | do_ifup() { | ||
+ | if [ ${addr} ] ; then | ||
+ | ip addr flush $1 | ||
+ | bond_link_up $1 | ||
+ | ip addr add ${addr} broadcast ${broadcast} dev $1 | ||
+ | ip link set dev $1 up | ||
+ | fi | ||
+ | } | ||
+ | |||
+ | link_exists() | ||
+ | { | ||
+ | if ip link show " | ||
+ | then | ||
+ | return 0 | ||
+ | else | ||
+ | return 1 | ||
+ | fi | ||
+ | } | ||
+ | |||
+ | create_switch () { | ||
+ | local switch=$1 | ||
+ | |||
+ | if [ ! -e "/ | ||
+ | brctl addbr ${switch} >/ | ||
+ | brctl stp ${switch} off >/ | ||
+ | brctl setfd ${switch} 0.1 >/ | ||
+ | fi | ||
+ | ip link set ${switch} up >/ | ||
+ | } | ||
+ | |||
+ | |||
+ | add_to_switch () { | ||
+ | local switch=$1 | ||
+ | local dev=$2 | ||
+ | |||
+ | if [ ! -e "/ | ||
+ | brctl addif ${switch} ${dev} >/ | ||
+ | fi | ||
+ | |||
+ | ip link set ${dev} up >/ | ||
+ | } | ||
+ | |||
+ | #taken from Xen | ||
+ | transfer_routes () { | ||
+ | local src=$1 | ||
+ | local dst=$2 | ||
+ | # List all routes and grep the ones with $src in. | ||
+ | # Stick 'ip route del' on the front to delete. | ||
+ | # Change $src to $dst and use 'ip route add' to add. | ||
+ | ip route list | sed -ne " | ||
+ | /dev ${src}\( \|$\)/ { | ||
+ | h | ||
+ | s/^/ip route del / | ||
+ | P | ||
+ | g | ||
+ | s/ | ||
+ | s/^/ip route add / | ||
+ | P | ||
+ | d | ||
+ | }" | sh -e | ||
+ | } | ||
+ | |||
+ | |||
+ | change_ips() { | ||
+ | local src=$1 | ||
+ | local dst=$2 | ||
+ | |||
+ | #take care also for case we do not have / | ||
+ | if [ -x $BOOTPROTO ]; then | ||
+ | if [ -x $(pgrep dhclient) ];then | ||
+ | | ||
+ | else | ||
+ | BOOTPROTO=" | ||
+ | fi | ||
+ | fi | ||
+ | |||
+ | if [ $BOOTPROTO = " | ||
+ | ifdown ${src} >/ | ||
+ | ip link set ${src} up >/ | ||
+ | bond_link_up ${src} | ||
+ | pkill dhclient >/ | ||
+ | for ((i=0; | ||
+ | pgrep dhclient >/ | ||
+ | sleep 1 | ||
+ | done | ||
+ | dhclient ${dst} >/ | ||
+ | else | ||
+ | get_ip_info ${src} | ||
+ | ifconfig ${src} 0.0.0.0 | ||
+ | do_ifup ${dst} | ||
+ | transfer_routes ${src} ${dst} | ||
+ | ip route add default via ${gateway} dev ${dst} | ||
+ | fi | ||
+ | } | ||
+ | |||
+ | antispoofing () { | ||
+ | iptables -P FORWARD DROP >/ | ||
+ | iptables -F FORWARD >/ | ||
+ | iptables -A FORWARD -m physdev --physdev-in ${dev} -j ACCEPT >/ | ||
+ | } | ||
+ | |||
+ | status () { | ||
+ | local dev=$1 | ||
+ | local sw=$2 | ||
+ | |||
+ | echo ' | ||
+ | ip addr show ${dev} | ||
+ | ip addr show ${sw} | ||
+ | echo ' ' | ||
+ | brctl show ${sw} | ||
+ | echo ' ' | ||
+ | ip route list | ||
+ | echo ' ' | ||
+ | route -n | ||
+ | echo ' | ||
+ | gateway=$(ip route list | awk '/ | ||
+ | ping -c 1 ${gateway} || true | ||
+ | echo ' | ||
+ | } | ||
+ | |||
+ | start () { | ||
+ | if [ " | ||
+ | return | ||
+ | fi | ||
+ | |||
+ | create_switch ${switch} | ||
+ | add_to_switch ${switch} ${pif} | ||
+ | change_ips ${pif} ${switch} | ||
+ | |||
+ | if [ ${antispoof} = ' | ||
+ | antispoofing | ||
+ | fi | ||
+ | |||
+ | grep -q GenuineIntel / | ||
+ | grep -q AuthenticAMD / | ||
+ | } | ||
+ | |||
+ | stop () { | ||
+ | if [ " | ||
+ | return | ||
+ | fi | ||
+ | if ! link_exists " | ||
+ | return | ||
+ | fi | ||
+ | |||
+ | change_ips ${switch} ${pif} | ||
+ | ip link set ${switch} down | ||
+ | brctl delbr ${switch} | ||
+ | |||
+ | grep -q GenuineIntel / | ||
+ | grep -q AuthenticAMD / | ||
+ | / | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | case " | ||
+ | start) | ||
+ | echo -n $" | ||
+ | start | ||
+ | echo | ||
+ | ;; | ||
+ | |||
+ | stop) | ||
+ | echo -n $" | ||
+ | stop | ||
+ | echo | ||
+ | ;; | ||
+ | |||
+ | status) | ||
+ | status ${pif} ${switch} | ||
+ | ;; | ||
+ | |||
+ | *) | ||
+ | echo " | ||
+ | echo 'Valid commands are: start, stop, status' | ||
+ | exit 1 | ||
+ | esac | ||
+ | |||
+ | |||
+ | </ | ||
+ | ===== Usage ===== | ||
+ | Here are some useful commands to have a kvm machine started | ||
+ | |||
+ | ==== Disk image creation ==== | ||
+ | To create a sparse file to be used as a disk image: | ||
+ | |||
+ | qemu-img create -f qcow2 < | ||
+ | |||
+ | ==== Launching a machine ==== | ||
+ | To launch a machine: | ||
+ | |||
+ | qemu-kvm -hda=< | ||
+ | |||
+ | This command line specifies a machine with these options: | ||
+ | * < | ||
+ | * e1000 network driver (suggested!) | ||
+ | * mac address 00: | ||
+ | * 2048 MB ram | ||
+ | * vnc configured on port 0. The console can be reached with //vncviewer :0// | ||
+ | |||
+ | For other options, see the qemu-kvm manual. | ||
+ | |||
+ | ==== Virtio ==== | ||
+ | Para-virtualized drivers are available starting from SL5 kernel as a guest. **YOU can not use para-virtualized drivers on a sl 4 guest machine or below.** | ||
+ | To use these drivers the command line to use is something like: | ||
+ | |||
+ | qemu-kvm -drive file=wn-test-kvm_virtio_disk, |