Product SiteDocumentation Site

12.2. Виртуализация

Виртуализация — это одно из крупнейших достижений вычислительной техники последних лет. Этот термин включает в себя различные абстракции и технологии имитации виртуальных компьютеров с разной степенью независимости от реального оборудования. На одном физическом сервере могут размещаться несколько систем, работающих одновременно и изолированных друг от друга. Приложений много, и зачастую они были бы невозможны без такой изоляции: к примеру, тестовые окружения с различными конфигурациями или разделение сервисов по разным виртуальным машинам для безопасности.
Существует множество решений для виртуализации, каждое со своими достоинствами и недостатками. Эта книга сфокусируется на Xen, LXC и KVM, но есть и другие реализации, достойные упоминания:

12.2.1. Xen

Xen — это решение для «паравиртуализации». Оно вводит тонкий слой абстракции, называемый «гипервизором», между оборудованием и вышележащими системами; он играет роль арбитра, контролирующего доступ к оборудованию из виртуальных машин. Однако он обрабатывает лишь немногие инструкции, остальные напрямую выполняются оборудованием от имени систем. Главное преимущество заключается в том, что производительность не страдает, и системы работают со скоростью, близкой к нативной; минусом является то, что ядра операционных систем, которые нужно запускать на гипервизоре Xen, должны быть адаптированы для этого.
Уделим немного времени терминологии. Гипервизор является нижним слоем, выполняющимся непосредственно на оборудовании, даже ниже ядра. Гипервизор может разделять остальное программное обеспечение по нескольким доменам, которые могут выглядеть как множество виртуальных машин. Один из этих доменов (первый, который запускается) известен как dom0 и имеет особую роль, поскольку только этот домен может управлять гипервизором и исполнением других доменов. Эти другие домены известны как domU. Другими словами, с точки зрения пользователя dom0 соответствует «хосту» в других системах виртуализации, а domU — «гостю».
Чтобы использовать Xen в Debian, нужны три компонента:
  • Сам гипервизор. В соответствии с доступным оборудованием пакет будет называться xen-hypervisor-4.4-amd64, xen-hypervisor-4.4-armhf или xen-hypervisor-4.4-arm64.
  • Ядро, работающее на этом гипервизоре. Любое ядро, новее 3.0, включая версию 3.16 из состава Jessie.
  • Для архитектуры i386 также требуется стандартная библиотека с заплатами, использующими Xen; она находится в пакете libc6-xen.
Чтобы избежать мороки с выбором этих компонентов вручную, для удобства создано несколько пакетов (таких как xen-linux-system-amd64); они тянут за собой заведомо работоспособный набор соответствующих пакетов гипервизора и ядра. С гипервизором также поставляется пакет xen-utils-4.4, содержащий инструменты для управления гипервизором из dom0. Он в свою очередь зависит от соответствующей стандартной библиотеки. Во время установки всего этого конфигурационные сценарии также создают новую запись в меню загрузчика Grub, чтобы запустить выбранное ядро в Xen dom0. Заметьте однако, что эта запись обычно устанавливается не первой в списке, и поэтому не выбирается по умолчанию. Если это не то поведение, которого вы хотели, следующие команды изменят его:
# mv /etc/grub.d/20_linux_xen /etc/grub.d/09_linux_xen
# update-grub
Когда всё необходимое установлено, следующим шагом будет тестирование поведения самого dom0; оно включает перезагрузку в гипервизор и ядро Xen. Система должна загрузиться обычным образом, с несколькими дополнительными сообщениями в консоли на ранних стадиях инициализации.
Теперь время собственно установить подходящие системы в domU с помощью инструментов из xen-tools. Этот пакет предоставляет команду xen-create-image, которая в значительной мере автоматизирует задачу. Единственный обязательный параметр — --hostname, передающий имя domU; другие опции важны, но они могут быть сохранены в конфигурационном файле /etc/xen-tools/xen-tools.conf, и их отсутствие в командной строке не вызовет ошибки. Поэтому следует проверить содержимое этого файла перед созданием образов, или же использовать дополнительные параметры в вызове xen-create-image. Отметим следующие важные параметры:
  • --memory для указания количества ОЗУ, выделенного вновь создаваемой системе;
  • --size и --swap, чтобы задать размер «виртуальных дисков», доступных для domU;
  • --debootstrap, чтобы новая система устанавливалась с помощью debootstrap; в этом случае также чаще всего используется опция --dist (с указанием имени дистрибутива, например jessie).
  • --dhcp объявляет, что конфигурация сети domU должна быть получена по DHCP, в то время как --ip позволяет задать статический IP-адрес.
  • Наконец, следует выбрать метод хранения для создаваемых образов (тех, которые будут видны как жёсткие диски из domU). Самый простой метод, соответствующий опции --dir, заключается в создании одного файла на dom0 для каждого устройства, которое будет передано domU. Для систем, использующих LVM, альтернативой является использование опции --lvm, за которой указывается имя группы томов; в таком случае xen-create-image создаст новый логический том в этой группе, и этот логический том станет доступным для domU как жёсткий диск.
