Виртуализация KVM с помощью libvirt/virsh и Open vSwitch

В данной статье я хочу рассмотреть настройку и использование простой схемы аппаратной виртуализации KVM в Gentoo Linux (KVM + libvirt/virsh + Open vSwitch) на сервере с одним реальным IP адресом. Такая схема бывает полезна в случае необходимости создания виртуальных серверов, например, на уже работающем арендованном удаленном сервере.

Под простой схемой имеется в виду отсутствие резервирования, миграции, настроек виртуального свитча выше 1-го уровня, high available режима и т.д. Рассмотрены будет следующие вопросы:

  • минимально-необходимые настройки для работы системы
  • установка и базовая настройка програмного обеспечения
  • создание и базовое управление виртуальной машиной

Оглавление

Этап 1. Подготовка к установке

Для работы виртуализации KVM в соответствии с выбранной схемой нужно установить следующее программное обеспечение:

  • qemu
  • libvirt
  • openvswitch

Перечисленное ПО для своей работы требует со стороны ядра поддержки некоторых функций.

Необходимо включить в ядре поддержку KVM и выбрать правильный модуль в соотвествии с процессором (Intel или AMD, у меня выбран Intel):

[*] Virtualization --->
    --- Virtualization
    <*> Kernel-based Virtual Machine (KVM) support
    <*>   KVM for Intel processors support 
    < >   KVM for AMD processors support
    <*>   Host kernel accelerator for virtio net (EXPERIMENTAL)

Для работы виртуальной сети следует включить следующие параметры:

Device Drivers --->
    [*] Network device support --->
            <*> Universal TUN/TAP device driver support

Networking support --->
    Networking options --->
        <*>   The IPv6 protocol
        <*> 802.1d Ethernet Bridging
        <*> 802.1Q VLAN Support
        <*> Open vSwitch
        [*] QoS and/or fair queueing  --->
            <*>   Ingress Qdisc
            <*>   Universal 32bit comparisons w/ hashing (U32)
            [*]   Actions
            <*>     Traffic Policing

Для увеличения эффективности работы гипервизора с памятью нужно включить Kernel SamePage Merging:

Processor type and features --->
    [*] Enable KSM for page merging

Этап 2. Установка программного обеспечения

Для правильной работы программ необходимо в файл /etc/portage/make.conf добавить две переменные, содержащие архитектуры, которые будет поддерживать наш виртуальный хост:

QEMU_SOFTMMU_TARGETS="i386 x86_64"
QEMU_USER_TARGETS="i386 x86_64"

Так же, для поддержки некоторых полезных функций нужно включить ряд USE-флагов:

app-emulation/qemu -filecaps qemu-ifup png virtfs xattr
app-emulation/libvirt qemu udev

На момент написания статьи Open vSwitch в Gentoo доступен версии 1.9.0.

Установить все необходимые программы можно с помощью одной команды:

emerge openvswitch qemu libvirt

Этап 3. Настройка программного обеспечения

Настройка Open vSwitch

Cначала нужно создать базу данных, где будут храниться все рабочие параметры виртуального свитча, и запустить Open vSwitch:

ovsdb-tool create /etc/openvswitch/conf.db
/etc/init.d/ovs-controller start
/etc/init.d/ovsdb-server start
/etc/init.d/ovs-vswitchd start

Вторым шагом нужно создать интерфейс, через который виртуальный свитч будет доступен с физического хоста:

ovs-vsctl add-br vbr0
ovs-vsctl set-controller vbr0 ptcp:

Так как реальный IP адрес один, доступ к виртуальным серверам будет обеспечиваться с помощью маршрутизации трафика, добавлять физический сетевой интерфейс к мосту vbr0 не требуется. Так же, отсутствие физического сетевого интерфеса внутри моста vbr0 изолирует виртуальные серверы от внешней сети, что увеличивает безопасность. Для базовой работы виртуальных серверов этих настроек должно быть достаточно.

Чтобы после перезагрузки сервера виртуальный свитч не приходилось запускать вручную, необходимо добавить init-скрипты виртуального свитча в список автоматической загрузки:

rc-update add /etc/init.d/ovs-controller boot
rc-update add /etc/init.d/ovsdb-server boot
rc-update add /etc/init.d/ovs-vswitchd boot

Для работы выбранной схемы интерфейсу vbr0 необходимо назначить IP адрес из подсети, в которой будут работать виртуальные серверы, например 10.0.0.1/24. Автоматическое назначение ip адреса можно реализовать с помощью стандартного механизма Gentoo:

  1. Создать символическую ссылку net.vbr0
    ln -s /etc/init.d/net.lo /etc/init.d/net.vbr0
  2. Добавить параметры для интерфейса vbr0 в файл /etc/conf.d/net
    config_vbr0="10.0.0.1/24"
  3. Добавить интерфейс в список автоматической загрузки
    rc-update add net.vbr0 default

Настройка qemu

Параметры qemu, работающего под управлением libvirt, находятся в файле /etc/libvirt/qemu.conf. Я задал следующие параметры:

# IP адрес, на котором будут расположены порты VNC
vnc_listen="0.0.0.0"
# Отключение шифрования TLS для VNC
vnc_tls=0
# Имя пользователя и группа, от имени которых будет запускаться qemu
user="root"
group="root"
# Форматы дампов
save_image_format = "gzip"
dump_image_format = "gzip"

