December 22, 2011

libvirt & Co. Облако "на коленке". Часть 1


Buzzword

Облако(cloud) это инфраструктура для управления виртуальными машинами. Агенты облака устанавливаются на железных серверах, превращая их единый мегасервер, которые используется для виртуализации. Облако должно уметь:

  • запускать группы виртуальных машин на базе загруженных в него образов
  • изменять образы виртуальных машин
  • управлять сетевой инфраструктурой - объединять виртуальные машины в ( возможно виртуальные ) локальные сети, настраивать правила доступа к этим сетям извне и доступ наружу из сетей
  • поддерживать остановку, приостановку и миграцию виртуалок
  • балансировать нагрузку на железные сервера
  • управлять местом на дисках
  • ..............

Предисловие

На сегодняшний день есть четыре основных облачных системы - перспективный и активно развиваемый openstack, рабочий но мало интересный из-за лицензии eucalyptus, совсем-совсем проприетарный VMware vCloud и очень-очень microsoft azure. Но это все "серьезные" облака, а как это часто бывает большие системы не удобно использовать на малых задачах. Я расскажу как управлять небольшими группами виртуальных машин "малой кровью". Впрочем openstack использует эти же утилиты, а все остальные узнают на чем основываются linux клауды.

Для описанных методик вам необходим Linux 2.6.26+ и процессор с поддержкой виртуализации. Проверить это можно следующими командами:

Hightlited/Raw
$ cat /proc/cpuinfo | egrep 'vmx|svm'
$ cat /proc/cpuinfo | egrep 'rvi|ept'

Если первая команда ничего не вывела - вам не повезло, аппаратной поддержки виртуализации у вас нет. Если обе команды выдали не пустой ответ - вам повезло вдвойне - в вашем процессоре есть поддержка виртуализации таблицы страниц - это значительно ускоряет работу с памятью, фактически выводя ее на уровень сырого железа.

Вложенная аппаратная виртуализация не поддерживается, т.е. если linux установлен в виртуальной машине, то описанные примеры работать не будут. Впрочем и те, кто запускает линукс в виртуалке и те, у кого нет поддержки виртуализации могут адаптировать эти примеры для использования xen c паравиртуализацией или lxc - эти техники не требуют аппаратной поддержки. В принципе ипользуемая libvirt имеет зачаточную поддержку windows, желающие могут попробовать и так.

Из других аппаратных требований желательно по-больше оперативной памяти (3Gb+) и быстрый диск (SSD). На магнитном жестком диске все будет работать, но некоторые наиболее интересные варианты организации виртульных образов заметно тормозят на дисковых операциях из-за большого количества разрозненных обращений.

Все примеры для Ubuntu 11.10, для других дистрибутивов нужно подправить обращения к пакетному менеджеру и пути к конфигам.


libvirt

Хотя формально libvirt называется библиотекой, но это целая инфраструктура для управления виртуальными машинами. Она включает:

  • libvirt-bin демон с внешним API, управляющий виртуальными машинами
  • libvirt - библиотека для доступа к демону
  • masqdns - dns/dhcp сервер, используемый совместно с iptables, vlan и бриджами для управлением виртуальными сетями
  • virsh - клиент командной строки

libvirt предоставляет почти унифицированный интерфейс для работы с различными гипервизорами - поддерживаются kvm, lxc, xen, vmware, hyper-v, openvz, и другие - в общем почти все, что еще шевелится. При этом libvirt не пытается подобрать общий знаменатель ко всем системам виртуализации, а предоставляет полный набор возможностей каждого гипервизора - просто не все конфигурации будут работать на всех системах виртуализаций.

Для описания виртуальных машин, сетей и хранилищ libvirt использует xml, строки с которым выступают параметрами во всех основных функциях. Модель кажется сначала странной, но после ближайшего рассмотрения понимаешь, что это очень яркий пример удачного использования dependency injection. В 99% случаев программам которые используют libvirt все равно какая структура каждой конкретной виртуальной машины. А при использовании внешних xml файлов их можно править не трогая код, при этом исходная программа будет(почти) однообразно работать на всех поддерживаемых гипервизорах и с самыми разными виртуальными машинами.

Итак начнем с самого простого - с запуска vm. Примеры кода будут на python, но все эти действия можно выполнить из командной строки с помощью virsh. В качестве гипервизора будем использовать kvm. Он по умолчанию доступен в современных Linux системах.

Ставим необходимые пакеты:

Hightlited/Raw
# apt-get install kvm qemu qemu-kvm qemu-common libvirt-bin libvirt0 python-libvirt
# modprobe kvm
# mkdprobe kvm-intel # kvm-amd

Выключаем apparmor/selinux. Желающие могут его настроить, но по умолчанию они настроены криво:

Hightlited/Raw
# service apparmor teardown
# service libvirt-bin stop
# service libvirt-bin start

Выкачиваем образ debian_vm и делаем конфигурационный файл для нее:

Show

Файл для запуска vm:

Hightlited/Raw
# tiny_cloud.py
import sys
import libvirt

# соединяемся с libvirtd
uri = 'qemu://system'
conn = libvirt.open(uri)

vm_xml_templ = open(sys.argv[1]).read()

vm_xml = vm_xml_templ.format(vcpu=1, 
                       mem=1024 * 1024, # 1Gb
                       name=sys.argv[2],
                       mac="00:44:01:61:78:01",
                       image_file=sys.argv[3]
                       )

# запускаем vm
conn.createXML(vm_xml, 0)

Запускаем:

Hightlited/Raw
# python tiny_cloud.py vm_templ.xml debian path_to_image

Проверяем, что виртуалка запущенна:

Hightlited/Raw
# virsh list    

 Id Name                 State
----------------------------------
  1 debian                 running

В принципе libvirt с помощью virsh позволяет регистрировать/запускать/останавливать виртуальные машины и без использования python, но для более сложных задач bash не самый лучший язык программирования.

Виртуальные машины запущенные под управлением kvm являются обычными linux процессами, так что ими можно управлять в том числе с помощью стандартных средств - ps, kill, nice, ionice, etc. Это так-же означает что работают все стандартные системы мониторинга (htop/atop/iotop/sar) и другое, а

Hightlited/Raw
   # ps aux | grep kvm

   покажет командную строку, с помощью которой можно запустить vm не используя
libvirt.

Продолжим с tiny_cloud.py - добавим останов виртуалки, разбор командной строки, etc.

Show

Для подключения к полученным виртуалкам можно использовать ssh или vnc viewer. Для виртуалок, поднятых с помощью libvirt есть удобный virt-manager, который показывает все запущенные домены и позволяет подключится по vnc, что необходимо если сеть не загрузилась или на образе не было ssh сервера.





Первая проблема после запуска виртуалки - програмно определять ip, который она получила. Для этого желательно разобраться с сетевой моделью libvirt и вообще с основными сетевыми средствами linux, чему и будет посвящена следующая статья.

Ссылки:
          people.debian.org/~aurel32/qemu/amd64/debian_squeeze_amd64_standard.qcow2
          ru.wikipedia.org/wiki/%D0%9E%D0%B1%D0%BB%D0%B0%D1%87%D0%BD%D1%8B%D0%B5_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F
          openstack.org
          www.eucalyptus.com
          www.vmware.com/solutions/cloud-computing/index.html
          en.wikipedia.org/wiki/Azure_Services_Platform
          en.wikipedia.org/wiki/Kernel-based_Virtual_Machine
          xen.org
          lxc.sourceforge.net
          wiki.openvz.org/Main_Page
          libvirt.org
          en.wikipedia.org/wiki/Dependency_injection
          virt-manager.org

Исходники этого и других постов со скриптами лежат тут - github.com/koder-ua. При использовании их, пожалуйста, ссылайтесь на koder-ua.blogspot.com.

11 comments:

e0ne said...

Интересный и актуальный пост. Как раз столкнулся с проблемами с libvirt.

Вот только линк на debian_vm -не валидный

koder said...

Точно, криво скомпилилось, поправил. Спасибо

koder said...

Пинают по поводу лишних элементов в xml конфиге для vm :) всем спасибо - доберусь до кода - поправлю

e0ne said...
This comment has been removed by the author.
e0ne said...

Неожиданно:
команда "$ cat /proc/cpuinfo | egrep 'vmx|svm'" ничего не вывела :(.
ubuntu 11.10, cpu - intel core i7

konstantin danilov said...

Оч странно.

$ cat /proc/cpuinfo | egrep 'vmx|svm'
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 popcnt aes lahf_lm ida arat dts tpr_shadow vnmi flexpriority ept vpid
.............

это на core i5. Какая версия i7? Есть без поддержки виртуализации. Может система запущенна в виртуалке?

e0ne said...

к последнему комментарию: это был прикол мат.платы от asus - она, почему-то, не хотела включать аппаратную виртуализацию, но после нескольких попыток - заработало

Anonymous said...

Свое облако на libvirt и kvm можно построить с помощью сервиса http://webvirtmgr.net - все очень просто и удобно.

WebVirtMgr.net said...

В комментариях упоминали наш сервис WebVirtMgr.net, мы рекомендуем присмотреться к нему повнимателнее.

Cервис позволяет легко и понятным образом настраивать виртуальные машины если они работают под KVM и управляются libvirt-ом. На данный момент сервис позиционируется как бесплатный инструмент управления и один из возможных способов организации работы с виртуальными машинами. Например нашим сервисом удобно пользоваться для первичной настройки, в дальнейшем управление может выполнятся другими интсрументами управления на свой вкус, например тем способом который описан в этой статье.

Anonymous said...

После выполнения скрипта команда virsh list выводит пустой список. Скрипт отрабатывает без исключений и ошибок.

где может быть прокол?

konstantin danilov said...

Сложно сказать, а ps aux показывает виртуалку?