Когда выборы сделаны, мы можем создать образ для нашего будущего Xen domU:
# xen-create-image --hostname testxen --dhcp --dir /srv/testxen --size=2G --dist=jessie --role=udev

[...]
General Information
--------------------
Hostname       :  testxen
Distribution   :  jessie
Mirror         :  http://ftp.debian.org/debian/
Partitions     :  swap            128Mb (swap)
                  /               2G    (ext3)
Image type     :  sparse
Memory size    :  128Mb
Kernel path    :  /boot/vmlinuz-3.16.0-4-amd64
Initrd path    :  /boot/initrd.img-3.16.0-4-amd64
[...]
Logfile produced at:
         /var/log/xen-tools/testxen.log

Installation Summary
---------------------
Hostname        :  testxen
Distribution    :  jessie
MAC Address     :  00:16:3E:8E:67:5C
IP-Address(es)  :  dynamic
RSA Fingerprint :  0a:6e:71:98:95:46:64:ec:80:37:63:18:73:04:dd:2b
Root Password   :  adaX2jyRHNuWm8BDJS7PcEJ
Теперь у нас есть виртуальная машина, но она ещё не запущена (и поэтому только занимает место на жёстком диске dom0). Разумеется, мы можем создать больше образов, возможно с разными параметрами.
До включения этих виртуальных машин нам нужно определить, как будет получаться доступ к ним. Разумеется, они могут быть назначены изолированными машинами, доступными только через системную консоль, но это редко соответствует сценарию работы. Большую часть времени domU будет считаться удалённым сервером, и доступ к нему будет осуществляться только через сеть. Однако было бы весьма неудобным добавлять сетевую карту для каждого domU; по этой причине Xen позволяет создавать виртуальные интерфейсы, которые каждый домен может видеть и использовать обычным образом. Заметьте, что эти карты, хоть они и виртуальные, будут полезными только когда они подключены к сети, хотя бы виртуальной. У Xen есть несколько сетевых моделей для этого:
  • Простейшей является модель моста; все сетевые карты eth0 (как в dom0, так и в domU-системах) ведут себя, как если бы они были напрямую подключены к Ethernet-коммутатору.
  • Следующая модель — маршрутизируемая, когда dom0 ведёт себя как маршрутизатор, находящийся между domU-системами и (физической) внешней сетью.
  • Наконец, в модели NAT dom0 опять находится между domU-системами и остальной сетью, но domU-системы не доступны извне напрямую, и трафик проходит через преобразование адресов на dom0.
Эти три сетевых режима включают различные интерфейсы с необычными именами, такими как vif*, veth*, peth* и xenbr0. Гипервизор Xen комбинирует их в соответствии с заданной схемой под контролем инструментов пространства пользователя. Поскольку NAT и маршрутизируемая модель приспособлены лишь для отдельных случаев, мы рассмотрим только модель моста.
Стандартная конфигурация пакетов Xen не меняет общесистемных сетевых настроек. Однако демон xend настроен на подключение виртуальных сетевых интерфейсов к любому уже существующему сетевому мосту (при наличии нескольких таких мостов предпочтение отдаётся xenbr0). Поэтому нам надо настроить мост в /etc/network/interfaces (для этого требуется установить пакет bridge-utils, поэтому он рекомендуется пакетом xen-utils-4.4), заменив существующую запись eth0:
auto xenbr0
iface xenbr0 inet dhcp
    bridge_ports eth0
    bridge_maxwait 0
