Виртуализация в Unix. Часть 1: Kernel-based Virtual Machine (KVM)

Alexander Bazhenov
16 min readSep 30, 2018

KVM — программное решение с открытым исходным кодом, обеспечивающее виртуализацию в дистрибутивах Linux и FreeBSD-системах (который так же портирован в них, как модуль ядра). Подробней о принципах работы и об устройстве KVM можно прочитать на сайте RedHat, или на linux-kvm.org, ниже будет представлена лишь практическая часть по подготовке системы к использованию в качестве гипервизора, настройке и созданию виртуальных машин.

Подготовка хоста виртуализации.

Подготовить систему к использованию в качестве гипервизора можно, как с помощью ansible-ролей, так и вручную — путем установки и настройки необходимых пакетов. Ниже будут рассмотрены оба способа.

Установка необходимых пакетов.

Прежде, чем использовать сервер в качестве гипервизора, проверим включена ли в BIOS аппаратная виртуализация. Для Intel следующий вывод должен содержать инструкции “vmx”, для AMD — “svm”:

# cat /proc/cpuinfo | egrep "vmx|svm"

Можно так же проверить командой:

# lscpu | grep Virtualization

Для установки пакетов и использования системы в качестве гипервизора подойдет как серверный, так и desktop-дистрибутив. Ниже будет рассмотрена установка на Centos 7.x, Debian Stretch, Ubuntu 16.x, но в других версиях этих дистрибутивов установка может быть абсолютно идентична.

Ubuntu.

# apt update
# apt install libvirt-bin lldpd python-libvirt python-lxml qemu-kvm ubuntu-vm-builder
# systemctl start libvirt-bin

Debian.

# apt update
# apt install -y qemu-kvm libvirt0
# systemctl enable libvirtd
# systemctl start libvirtd

Centos.

Для Centos пакеты лучше устанавливать из EPEL репозитория:

# yum install epel-release

или из oVirt, где они новей:

# yum install https://resources.ovirt.org/pub/yum-repo/ovirt-release42.rpm

Непосредственно сама установка пакетов:

# yum update
# yum install qemu-kvm qemu-img libvirt libvirt-python libvirt-client virt-install virt-viewer
# systemctl enable libvirtd
# systemctl start libvirtd

Настройка Bridged Network.

По умолчанию, все создаваемые виртуальные машины будут в дефолтной сети KVM, которая находится за NAT’ом. Её можно удалить:

# virsh net-destroy default
# virsh net-undefine default
# service libvirtd restart

Список всех сетей для KVM можно получить командой:

# net-list --all

Для того, чтобы создаваемые виртуальные машины находились в одной сети необходимо настроить network bridge.

Убедимся, загружен ли модуль bridge:

# modinfo bridge

Если нет, то загрузим:

# modprobe bridge

Ubuntu/Debian.

Устанавливаем пакет bridge-utils и редактируем настройки сетевых интерфейсов:

# apt install bridge-utils
# cat /etc/network/interfaces

Для статических адресов:

iface ens3 inet manualauto br0
iface br0 inet static
address 10.1.1.76
netmask 255.255.255.0
gateway 10.1.1.1
dns-nameservers 10.10.12.2 10.10.12.3
dns-search domain.com
bridge_ports ens3
bridge_stp off
bridge_fd 0
bridge_maxwait 0

Для DHCP:

iface ens3 inet manualauto br0
iface br0 inet dhcp
bridge_ports ens3
bridge_stp off
bridge_fd 0
bridge_maxwait 0

Переподнимаем интерфейс и перегружаем daemon:

# ifdown br0 && ifup br0
# systemctl restart networking

Centos.

# yum install bridge-utils -y

Для конфигурации можно использовать текстово-графический интерфейс network manager’а:

# nmtui

или исправить конфигурацию интерфейсов вручную. Приводим конфиг интерфейса, к которому будет подключен bridge к следующему виду:

# cat /etc/sysconfig/network-scripts/ifcfg-eno1HWADDR=00:25:90:5B:22:10
TYPE=Ethernet
BOOTPROTO=none
UUID=59eddc7c-c439-33bf-beca-5222a4a0331e
DEVICE="eno1"
ONBOOT=yes
NM_CONTROLLED="no"
BRIDGE=br0

Непосредственно сам bridge:

# cat /etc/sysconfig/network-scripts/ifcfg-br0

Для статических адресов:

DEVICE="br0"
BOOTPROTO="static"
IPADDR="10.1.1.76"
NETMASK="255.255.255.0"
GATEWAY="10.1.1.76"
DNS1=10.1.1.2
DNS2=10.1.1.3
ONBOOT="yes"
TYPE="Bridge"

Для DHCP:

DEVICE="br0"
ONBOOT=yes
TYPE="Bridge"
BOOTPROTO="dhcp"
ONBOOT="yes"

Если интерфейс не управляется network manager’ом следует добавить строчку:

NM_CONTROLLED="no"

Переподнимаем интерфейс и перегружаем daemon:

# ifdown br0 && ifup br0
# systemctl restart networking

Подготовка хоста виртуализации с помощью Ansible.

Перед тем как управлять хостами с помощью Ansible для Debian/Ubuntu дополнительно может потребоваться установить python (или python-minimal):

# apt install python

или:

# apt install python-minimal

Нам понадобятся три роли: epel-repo для установки репозитория Epel, network — для создания network bridge и kvm — непосредственно для самой подготовки хоста виртуализации. Устанавливаем Ansible. Для Ubuntu/Debian:

# apt install ansible sshpass

Для Centos/RHEL:

# yum install ansible sshpass

Установку для других дистрибутивов смотрите в официальной документации. Указываем в конфиге путь к скачанным ролям — например, /home/username/ansible/roles:

# cat /etc/ansible/ansible.cfg...
roles_path = /home/username/ansible/roles
...

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

# cat /home/username/ansible/roles/inventory...
10.1.1.76
[new-hypervisors:vars]
ansible_connection=ssh
ansible_become_user=root
ansible_ssh_common_args='-o StrictHostKeyChecking=no'
ansible_ssh_user=user
ansible_ssh_pass=ssh-password-here
ansible_become_pass=root-password-here

И далее задаем в playbook’е, вызывающем роли kvm и network необходимые параметры — настройки сети (IP-адресс хоста не меняется), имя bridge-интерфейса:

# cat /home/username/ansible/roles/init_new_kvm_hypervisor.yml...- hosts: new-hypervisors
become: true
become_method: sudo
roles:
- role: epel-repo
when: ansible_os_family == "RedHat"
- role: network
network_bridge_name: br0
network_gateway_address: 10.1.1.1
network_nameserver1: 10.1.1.2
network_nameserver2: 10.1.1.3
network_netmask_cidr: 255.255.255.0
searchdomain: domain.com
bootproto: static
- role: kvm
kvm_config_users: true

В некоторых дистрибутивах (Centos) создание bridged interface может завершиться с ошибкой (bug пока что не исправлен), поэтому лучше явно указать, к какому интерфейсу подключать bridge. Задаем его имя, исправляя перед запуском playbook’а:

# ... /roles/network/vars/network.yml...
ports: "eth0"

Запускаем playbook:

# ansible-playbook init_new_kvm_hypervisor.yml -i inventory

Управление хостом виртуализации.

Управление гипервизором проще всего осуществлять через virt-manager. Устанавливаем в локальной системе:

# sudo apt install virt-manager

или:

# sudo yum install virt-manager

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

# adduser user
# passwd user

Для того, чтобы пользователь имел возможность управлять libvirt’ом его нужно добавить в соответствующую группу: в Centos — это группа libvirt, в Ubuntu — libvirtd. Проверим:

# cut -d: -f1 /etc/group | grep libvirt
libvirtd

Следовательно, добавляем пользователя user в группу libvirtd:

# usermod -aG livbirtd user

В некоторых дистрибутивах (Debian 9.x) пользователя так же необходимо будет добавить в группу “libvirt-qemu”. Просмотреть список групп можно:

# cat /etc/group | grep libvirt

Теперь необходимо сгенерировать ключ ssh и установить его на сервер, к которому будем подключаться через libvirt. Поскольку virt-manager по умолчанию запускается от обычного пользователя (не из под root), то и ключ генерируем не из под root’а. Обычно ключи лежат в папке /home/user/.ssh/id_rsa. Если их нет, то создаем:

# ssh-keygen -t rsa
Рис. 1. Подключение в virt-manager.

и устанавливаем на сервер с libvirt:

# ssh-copy-id user@10.1.1.76

Далее подключаемся в virt-manager к серверу виртуализации (рис. 1).

Помимо графического интерфейса virt-manager возможно так же подключение из консоли (virsh). Подробную инструкцию можно найти на сайте libvirt.

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