Запускать вручную qemu не требуется.

Настройка libvirt

Для рассматриваемой простой схемы никакие дополнительные настройки libvirt производить не нужно, достаточно просто запустить libvirt.

Запускается libvirt командой:

/etc/init.d/libvirtd start

Так же, стоит добавить libvirt в список автоматической загрузки:

rc-update add libvirtd default

Этап 4. Создание и управление виртуальным сервером

Создать виртуальный сервер в libvirt можно несколькими способами. В рамках этой статьи я покажу способ создания виртуального сервера с помощью файла-описания сервера в формате XML.

Для примера создадим сервер со следующими параметрами:

  • имя — servername
  • описание — Description of server
  • архитектура — x86_64
  • количество CPU — 1
  • объем RAM — 192MiB
  • тип образа HDD — qcow2
  • шина HDD — virtio
  • объем HDD — 20Gb
  • расположение образа HDD — /path/to/hdd.qcow2
  • виртуальный CDROM, расположение образа — /path/to/sdrom.iso
  • виртуальная сеть — openvswitch bridge (vbr0)
  • тип сетевого адаптера — virtio
  • порт удаленного доступа VNC — 5900

В результате получается следующий файл servername.xml:

<domain type='kvm' id='1'>
  <name>servername</name>
  <description>Description of server</description>
  <memory unit='KiB'>196608</memory>
  <vcpu placement='static'>1</vcpu>
  <os>
    <type arch='x86_64' machine='pc-1.3'>hvm</type>
    <boot dev='hd'/>
    <bootmenu enable='yes'/>
  </os>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' cache='writeback' io='threads'/>
      <source file='/path/to/hdd.qcow2'/>
      <target dev='vda' bus='virtio'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/path/to/cdrom.iso'/>
      <target dev='vdc' bus='virtio'/>
      <readonly/>
    </disk>
    <interface type='bridge'>
      <source bridge='vbr0'/>
      <virtualport type='openvswitch'>
      </virtualport>
      <model type='virtio'/>
    </interface>
    <graphics type='vnc' port='5900' autoport='no'>
      <listen type='address'/>
    </graphics>
  </devices>
</domain>

Пояснения к полученному файлу, я думаю, не требуются, так как все параметры легко воспринимаемы и понятны. Для более подробного изучения параметров следует обратиться к официальному описанию: http://libvirt.org/formatdomain.html

Образ жесткого диска необходимо создать вручную командой:

qemu-img create -f qcow2 /path/to/hdd.qcow2 20G

Полученный файл образа будет иметь размер около 190Kb, по мере наполнения размер будет увеличиваться.

Для ускорения работы виртуального сервера с образом жесткого диска в формате qcow2 нужно задать параметр preallocation=metadata при создании образа жесткого диска. Размер образа при этом будет равен заданному максимальному размеру (в нашем случае 20Gb), скорость работы увеличится в связи с отсутствием необходимости расширять файл.

qemu-img create -f qcow2 -o preallocation=metadata /path/to/hdd.qcow2 20G

Создать виртуальный сервер на основе полученного файла XML можно с помощью программы virsh, входящий в состав libvirt. Следующая команда создает виртуальный сервер:

virsh define /path/to/servername.xml

Созданный сервер можно увидеть, выполнив команду:

virsh list --all

Список параметров созданного сервера в формате XML можно получить командой:

virsh dumpxml servername

Сервер создан, настало время его запустить и подключиться к его консоли. Для запуска виртуального сервера нужно выполнить команду:

virsh start servername

Подключиться к консоли запущенного сервера можно с помощью любого клиента VNC, набрав в адресной строке клиента IP адрес или имя физического сервера, на котором настроена виртуализация, а так же указав порт, заданный в файле servername.xml. Разумеется, доступ к указанному порту должен быть разрешен.

Принудительно остановить работающий сервер можно командой:

virsh destroy servername

Этап 5. Настройка iptables

Чтобы виртуальные серверы могли получить доступ во внешнюю сеть, необходимо произвести дополнительные настройки — включить forward в файле sysctl.conf и добавить необходимые правила в iptables.

Forward включается путем добавления в файл /etc/sysctl.conf строки:

net.ipv4.ip_forward = 1

Чтобы изменения, внесенные в файл /etc/sysctl.conf заработали, нужно выполнить команду:

sysctl -p

В iptables следует разрешить входящий и исходящий трафик в цепочке FORWARD таблицы filter относительно подсети, в которой работают виртуальные серверы, а так же настроить SNAT в цепочке POSTROUTING таблицы nat (и DNAT при необходимости прямого доступа к виртуальным серверам).

FORWARD можно разрешить, например, такими правилами:

iptables -A FORWARD -s 10.0.0.0/24 -j ACCEPT
iptables -A FORWARD -d 10.0.0.0/24 -j ACCEPT

SNAT можно обеспечить следующим правилом:

iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j SNAT --to external-ip

где external-ip - IP адрес на сетевом интерфейсе физического сервера,
подключенном во внешнюю сеть

Сохранить добавленные правила можно командой:

/etc/init.d/iptables save

После внесения всех необходимых правил созданный виртуальный сервер получит доступ ко внешней сети (например, Internet).

На этом настройку простой схемы аппаратной виртуализации можно считать завершенной.

css.php