Перезагрузившись для проверки, что мост создаётся автоматически, мы можем запустить domU с помощью инструментов управления Xen, а именно команды xl. Эта команда позволяет производить различные манипуляции с доменами, в частности выводить их список, запускать их и останавливать.
# xl list
Name                                        ID   Mem VCPUs      State   Time(s)
Domain-0                                     0   463     1     r-----      9.8
# xl create /etc/xen/testxen.cfg
Parsing config from /etc/xen/testxen.cfg
# xl list
Name                                        ID   Mem VCPUs      State   Time(s)
Domain-0                                     0   366     1     r-----     11.4
testxen                                      1   128     1     -b----      1.1
Заметьте, что domU testxen использует реальную память, взятую из ОЗУ, которая иначе была бы доступна dom0, а не виртуальную. Поэтому при сборке сервера для размещения машин Xen следует побеспокоиться об обеспечении достаточного объёма физического ОЗУ.
Voilà! Наша виртуальная машина запускается. Мы можем получить доступ к ней в одном из двух режимов. Обычный путь — подключаться к ней «удалённо» через сеть, как мы подключались бы к реальной машине; для этого обычно требуется настройка либо DHCP-сервера, либо DNS. Другой путь, который может стать единственно возможным в случае неправильной настройки сети, — использование консоли hvc0 с помощью команды xl console:
# xl console testxen
[...]

Debian GNU/Linux 8 testxen hvc0

testxen login: 
После этого можно начать сессию, как если бы вы сидели за клавиатурой виртуальной машины. Для отключения от этой консоли служит сочетание клавиш Control+].
Когда domU запущен, он может использоваться как любой другой сервер (ведь это, помимо прочего, система GNU/Linux). Однако благодаря тому, что это виртуальная машина, доступны и некоторые дополнительные возможности. К примеру, domU может быть временно приостановлен, а затем вновь запущен с помощью команд xl pause и xl unpause. Заметьте, что хотя приостановленный domU не использует ресурсы процессора, выделенная ему память по-прежнему занята. Может иметь смысл использовать команды xl save и xl restore: сохранение domU освобождает ресурсы, которые ранее использовались этим domU, в том числе и ОЗУ. После восстановления (или снятия с паузы) domU не замечает ничего кроме того, что прошло некоторое время. Если domU был запущен, когда dom0 выключается, сценарии из пакетов автоматически сохраняют domU и восстанавливают его при следующей загрузке. Отсюда, конечно, проистекает обычное неудобство, проявляющееся, например, при переводе ноутбука в спящий режим; в частности, если domU приостановлен слишком надолго, сетевые подключения могут завершиться. Заметьте также, что Xen на данный момент несовместим с большей частью системы управления питанием ACPI, что мешает приостановке dom0-системы.
Выключение или перезагрузка domU могут быть выполнены как изнутри domU (с помощью команды shutdown), так и из dom0, с помощью xl shutdown или xl reboot.

12.2.2. LXC

Хотя она и используется для создания «виртуальных машин», LXC является, строго говоря, не системой виртуализации, а системой для изоляции групп процессов друг от друга, даже если они все выполняются на одном узле. Она использует набор недавних изменений в ядре Linux, известных под общим названием control groups, благодаря которому разные наборы процессов, называемые «группами», имеют разные представления о некоторых аспектах системы. Наиболее примечательные из этих аспектов — идентификаторы процессов, конфигурация сети и точки монтирования. Такая группа изолированных процессов не будет иметь доступа к другим процессам в системе, и её доступ к файловой системе может быть ограничен определённым подмножеством. У неё также могут быть свои собственные сетевой интерфейс и таблица маршрутизации, и она может быть настроена так, чтобы видеть только подмножество устройств, присутствующих в системе.
С помощью комбинации этих возможностей можно изолировать целое семейство процессов начиная с процесса init, и получившийся набор будет выглядеть чрезвычайно похоже на виртуальную машину. Официальное название для такой схемы «контейнер» (отсюда и неофициальное название LXC: LinuX Containers), но весьма значительным отличием от «настоящих» виртуальных машин, таких как предоставляемые Xen или KVM, заключается в отсутствии второго ядра; контейнер использует то же самое ядро, что и хост-система. У этого есть как преимущества, так и недостатки: к преимуществам относится великолепная производительность благодаря полному отсутствию накладных расходов, а также тот факт, что ядро видит все процессы в системе, поэтому планировщик может работать более эффективно, чем если бы два независимых ядра занимались планированием выполнения разных наборов задач. Основное из неудобств — невозможность запустить другое ядро в контейнере (как другую версию Linux, так и другую операционную систему).
Поскольку мы имеем дело с изоляцией, а не обычной виртуализацией, настройка контейнеров LXC более сложна, чем простой запуск debian-installer на виртуальной машине. Мы опишем некоторые предварительные требования, затем перейдём к конфигурации сети; после этого мы сможем собственно создать систему для запуска в контейнере.