Создание виртуальных машин из virt-manager’а тривиально и в дополнительном описании не нуждается. Что касаемо CLI, то создание виртуальной машины с именем “ubuntu-vm” ОС Ubuntu с 1024 килобайтами RAM и 1 ядром CPU будет выглядеть:

# virt-install --name=ubuntu-vm \
--virt-type kvm \
--vcpus=1 \
--memory=1024 \
--cdrom=/tmp/ubuntu.iso \
--disk size=5 \
--noautoconsole \
--os-variant=ubuntuprecise

После создания виртуальная машина сама запустится, в противном случае запустить можно командой:

# virsh start ubuntu-vm

Завершить работу ВМ можно командой:

# virsh shutdown ubuntu-vm

Завершить работу принудительно (hard power-off):

# virsh destroy ubuntu-vm

Перезагрузить:

# virsh reboot ubuntu-vm

Удалить:

# # virsh undefine ubuntu-vm

Просмотреть список всех виртаульных машин можно командой:

# virsh list --all

а только запущенных (running):

# virsh list

“Заморозить” (suspend) и запустить далее (resume) виртуальную машину можно командами:

# virsh suspend <domain-id, domain-name or domain-uuid>
# virsh resume <domain-id, domain-name or domain-uuid>

Сохранить состояние машины можно командой:

# virsh save <domain-name> <domain-id or domain-uuid> <filename>

а восстановить:

# virsh restore <filename>

По умолчанию все конфигурации виртуальных машин находятся в xml-формате папке /etc/libvirt/qemu. Можно открыть их на редактирование любым привычным редактором, а можно выполнить команду (откроется в vi):

# virsh edit vm-1

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

# virsh dominfo vm-1

Отобразить потребляемые ресурсы (CPU и Memory) можно командой:

# virt-top

Если пакет не установлен в системе, то:

# apt install virt-top

или:

# yum install virt-top

Клонирование виртуальных машин может быть осуществлено через графический интерфейс virt-manager’а, или через консольный virt-clone. Следующая команда создаст клон оригинальной <vm-name> и автоматически сгенерирует образ диска:

# virsh suspend <vm-name>
# virt-clone --original <vm-name> --auto-clone
# virsh resume <vm-name>

Принудительно задать имя клона:

# virt-clone --original=<original-vm-name> --name=<destination-vm-name> --auto-clone

Задать имена виртуальных дисков (например, если клонируемая ВМ имеет два диска):

# virt-clone --original=<original-vm-name> --name=<destination-vm-name> --file /var/lib/libvirt/images/original-vm-disk1.img --file /var/lib/libvirt/images/original-vm-disk2.img

Если в качестве носителей ВМ используется LVM:

# virt-clone -o <original-vm-name> --name <destination-vm-name> --file /dev/vg_kvm/lv_disk2

Можно так же клонировать ВМ, которые содержат snapshots. Более подробную информацию об управлении виртуальными машинами можно найти на сайте centos.org, или RedHat.

Подключение к консоли.

Рис. 2. KVM Spice Display settings.

Spice.

Для подключения через virt-manager достаточно, чтобы в качестве сервера был выбран Spice (см. настройки на рис. 2), а в качестве дисплей адаптеров виртуальной машины — QXL, или VGA. Подключение через virt-manager необходимо осуществлять по SSH-ключу (не по паролю). В большинстве случаев дефолтные конфиги libvirt уже пригодны для подключения к Spice, в противном случае стоит сверить следующие настройки:

# cat /etc/libvirt/qemu.conf...
remote_display_port_min = 5900
remote_display_port_max = 6000
# Для Centos:
security_driver = "selinux"
...

Все остальные параметры Spice должны быть дефолтными (обычно закомментированы).

Рис. 3. KVM VNC Display Settings.

VNC.

Для подключения по VNC аналогично достаточно в virt-manager выбрать “VNC Server” (рис. 3), а в качестве display-адаптеров в гостевых системах использовать QXL, или VGA.

Можно так же отредактировать настройки видео через CLI:

# virsh edit <vm-name>
...
<graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0' passwd='yourpassword'>
<listen type='address' address='0.0.0.0'/>
</graphics>
...

Приведенный пример будет слушать подключения на всех IP-адресах KVM сервера и при подключении запрашивать пароль “yourpassword”. Если убрать параметр passwd, то можно будет подключиться без пароля. Для того, чтобы определить IP-адрес и порт для подкючения к виртуальной машины по VNC выполните команду:

# virsh vncdisplay <vm-name>
127.0.0.1:1

К полученному значению порта нужно прибавить 5900. Таким образом, в приведенном примере, подключение возможно с любого IP-адреса по порту 5901.

tty.

Подключение к текстовой консоли так же возможно напрямую через CLI. Но для этого предварительно нужно указать некоторые параметры загрузки. Для Centos/RHEL:

# /etc/grub.conf
console=tty0 console=ttyS0,115200

Альтернативно можно дописать в /etc/grub следующие параметры:

serial --unit=0 --speed=115200
terminal --timeout=5 serial console

Подключаемся к консоли:

# virsh console <vm-name>

Использование NUMA.

По умолчанию libvirt использует дефолтную политику гипервизора, которая в свою очередь подразумевает запуск виртуальной машины на любых свободных вычислительных ресурсах (процессорах и ядрах). Но бывают случаи, когда явное задание ресурсов процессора бывает рациональней, особенно для систем с архитектурой NUMA (Non-Uniform Memory Access). Рассмотрим пример конфига, когда нужно назначить виртуальной машины определенные ядра процессора. Но для начала просмотрим информацию о процессорных ресурсах:

# virsh nodeinfoCPU model:           x86_64
CPU(s): 16
CPU frequency: 1600 MHz
CPU socket(s): 2
Core(s) per socket: 4
Thread(s) per core: 2
NUMA cell(s): 2
Memory size: 16768108 KiB

Таким образом видим, что установлен два процессора с 4 ядрами и двумя потоками на каждом ядре. Из вывода так же видим, что имеется две NUMA-ноды. Дополнительные параметры CPU можно получить командой:

# virsh capabilities

Но назначение ресурсов CPU конкретной ноде не даст никакой пользы, если у этой NUMA-ноды недостаточно памяти. libvrit хранит информацию о доступной памяти на каждой NUMA-ноде. Получить информацию можно:

# virsh freecell --all
0: 2203620 kB
1: 3354784 kB

Таким образом видим, что для запуска ВМ с 3Гб оперативной памяти лучше использовать первую NUMA-ноду (cell 1). Просмотреть информацию можно так же через numactl. Устанавливаем:

# apt install numactl

или:

# yum install numactl

Смотрим:

# numactl --hardware
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 8 9 10 11
node 0 size: 8183 MB
node 0 free: 7486 MB
node 1 cpus: 4 5 6 7 12 13 14 15
node 1 size: 8192 MB
node 1 free: 7786 MB
node distances:
node 0 1
0: 10 21
1: 21 10

Для примера создадим виртуальную машину, которой назначено по 2 ядра от каждого процессора:

# virt-install \
--connect qemu:///system \
--virt-type kvm \
--name vm-1 \
--ram=6144 \
--disk path=vm-1.qcow2,size=15 \
--os-variant ubuntuprecise \
--vcpus=8,cpuset=0,1,12,13 \
--cpu host-passthrough \

--noautoconsole \
-w bridge=br0,mac=52:54:01:b1:d3:2b \
--cdrom $kvm_images_path/$isoname
# virsh vcpupin vm-1 0 0
# virsh vcpupin vm-1 1 1
# virsh vcpupin vm-1 2 12
# virsh vcpupin vm-1 3 13

Просмотреть результат CPU affintiy можно командой:

# virsh vcpuinfo vm-1

Подробней об использовании NUMA можно узнать на сайте Fedora и RedHat.

Проброс устройств (Passthrough).

Рассмотрим проброс устройств на примере проброса Ethernet-порта с хоста гипервизора внутрь гостевой системы в режиме PCI Passthrough. Вообще, Network адаптеры создаваемые для виртуальных машин в KVM можно так же назначать (assign) к любому ethernet-интерфейсу, но тогда теряется часть функционала hardware, а трафик пойдет через ядро хостовой системы. Для работы PCI Passthrough нужно чтобы процессор и чипсет поддерживали технологию виртуализации (в Intel — это VT-d, в AMD — AMD-Vi) и была активирована опция intel_iommu/amd_iommu. В первую очередь необходимо проверить, активированы ли данные опции в BIOS. Далее проверяем доступна ли IOMMU в самой ОС. Для AMD:

# dmesg | grep -iE "(IOMMU|AMD-Vi)"