12.2.2.1. Предварительные шаги

Пакет lxc содержит инструменты, необходимые для запуска LXC, поэтому его необходимо установить.
LXC также требует систему конфигурации control groups, представляющую собой виртуальную файловую систему, которая должна быть смонтирована в /sys/fs/cgroup. Так как Debian 8 перешел на systemd, который также зависит от control groups, это делается автоматически во время загрузки без дополнительной настройки.

12.2.2.2. Сетевые настройки

Цель установки LXC — в запуске виртуальных машин; хотя мы, разумеется, можем держать их изолированными от сети и взаимодействовать с ними только через файловую систему, для большинства задач требуется хотя бы минимальный сетевой доступ к контейнерам. В типичном случае каждый контейнер получит виртуальный сетевой интерфейс присоединённый к реальной сети через мост. Этот виртуальный интерфейс может быть подключён либо напрямую к физическому сетевому интерфейсу хост-системы (в таком случае контейнер непосредственно в сети), либо к другому виртуальному интерфейсу, определённому в хост-системе (тогда хост сможет фильтровать или маршрутизировать трафик). В обоих случаях потребуется пакет bridge-utils.
В простейшем случае это всего лишь вопрос правки /etc/network/interfaces, переноса конфигурации физического интерфейса (например eth0) на интерфейс моста (обычно br0) и настройки связи между ними. Например, если конфигурационный файл сетевых интерфейсов изначально содержит записи вроде таких:
auto eth0
iface eth0 inet dhcp
Их следует отключить и заменить на следующие:
#auto eth0
#iface eth0 inet dhcp

auto br0
iface br0 inet dhcp
  bridge-ports eth0
Результат такой настройки будет похож на тот, какой мы получили бы, если бы контейнеры были машинами, подключёнными к той же физической сети, что и хост-машина. Конфигурация «мост» управляет прохождением кадров Ethernet между всеми связанными интерфейсами, включая и физический eth0, и интерфейсы, заданные для контейнеров.
В случаях, когда такую конфигурацию использовать невозможно (например если контейнерам нельзя выделить публичные IP-адреса), будет создан и подключён к мосту виртуальный tap-интерфейс. Это будет эквивалентно сетевой топологии, при которой вторая сетевая карта подключена к отдельному коммутатору, и к нему же подключены контейнеры. Хост тогда должен выступать как шлюз для контейнеров, если им требуется соединяться с остальным миром.
В дополнение к bridge-utils для «продвинутой» конфигурации потребуется пакет vde2; файл /etc/network/interfaces тогда примет следующий вид:
# Интерфейс eth0 без изменений
auto eth0
iface eth0 inet dhcp

# Виртуальный интерфейс
auto tap0
iface tap0 inet manual
  vde2-switch -t tap0

# Мост для контейнеров
auto br0
iface br0 inet static
  bridge-ports tap0
  address 10.0.0.1
  netmask 255.255.255.0
Сеть может быть настроена как статически в контейнерах, так и динамически и помощью DHCP-сервера, запущенного на хост-системе. Такой DHCP-сервер должен быть сконфигурирован для ответа на запросы на интерфейсе br0.

12.2.2.3. Установка системы

Давайте теперь настроим файловую систему для использования контейнером. Поскольку эта «виртуальная машина» не будет запускаться непосредственно на оборудовании, потребуются некоторые дополнительные манипуляции по сравнению с обычной файловой системой, особенно когда дело касается ядра, устройств и консолей. К счастью, пакет lxc включает сценарии, которые в значительной степени автоматизируют эту настройку. В частности, следующие команды (для которых требуются пакеты debootstrap и rsync) установят контейнер с Debian:
root@mirwiz:~# lxc-create -n testlxc -t debian
debootstrap is /usr/sbin/debootstrap
Checking cache download in /var/cache/lxc/debian/rootfs-jessie-amd64 ... 
Downloading debian minimal ...
I: Retrieving Release 
I: Retrieving Release.gpg 
[...]
Download complete.
Copying rootfs to /var/lib/lxc/testlxc/rootfs...
[...]
Root password is 'sSiKhMzI', please change !
root@mirwiz:~# 
Заметьте, что файловая система изначально создана в /var/cache/lxc, а затем перемещена в каталог назначения. Это позволяет создавать идентичные контейнеры намного быстрее, поскольку требуется лишь скопировать их.
Заметьте, что сценарий создания шаблона debian принимает опцию --arch с указанием архитектуры системы для установки и опцию --release, если вы вы хотите установить что-то отличное от текущего стабильного релиза Debian. Вы можете также установить переменную окружения MIRROR, чтобы указать на локальное зеркало Debian.
Только что созданная файловая система теперь содержит минимальную систему Debian, и по умолчанию у контейнера нет сетевого интерфейса (за исключением loopback). Поскольку это не то, чего мы хотели, мы отредактируем конфигурационный файл контейнера (/var/lib/lxc/testlxc/config) и добавим несколько записей lxc.network.*:
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.hwaddr = 4a:49:43:49:79:20
Эти записи означают, соответственно, что в контейнере будет создан виртуальный интерфейс, что он будет автоматически подниматься при запуске этого контейнера, что он будет автоматически соединяться с мостом br0 на хост-системе и что его MAC-адрес будет соответствовать указанному. Если бы эта последняя запись отсутствовала или была отключена, генерировался бы случайный MAC-адрес.
Другая полезная запись в этом файле — имя узла:
lxc.utsname = testlxc

12.2.2.4. Запуск контейнера

Теперь, когда наша виртуальная машина готова, давайте запустим контейнер:
root@mirwiz:~# lxc-start --daemon --name=testlxc
root@mirwiz:~# lxc-console -n testlxc
Debian GNU/Linux 8 testlxc tty1

testlxc login: root
Password: 
Linux testlxc 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1 (2015-05-24) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@testlxc:~# ps auxwf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2  28164  4432 ?        Ss   17:33   0:00 /sbin/init
root        20  0.0  0.1  32960  3160 ?        Ss   17:33   0:00 /lib/systemd/systemd-journald
root        82  0.0  0.3  55164  5456 ?        Ss   17:34   0:00 /usr/sbin/sshd -D
root        87  0.0  0.1  12656  1924 tty2     Ss+  17:34   0:00 /sbin/agetty --noclear tty2 linux
root        88  0.0  0.1  12656  1764 tty3     Ss+  17:34   0:00 /sbin/agetty --noclear tty3 linux
root        89  0.0  0.1  12656  1908 tty4     Ss+  17:34   0:00 /sbin/agetty --noclear tty4 linux
root        90  0.0  0.1  63300  2944 tty1     Ss   17:34   0:00 /bin/login --     
root       117  0.0  0.2  21828  3668 tty1     S    17:35   0:00  \_ -bash
root       268  0.0  0.1  19088  2572 tty1     R+   17:39   0:00      \_ ps auxfw
root        91  0.0  0.1  14228  2356 console  Ss+  17:34   0:00 /sbin/agetty --noclear --keep-baud console 115200 38400 9600 vt102
root       197  0.0  0.4  25384  7640 ?        Ss   17:38   0:00 dhclient -v -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.e
root       266  0.0  0.1  12656  1840 ?        Ss   17:39   0:00 /sbin/agetty --noclear tty5 linux
root       267  0.0  0.1  12656  1928 ?        Ss   17:39   0:00 /sbin/agetty --noclear tty6 linux
root@testlxc:~# 
Теперь мы в контейнере; наш доступ к процессам ограничен только теми, которые запущены изнутри самого контейнера, и наш доступ к файловой системе также ограничен до выделенного подмножества полной файловой системы (/var/lib/lxc/testlxc/rootfs). Мы можем выйти из консоли с помощью Control+a q.
Заметьте, что мы запустили контейнер как фоновый процесс благодаря опции --daemon команды lxc-start. Контейнер можно прервать впоследствии с помощью такой команды как lxc-stop --name=testlxc.
Пакет lxcсодержит сценарий инициализации, который может автоматически запускать один или несколько контейнеров при загрузке хост-системы (он использует lxc-autostart, запускающую контейнеры, параметр lxc.start.auto которых установлен в значение 1). Более тонкий контроль порядка запуска возможен с помощью lxc.start.order и lxc.group: по умолчанию сценарий инициализации сначала запускает контейнеры, входящие в группу onboot, а затем — контейнеры, не входящие ни в какие группы. В обоих случаях порядок внутри группы определяется параметром lxc.start.order.