Для Intel:

# dmesg | grep -iE "(IOMMU|VT-d)"

Возможно, в /etc/default/grub так же придется добавить опцию. Для Intel:

GRUB_CMDLINE_LINUX=" ... intel_iommu=on"

Для AMD:

GRUB_CMDLINE_LINUX=" ... iommu=pt iommu=1"

Обновляем grub и перезагружаемся:

Ubuntu/Debian:

# update-grub
# reboot

Centos:

# grub2-mkconfig -o /boot/grub2/grub.cfg
# reboot

Теперь необходимо добавить адрес PCI-устройства:

# lspci | grep Ethernet
01:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
01:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)

Соответственно, адрес устройства 01:00.0, или 01:00.1. Находим его в virt-manager’е в настройках ВМ:

Add Hardware -> PCI host Device

или добавляем через CLI при создании машины, добавив следующую строчку:

# virt-install \
--connect qemu:///system \
...
--host-device pci_0000_01_00_0 \

Дополнительную информацию про Assign Device in KVM можно получить на сайте RedHat и linux-kvm.org. Так же, на habr’е была отличная статья по GPU Passthrough.

Работа со snapshots.

Наиболее простой способ управления snapshots — это virt-manager, который в свою очередь использует команды qemu. “Замораживаем” виртуальную машину, создаем snapshot и по завершении “размораживаем” виртуальную машину:

# virsh domfsfreeze vm-name
# qemu-img create -f qcow2 -b vm-name.qcow2 vm-name-snapshot.qcow2
# virsh domfsthaw vm-name

QEMU также поддерживает временные снимки, в которых пользователю не нужно создавать отдельный img-файл: флаг “-snapshot” позволяет создавать временные файлы пока виртуальная машина включена и, как только она будет выключена, все изменения удалятся:

# qemu -hda centos.img -snapshot
Рис. 4. VirtIO Serial.

Но QEMU в отличие от virsh не может создавать snapshot виртуальных машин “на ходу”, но для того, чтобы воспользоваться этой возможностью необходимо в гостевой системе установить qemu-guest-agent и добавить для этой виртуальной машины устройство “QEMU channel device”. Заходим в свойства виртуальной машины в virt-manager (рис. 4) и добавляем устройство:

Add Hardware -> Channel -> org.qemu.guest_agent.0

Или через консоль:

# virsh shutdown <vm-name>
# virsh edit <vm-name>
<channel type='unix'>
<target type='virtio' name='org.qemu.guest_agent.0'/>
</channel>
# virsh start <vm-name>

Устройство так же может быть добавлено и для запущенной виртуальной машины. Создаем xml:

# cat agent.xml
<channel type='unix'>
<target type='virtio' name='org.qemu.guest_agent.0'/>
</channel>
# virsh attach-device <vm-name> agent.xml

Теперь на виртуальной машине <vm-name> (так же еще называют “dom name”) необходимо установить “гостевой агент”. Ubuntu/Debian:

# apt install qemu-guest-agent

Centos/RHEL:

# yum install qemu-guest-agent

Запускаем агент и добавляем в автозагрузку:

# systemctl enable qemu-guest-agent
# systemctl start qemu-guest-agent

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

# virsh qemu-agent-command <vm-name> '{"execute":"guest-ping"}'

Получим следующий вывод:

{"return":{}}

Но по факту, для создания snapshots нам потребуется поддержка “заморозки” гостевой файловой системы (fsreeze). Проверяем, выполнив команду с хоста гипервизора:

# virsh qemu-agent-command cloud-gate.emzior '{"execute":"guest-info"}' | grep fsfreeze

Если получим вывод вида:

{"return":{"version":"2.5.0","supported_commands":
...
{"enabled":true,"name":"guest-fsfreeze-thaw","success-response":true},{"enabled":true,"name":"guest-fsfreeze-status","success-response":true},{"enabled":true,"name":"guest-fsfreeze-freeze-list","success-response":true},{"enabled":true,"name":"guest-fsfreeze-freeze","success-response":true}, ...

значит поддерживается и можно приступать к созданию snapshots. Дополнительную информацию о QMP-командах и принципах работы гостевого агента можно найти на сайте qemu.org.

Дампим настройки машины в xml:

# virsh snapshot-dumpxml <vm-name> snapshot.xml

Создаем snapshot непосредственно с самими данными:

# virsh snapshot-create-as <vm-name> --disk-only --atomic --quiesce --no-metadata

Получим сообщение вида:

Domain snapshot 1538052795 created

В последствии подобные snapshots, содержащие только состояние дисков, удобно использовать для backup’ов (за счет использования опции blockcommit). Во всех остальных случаях удобней пользоваться полными снимками виртуальных машин. Создадим полный snapshot:

# virsh snapshot-create-as --domain <vm-name> \
--name "snapshotname" \
--description "Somedescription here" \
--atomic

Как видно, можно так же задать имя (ключ “name”) и описание (ключ “description). За списком остальных ключей следует обратиться к документации на сайте RedHat.

Просмотреть список всех snapshots для виртуальной машины можно командой:

# virsh snapshot-list --domain

В результате получите список полных snapshots. Snapshot’ы содержащие только блочные устройства (ключи “--disk-only --quiesce --no-metadata”) можно получить командой:

# virsh domblklist <vm-name>

Получить информацию о каком-либо конкретном snapshot’e:

# virsh snapshot-info --domain <vm-name> --snapshotname "snapshotname"

Получим примерно следующий вывод:

Name:           snapshotname1
Domain: test
Current: yes
State: running
Location: internal
Parent: -
Children: 0
Descendants: 0
Metadata: yes

Откатить состояние ВМ к определенному snapshot’у можно командой:

# virsh snapshot-revert <vm-name> <snapshotname>

Удаление snapshot’а:

# virsh snapshot-delete <vm-name> <snapshotname>

Иногда snapshot может быть случайно удален. Если виртуальная машина не остановлена, то snapshot можно восстановить: на Stackoverflow есть post, описывающий пошаговое восстановление образов/snapshots виртуальных машин.

Работа со Storage Pools.

Образы жестких дисков виртуальных машин располагаются в так называемых Storage Pools. libvirt поддерживает различные типы storage pool’ов — от обычной локальной папки (local storage, или filesystem pool), или LVM-based до NFS, iSCSI, CEPH и тд. По умолчанию libvirt хранит образы дисков в локальном filesystem pool, который располагается в /var/lib/libvirt/images. Как обычно, большую часть операций со storage pools можно производить из virt-manager:

правая кнопка на хосте -> Details -> Storage

Что касаемо, консоли, то получить список доступных для хоста pool’ов можно командой:

# virsh pool-list
Name State Autostart
-------------------------------------------
images active yes

Если требуется вывести так же список неактивных pool’ов, то следует воспользоваться ключом “--all”:

# virsh pool-list --all

Информацию о конкретном pool’е можно получить:

# virsh pool-info images
Name: images
UUID: 5b41d0cd-ddb9-4270-8726-cfd55a2bf843
State: running
Persistent: yes
Autostart: yes
Capacity: 927.93 GiB
Allocation: 139.34 GiB
Available: 788.59 GiB

Обновить имеющиеся образы в storage pool’е:

# virsh pool-refresh <pool-name>
Pool images refreshed

К примеру, если требуется создать дополнительный storage pool, расположенный локально в папке /mnt/somefolder, то для начала требуется создать xml:

# cat somefolder.xml<pool type="dir">
<name>somefolder</name>
<target>
<path>/mnt/somefolder</path>
</target>
</pool>

Создаем pool из этого xml, проверяем результат и запускаем:

# virsh pool-create somefolder.xml
# virsh pool-list --all
Name State Autostart
-------------------------------------------
images active yes
somefolder active no

Если по каким-то причинам Pool неактивен, можно активировать командой:

# virsh pool-start <pool-name>

Или даже добавить в автозапуск:

# virsh pool-autostart <pool-name>

Если требуется удалить Pool, то для того, чтобы избежать проблем с виртуальными машинами использующими этот Pool, требуется вначале выполнить:

# virsh pool-destroy <pool-name>

При желании, если вы хотите удалить каталог, в котором находится пул хранилищ, используйте следующую команду:

# virsh pool-delete <pool-name>

Удалить предопределяющие Pool данные можно командой:

# virsh pool-undefine <pool-name>

Остальную более подробную информацию об управлении Storage Pool’ами можно найти на сайте RedHat и libvirt.org.

Операции с образами дисков.

Операции с образами виртуальных дисков обеспечивает пакет QEMU, который в свою очередь поддерживает множество различных форматов: qcow, qcow2, raw, vdi, vmdk, vhdx и тд (более полный список опубликован здесь). Проще всего управлять образами через virt-manager, однако функционал QEMU будет несколько ограничен (например, нельзя изменить размер образа, или сконвертировать образ из одного формата в другой). Через консоль создание образа диска в нативном для KVM формате qcow2:

# qemu-img create -f qcow2 <image-name>.qcow2 10G

с последующим attach’ем к виртуальной машине <vm-name> как устройство vdb будет выглядеть следующим образом:

# virsh attach-disk {vm-name}  /var/lib/libvirt/images/<image-name>.qcow2 vdb

или:

# virsh attach-disk <vm-name> \
--source /var/lib/libvirt/images/<image-name>.qcow2 \
--target vdb \
--persistent

В целом интерфейс virsh c функцией attach-disk используется в следующем формате:

# virsh attach-disk domain source target [--driver driver] [--subdriver subdriver] [--cache cache] [--type type] [--mode mode] [--config] [--sourcetype soucetype] [--serial serial] [--shareable] [--rawio] [--address address] [--multifunction]

В качестве driver’а в большинстве случаев указывается “qemu”, в качестве cache можно указать “writethrough”. Подробней о режимах дискового кэширования можно ознакомиться здесь. Если параметр кэширования не задан, то используются параметры “Hypervisor defaults”.

Альтернативным способом будет добавление уcтройства через его xml-конфиг:

cat NewStorage.xml<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/var/lib/libvirt/images/<image-name>.img'/>
<target dev='vdb'/>
</disk>
virsh attach-device <vm-name> NewStorage.xml

Дополнительно информацию о процессе добавления образов можно получить на сайтах: RedHat и Fedoraproject.org.

Изменим размер образа (увеличим на 10Гб):

# virsh shutdown <vm-name>
# qemu-img resize <image-name>.qcow2 +10G
# virsh start <vm-name>

Иногда при попытке изменить размер образа диска можно получить сообщение:

qemu-img: Can't resize an image which has snapshots

Но при этом в virt-manager’е не отображается ни одного снимка, а команда:

# virsh snapshot-list {domain_name}

так же е выводит никаких результатов о созданных snapshots. Вероятней всего, snapshot был создан через qemu и получить информацию об образе можно командой:

# qemu-img info /var/lib/libvirt/images/image_name.qcow2

которая, к примеру, выдает:

image: /var/lib/libvirt/images/image_name.qcow2
file format: qcow2
virtual size: 50G (53687091200 bytes)
disk size: 90G
cluster_size: 65536
Snapshot list:
ID TAG VM SIZE DATE VM CLOCK
1 before_install 999M 2018-03-20 17:48:40 00:00:00.000
Format specific information:
compat: 1.1
lazy refcounts: true
refcount bits: 16
corrupt: false

Как видим, перед расширением образа необходимо удалить snapshot по его ID:

# qemu-img snapshot -d 1 /var/lib/libvirt/images/image_name.qcow2

Смотрим информацию об образе можно командой:

# qemu-img info <image-name>.qcow2
image: <image-name>.qcow2
file format: qcow2
virtual size: 20G (21474836480 bytes)
disk size: 10G
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: true
refcount bits: 16
corrupt: false

Зачастую бывает нужно сконвертировать образ из одного формата в другой (например, для того, чтобы native-формат qcow2 работал быстрей, чем vmdk от VMware). Для этого можно воспользоваться пакетом qemu-img:

# sudo apt-get install qemu-utils

или:

# yum install qemu-img

Пакет qemu-img поддерживает vmdk, qcow2, vhd, vhdx, raw, vdi. По факту нужно указать исходный и конечный формат. Сконвертируем vdi в qcow2:

# qemu-img convert -p -f vdi -O qcow2 /var/lib/libvirt/images/<source-image-name>.vdi /var/lib/libvirt/images/<destination-image-name>.qcow2

Возможно использовать следующие опции:

-p - отображать процесс конвертирования в процентах
-f - исходный формат
-O - конечный формат
-o - дополнительные опции. Например:
-o subformat=dynamic - указывается для получения динамического диска на выходе (доступно не во всех форматах).

Дополнительную информацию по qemu-img можно получить на сайтах fedoraproject.org и RedHat.

Ссылки.

Многое (за исключением специфических для RedHat компонентов) можно так же почерпнуть по следующим ссылкам:

Информацию по распоространенным проблемам при работе с livbirt можно найти в отдельном разделе сайта RedHat:

--

--