12.2.3. Виртуализация с помощью KVM

KVM, что расшифровывается как Kernel-based Virtual Machine, является первым и главным модулем ядра, предоставляющим большую часть инфраструктуры, которая может использоваться виртуализатором, но не является самим виртуализатором. Собственно контроль за виртуализацией осуществляется приложением, основанным на QEMU. Не переживайте, если в этом разделе будут упоминаться команды qemu-*: речь всё равно о KVM.
В отличие от других систем виртуализации, KVM был влит в ядро Linux с самого начала. Его разработчики выбрали использование наборов инструкций процессора, выделенных для виртуализации (Intel-VT и AMD-V), благодаря чему KVM получился легковесным, элегантным и не прожорливым до ресурсов. Обратной стороной медали является, естественно, то, что KVM работает не на любом компьютере, а только на таком, в котором установлен подобающий процессор. Для x86-машин можно убедиться, такой ли у вас процессор, проверив наличие флага «vmx» или «svm» в файле /proc/cpuinfo.
Поскольку его разработка активно поддерживается Red Hat, KVM стал в той или иной степени эталоном виртуализации в Linux.

12.2.3.1. Предварительные шаги

В отличие от таких инструментов, как VirtualBox, сам по себе KVM не включает никакого пользовательского интерфейса для создания виртуальных машин и управления ими. Пакет qemu-kvm предоставляет лишь исполняемый файл, способный запустить виртуальную машину, а также инициализационный скрипт, загружающий соответствующие модули ядра.
К счастью, Red Hat также предоставляет набор инструментов для решения этой проблемы, разрабатывая библиотеку libvirt и связанные с ней инструменты менеджера виртуальных машин. libvirt позволяет управлять виртуальными машинами унифицированным образом, независимо от стоящей за ней системой виртуализации (на данный момент она поддерживает QEMU, KVM, Xen, LXC, OpenVZ, VirtualBox, VMWare и UML). virtual-manager — это графический интерфейс, который использует libvirt для создания виртуальных машин и управления ими.
Первым делом мы установим необходимые пакеты с помощью команды apt-get install qemu-kvm libvirt-bin virtinst virt-manager virt-viewer. libvirt-bin предоставляет демон libvirtd, позволяющий (возможно удалённо) управлять виртуальными машинами, запущенными на хосте, и запускает необходимые виртуальные машины при загрузке хоста. Кроме того, этот пакет предоставляет утилиту virsh с интерфейсом командной строки, которая позволяет контролировать виртуальные машины, управляемые libvirt.
Пакет virtinst предоставляет virt-install, которая позволяет создавать виртуальные машины из командной строки. Наконец, virt-viewer позволяет получать доступ к графической консоли виртуальной машины.

12.2.3.2. Сетевые настройки

Как и в случаях Xen и LXC, наиболее распространённая сетевая конфигурация включает мост, группирующий сетевые интерфейсы виртуальных машин (см. Раздел 12.2.2.2, «Сетевые настройки»).
В качестве альтернативы, в конфигурации KVM по умолчанию, виртуальной машине выдаётся адрес из частного диапазона (192.168.122.0/24), и NAT настраивается таким образом, чтобы виртуальная машина могла получить доступ во внешнюю сеть.
Ниже в этом разделе считается, что на хост-системе имеются физический интерфейс eth0 и мост br0, и что первый присоединён к последнему.

12.2.3.3. Установка с помощью virt-install

Создание виртуальной машины очень похоже на установку обычной системы с той разницей, что характеристики виртуальной машины описываются в командной строке, кажущейся бесконечной.
С практической точки зрения это значит, что мы будем использовать установщик Debian, загружая виртуальную машину с виртуального привода DVD-ROM, соответствующего образу DVD Debian, хранящемуся на хост-системе. Виртуальная машина экспортирует свой графический интерфейс по протоколу VNC (см. подробности в Раздел 9.2.2, «Использование удалённых графических рабочих столов»), что позволит нам контролировать процесс установки.
Для начала потребуется сказать libvirtd, где хранить образы дисков, если только нас не устраивает расположение по умолчанию (/var/lib/libvirt/images/).
root@mirwiz:~# mkdir /srv/kvm
root@mirwiz:~# virsh pool-create-as srv-kvm dir --target /srv/kvm
Pool srv-kvm created

root@mirwiz:~# 
Давайте запустим процесс установки на виртуальной машине и поближе взглянем на наиболее важные опции virt-install. Эта команда регистрирует виртуальную машину и её параметры в libvirtd, а затем запускает её, чтобы приступить к установке.
# virt-install --connect qemu:///system  1
               --virt-type kvm           2
               --name testkvm            3
               --ram 1024                4
               --disk /srv/kvm/testkvm.qcow,format=qcow2,size=10 5
               --cdrom /srv/isos/debian-8.1.0-amd64-netinst.iso  6
               --network bridge=br0      7
               --vnc                     8
               --os-type linux           9
               --os-variant debianwheezy

Starting install...
Allocating 'testkvm.qcow'             |  10 GB     00:00
Creating domain...                    |    0 B     00:00
Guest installation complete... restarting guest.

1

Опция --connect указывает, какой «гипервизор» использовать. Он указывается в виде URL, содержащего систему виртуализации(xen://, qemu://, lxc://, openvz://, vbox:// и т. п.) и машину, на которой должны размещаться виртуальные машины (это поле можно оставить пустым в случае локального узла). В дополнение к этому, в случае QEMU/KVM каждый пользователь может управлять виртуальными машинами, работающими с ограниченными правами, и путь URL позволяет дифференцировать «системные» машины (/system) от остальных (/session).

2

Так как KVM управляется тем же образом, что и QEMU, в --virt-type kvm можно указать использование KVM, хотя URL и выглядит так же, как для QEMU.

3

Опция --name задаёт (уникальное) имя виртуальной машины.

4

Опция --ram позволяет указать объём ОЗУ (в МБ), который будет выделен виртуальной машине.

5

--disk служит для указания местоположения файла образа, который будет представляться жёстким диском виртуальной машины; этот файл создаётся, если только ещё не существует, а его размер (в ГБ) указывается параметром size. Параметр format позволяет выбрать из нескольких способов хранения образа файла. Формат по умолчанию (raw) — это отдельный файл, в точности соответствующий диску по размеру и содержимому. Мы выбрали здесь более передовой формат, специфичный для QEMU и позволяющий начать с небольшого файла, увеличивающегося только по мере того, как виртуальная машина использует пространство.

6

Опция --cdrom используется, чтобы указать, где искать оптический диск для установки. Путь может быть либо локальным путём к ISO-файлу, либо URL, по которому можно получить файл, либо файлом устройства физического привода CD-ROM (то есть /dev/cdrom).

7

С помощью опции --network указывается, каким образом виртуальная сетевая карта интегрируется в сетевую конфигурацию хоста. Поведением по умолчанию (которое мы задали явно в этом примере) является интеграция в любой существующий сетевой мост. Если ни одного моста нет, виртуальная машина сможет получить доступ к физической сети только через NAT, поэтому она получает адрес в подсети из частного диапазона (192.168.122.0/24).

8

--vnc означает, что подключение к графической консоли нужно сделать доступным через VNC. По умолчанию соответствующий VNC-сервер слушает только на локальном интерфейсе; если VNC-клиент должен запускаться на другой системе, для подключения потребуется использовать SSH-туннель (см. Раздел 9.2.1.3, «Создание шифрованных туннелей»). Как вариант, можно использовать опцию --vnclisten=0.0.0.0, чтобы VNC-сервер стал доступен на всех интерфейсах; заметьте, что если вы сделаете так, вам серьёзно стоит заняться настройкой межсетевого экрана.

9

Опции --os-type и --os-variant позволяют оптимизировать некоторые параметры виртуальной машины, исходя из известных особенностей указанной операционной системы.
Сейчас виртуальная машина запущена, и нам надо подключиться к графической консоли, чтобы произвести установку. Если предыдущий шаг выполнялся в графическом окружении, это подключение установится автоматически. В противном случае, или же при удалённой работе, чтобы открыть графическую консоль, можно запустить virt-viewer в любом графическом окружении (пароль root на удалённой машине запрашивается дважды, поскольку для работы требуется два SSH-соединения):
$ virt-viewer --connect qemu+ssh://root@server/system testkvm
root@server's password: 
root@server's password: 
Когда процесс установки завершится, виртуальная машина перезагрузится и будет готова к работе.

12.2.3.4. Управление машинами с помощью virsh

Теперь, когда установка выполнена, давайте посмотрим, как обращаться с имеющимися виртуальными машинами. Первым делом попробуем попросить у libvirtd список управляемых им виртуальных машин:
# virsh -c qemu:///system list --all
 Id Name                 State
----------------------------------
  - testkvm              shut off
Давайте запустим нашу тестовую виртуальную машину:
# virsh -c qemu:///system start testkvm
Domain testkvm started
Теперь можно получить инструкции для подключения к графической консоли (возвращённый VNC-дисплей можно передать в качестве параметра команде vncviewer):
# virsh -c qemu:///system vncdisplay testkvm
:0
В число прочих подкоманд virsh входят:
  • reboot для перезапуска виртуальной машины;
  • shutdown для корректного завершения работы;
  • destroy для грубого прерывания работы;
  • suspend для временной приостановки;
  • resume для продолжения работы после приостановки;
  • autostart для включения (или для выключения, с опцией --disable) автоматического запуска виртуальной машины при запуске хост-системы;
  • undefine для удаления всех следов виртуальной машины из libvirtd.
Все эти подкоманды принимают идентификатор виртуальной машины в качестве параметра.

12.2.3.5. Установка RPM-системы в Debian с помощью yum

Если виртуальная машина предназначается для запуска Debian (или одного из производных дистрибутивов), систему можно инициализировать с помощью debootstrap, как описано выше. Но если на виртуальную машину надо установить систему, основанную на RPM (такую как Fedora, CentOS или Scientific Linux), установку следует производить с помощью утилиты yum (которая доступна из одноимённого пакета).
Эта процедура требует использования rpm для распаковки начального набора файлов, включая, в частности, конфигурационные файлы yum, а затем вызов yum для распаковки оставшихся пакетов. Но поскольку yum вызывается извне chroot, потребуется внести некоторые временные изменения. В примере ниже целевой chroot — /srv/centos.
# rootdir="/srv/centos"
# mkdir -p "$rootdir" /etc/rpm
# echo "%_dbpath /var/lib/rpm" > /etc/rpm/macros.dbpath
# wget http://mirror.centos.org/centos/7/os/x86_64/Packages/centos-release-7-1.1503.el7.centos.2.8.x86_64.rpm
# rpm --nodeps --root "$rootdir" -i centos-release-7-1.1503.el7.centos.2.8.x86_64.rpm
rpm: RPM should not be used directly install RPM packages, use Alien instead!
rpm: However assuming you know what you are doing...
warning: centos-release-7-1.1503.el7.centos.2.8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
# sed -i -e "s,gpgkey=file:///etc/,gpgkey=file://${rootdir}/etc/,g" $rootdir/etc/yum.repos.d/*.repo
# yum --assumeyes --installroot $rootdir groupinstall core
[...]
# sed -i -e "s,gpgkey=file://${rootdir}/etc/,gpgkey=file:///etc/,g" $rootdir/etc/yum.repos.d/*.repo