IP-KVM через QEMU
Устранение неисправностей при загрузке операционной системы на серверах без KVM — непростое занятие. Создаем себе KVM-over-IP через образ восстановления и виртуальную машину.
В случае возникновения проблем с операционной системой на удаленном сервере, администратор загружает образ восстановления и проводит необходимые работы. Такой способ отлично работает, когда причина сбоя известна, а образ восстановления и установленная на сервере операционная система из одного семейства. Если причина сбоя еще не известна, необходимо понаблюдать за ходом загрузки операционной системы.
Удаленный KVM
Получить доступ к консоли сервера можно с помощью встроенных средств, таких как IPMI или Intel® vPro™, или с помощью внешних устройств, именуемых IP-KVM. Существуют ситуации, в которых все из перечисленных технологий недоступны. Однако, это не конец. Если сервер можно удаленно перезагрузить в образ восстановления на базе операционной системы семейства Linux, то можно быстро организовать KVM-over-IP.
Образ восстановления представляет собой полноценную операционную систему, которая размещается в оперативной памяти. Таким образом, мы можем запускать любое программное обеспечение, в том числе и виртуальные машины (ВМ). То есть можно запустить ВМ, внутри которой будет работать операционная система сервера. Доступ к консоли ВМ может быть организован, например, через VNC.
Для запуска операционной системы сервера внутри ВМ необходимо указать диски сервера в качестве дисков ВМ. В операционных системах семейства Linux физические диски представляются блочными устройствами вида /dev/sdX, с которыми можно работать как с обычными файлами.
Некоторые гипервизоры, такие как QEMU и VirtualBox позволяют хранить данные ВМ в «сыром» виде, то есть только данные хранилища без метаданных гипервизора. Таким образом, ВМ можно запустить с использованием физических дисков сервера.
Подобный способ требует ресурсов на запуск образа восстановления и ВМ внутри него. Однако, при наличии четырех и более гигабайт оперативной памяти это не станет проблемой.
Подготовка окружения
В качестве виртуальной машины можно использовать легковесную и простую программу QEMU, которая чаще всего не является частью образа восстановления, поэтому должна быть установлена отдельно. Образ восстановления, который мы предлагаем клиентам, основан на Arch Linux, в котором используется пакетный менеджер pacman.
Сперва необходимо удостовериться, что образ восстановления использует последнии версии программного обеспечения. Выполнить проверку и обновить все компоненты ОС можно следующей командой:
После обновления необходимо установить QEMU. Команда на установку через pacman будет выглядеть так:
Проверим, что qemu установилась корректно:
# qemu-system-x86_64 —version
QEMU emulator version 4.0.0
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
Если все так, то образ восстановления готов к работе.
Запуск виртуальной машины
Сперва необходимо определиться с количеством ресурсов, выделяемых ВМ, и выяснить пути до физических дисков. В нашем случае мы выделим два ядра и два гигабайта оперативной памяти виртуальной машине, а диски находятся по пути /dev/sda и /dev/sdb. Запустим ВМ:
qemu-system-x86_64 \
-m 2048M \
-net nic -net user \
-enable-kvm \
-cpu host,nx \
-M pc \
-smp 2 \
-vga std \
-drive file=/dev/sda,format=raw,index=0,media=disk \
-drive file=/dev/sdb,format=raw,index=1,media=disk \
-vnc :0,password \
-monitor stdio
Немного подробнее о том, что значит каждый из параметров:
- -m 2048M — выделяем 2 ГБ оперативной памяти на ВМ;
- -net nic -net user — добавляем простое подключение к сети через гипервизор с использованием NAT (Network Address Translation);
- -enable-kvm — включаем полную виртуализацию KVM (Kernel Virtual Machine);
- -cpu host — говорим виртуальному процессору получить весь функционал процессора сервера;
- -M pc — тип оборудования PC;
- -smp 2 — виртуальный процессор должен быть двухъядерным;
- -vga std — выбираем стандартную видеокарту, которая не поддерживает большие разрешения экрана;
- -drive file=/dev/sda,format=raw,index=0,media=disk
- file=/dev/sdX — путь до блочного устройства, представляющего диск сервера;
- format=raw — помечаем, что в указанном файле все данные лежат в «сыром» виде, то есть как на диске;
- index=0 — номер диска, должен увеличиваться для каждого следующего диска на единицу;
- media=disk — виртуальная машина должна распознать это хранилище как диск;
- -vnc :0, password — запускаем VNC-сервер по умолчанию на 0.0.0.0:5900, в качестве авторизации используем пароль;
- -monitor stdio — общение администратора с qemu будет происходить через стандартные потоки ввода-вывода.
Если все в порядке, то запустится QEMU монитор:
QEMU 4.0.0 monitor — type ‘help’ for more information
(qemu)
Мы указали, что авторизация происходит по паролю, но не указали сам пароль. Сделать это можно отправив команду change vnc password в QEMU-монитор. Важное замечание: пароль не может быть больше восьми символов.
(qemu) change vnc password
Password: ******
После этого мы можем подключиться любым VNC-клиентом, например, Remmina, по IP-адресу нашего сервера с указанным нами паролем.
Теперь мы не только видим возможные ошибки на этапе загрузки, но и можем с ними бороться.
По окончании работ необходимо завершить виртуальную машину. Это можно сделать как внутри ОС, подав сигнал на выключение, либо дать команду system_powerdown в QEMU-монитор. Это будет эквивалентно однократному нажатию кнопки выключения: операционная система внутри виртуальной машины плавно завершится.
Установка операционной системы
Виртуальная машина имеет полный доступ к дискам сервера и потому может быть использована для установки операционной системы вручную. Единственное ограничение заключается в количестве оперативной памяти: не всегда ISO-образ можно разместить в оперативной памяти. Выделим в оперативной памяти четыре гигабайта для хранения образа в /mnt:
mount -t tmpfs -o size=4G tmpfs /mnt
Также загрузим установочный образ операционной системы FreeBSD 12.0:
wget -P /mnt ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/amd64/ISO-IMAGES/12.0/FreeBSD-12.0-RELEASE-amd64-bootonly.iso
Теперь можно запускать ВМ:
qemu-system-x86_64 \
-m 2048M \
-net nic -net user \
-enable-kvm \
-cpu host,nx \
-M pc \
-smp 2 \
-vga std \
-drive file=/dev/sda,format=raw,index=0,media=disk \
-drive file=/dev/sdb,format=raw,index=1,media=disk \
-vnc :0,password \
-monitor stdio \
-cdrom /mnt/FreeBSD-12.0-RELEASE-amd64-bootonly.iso \
-boot d
Флаг -boot d устанавливает загрузку с CD-привода. Подключаемся VNC-клиентом и видим загрузчик FreeBSD.
Так как для доступа в интернет использовалось получение адреса по DHCP, возможно, после настройки будет необходимо загрузиться в только что установленную систему и исправить сетевые настройки. В некоторых случаях может потребоваться установка драйверов сетевого адаптера, так как сетевая карта, установленная в сервере и эмулируемая в ВМ отличаются.
Работа с виртуальными машинами KVM. Подготовка хост-машины
Вступление
Как и было обещано в предыдущей статье, сегодня мы поговорим о базовой настройке хост-машины для работы KVM.
Для начала необходимо узнать, есть ли у нашего процессора необходимые инструкции для поддержки виртуализации.
$ egrep ‘(vmx|svm)’ /proc/cpuinfo
Если есть — это замечательно.
Подготовка операционной системы
Установку Debian Squeeze я, пожалуй, описывать не буду: если уж вы добрались до KVM, то установка системы — плёвое дело.
Устанавливать нужно будет 64-битную OS, поскольку необходимые пакеты есть только для этой архитектуры.
В Debian Squeeze «свежесть» пакетов с KVM и сопутствующих программами нас совсем не устраивает, поскольку очень много всяких фиксов и фич попросту пройдут мимо нас. Поэтому мы добавим репозитории Debian Sid и experimental:
deb http://ftp.ru.debian.org/debian sid main contrib non-free
deb-src http://ftp.ru.debian.org/debian sid main contrib non-free
deb http://ftp.ru.debian.org/debian experimental main contrib non-free
deb-src http://ftp.ru.debian.org/debian experimental main contrib non-free
Указываем, что у нас базовый дистрибутив stable, а не то, что подумала система:
# echo ‘APT::Default-Release «stable»;’ > /etc/apt/apt.conf.d/default
Оттуда нам понадобятся пакеты:
# aptitude -t experimental install linux-image-2.6.39-1-amd64 qemu-kvm virtinst libvirt-bin
Из стабильного репозитория нам будут нужны:
# aptitude install uml-utilities bridge-utils
На вашем рабочем десктопе вы можете поставить virt-manager (GUI-утилита), который позволит удобно создавать нужные конфигурации виртуальных машин.
Ядро чем «свежее» — тем лучше (в известных пределах конечно: из git, например, я бы ставить не рекомендовал). Хорошим вариантом будет 2.6.39, вышедшее недавно.
Следует отметить, что в стандартном ядре отсутствует модуль для поддержки записи в UFS2, и если планируется запускать гостевую FreeBSD, потребуется собрать ядро с этим модулем. Ну и, конечно, в Debian-овском ядре отсутствуют свежие версии cgroups.
Что должно быть включено в ядре для использования максимального объема требуемого функционала:
CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_NET=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_VIRTIO=y
CONFIG_VIRTIO_RING=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_CGROUPS=y
CONFIG_CGROUP_NS=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_MEM_RES_CTLR=y
CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED=y
CONFIG_CGROUP_SCHED=y
CONFIG_BLK_CGROUP=y
CONFIG_NET_CLS_CGROUP=y
Затем идём по ссылке и устанавливаем все deb-пакеты оттуда, копируем insmod.static в /sbin/insmod.static (это нужно, поскольку в работе libguestfs использует статически скомпилированную версию insmod, а в Debian и Ubuntu такого файла просто нет, однако в последней версиии febootstrap эту проблему устранили, insmod.static более не нужно загружать на сервер). libguestfs позволяет нам получать доступ к диску VDS через API libguestfs(C, Perl, Python, PHP) или через утилиту guestfish.
Первый блин
Сейчас мы установили все, необходимое для запуска VDS, их доступа в сеть и установки самой виртуальной машины.
Давайте попробуем что-нибудь поставить, например, тот же самый Debian. Пока без настройки сети, просто, по умолчанию.
Скачиваем установщик netinstall:
Редактируем /etc/libvirt/qemu.conf, чтобы виртуальные машины работали у нас от непривилегированного пользователя:
user = «username»
group = «libvirt»
Поскольку у нас будут использоваться tun-устройства, нужно выставить capability CAP_NET_ADMIN, сделать это можно как для отдельного исполняемого файла, так и для пользователя в целом, или настроить чтобы libvirt не сбрасывал нужные права для qemu/kvm.
Выставляем для отдельного файла:
sudo setcap cap_net_admin=ei /usr/bin/kvm
Или выставляем для пользователя в целом в файле /etc/security/capability.conf:
Или выставляем соответствующую настройку в /etc/libvirt/qemu.conf:
Добавим пользователя в группу libvirt и kvm:
# adduser username libvirt
# adduser username kvm
Запустим установку виртуальной машины:
$ virt-install —connect qemu:///system -n debian_guest -r 512 —arch=i686 —vcpus=1 —os-type=linux —os-variant=debiansqueeze —disk debian-6.0.1a-i386-netinst.iso,device=cdrom —disk debian_guest.img,bus=virtio,size=2,sparse=false,format=raw —network=default,model=virtio —hvm —accelerate —vnc
Подробно разберём параметры, которые мы указали:
- —connect qemu:///system URL, по которому мы подключаемся к KVM. Подключаться можно через ssh.
- -n debian_guest Имя гостевой системы.
- -r 512 Выделяемый объём оперативной памяти в мегабайтах.
- —arch=i686 Архитектура гостевой операционной системы.
- —vcpus=1 Количество виртуальных процессоров, доступных гостю.
- —os-type=linux —os-variant=debianlenny Специфичные для данной операционной системы параметры.
- —disk debian-6.0.1a-i386-netinst.iso,device=cdrom Загружаемся с диска, образ которого указали.
- —disk debian_guest.img,bus=virtio,size=2,sparse=false,format=raw Создаём образ системы размером 2Гб, который сразу помещаем на диск (можно создать образ нулевого размера, но тогда возможна фрагментация, что получается несколько медленнее). Формат простой, можно сделать с dd файл. Драйвер диска virtio, использовать лучше virtio, чем ide: производительность их отличается если не на порядок, то в разы.
- —network=default,model=virtio Сетевые настройки по умолчанию. В этом случае libvirt создаст мост, сделает dhcp сервер и выдаст через него адрес для доступа виртуальной машины.
- —hvm Полная виртуализация — то есть, можно использовать собственные ядра.
- —accelerate Работа через /dev/kvm.
- —vnc Запускаем VNC, чтобы подключаться к текстовой консоли.
Утилиты настройки и управления
Для управления установкой и для клонирования виртуальных машин у нас есть две замечательные утилиты — графическая и консольная: virt-manager и virsh, соответственно. Конечно, консольная версия намного богаче по возможностям, но ничто не сравнится с видом графиков, от которых сердце сисадмина млеет.
Думаю с virt-manager вы и сами разберётесь, давайте попробуем покопаться в консольных внутренностях virsh. Вот несколько команд которые стоит выполнить и посмотреть что из этого получится:
$ virsh —connect qemu:///system list —all
$ virsh —connect qemu:///system dominfo debian_guest
$ virsh —connect qemu:///system stop debian_guest
Чтобы тысячу раз не писать —connect qemu:///system, добавьте:
export VIRSH_DEFAULT_CONNECT_URI= qemu:///system
В .bashrc или просто выполните эту команду в терминале.
Подготовка сети
В официальной документации предлагается использовать несколько вариантов организации сети: NAT, bridged и прямое использование сетевых карт. И, к сожалению, в различных примерах, которые я нашел в сети и на официальном сайте, рассматриваются только NAT и bridged сети.
В моей конфигурации используются TUN/TAP устройства, на которые с eth0 маршрутизируется трафик. Коротко опишу, почему выбран именно такой способ маршрутизации:
NAT нам не подходит, поскольку каждая VDS должна быть доступна из сети напрямую.
Схема с мостами не очень надёжная, поскольку теоретически есть возможность «захвата» IP адреса чужой виртуальной машины.
Итак:
Данный участок конфигурации нужно указывать непосредственно в конфигурационном файле гостя, расположенного по адресу /etc/libvirt/qemu/debian_guest.xml. Редактировать лучше всего через:
$ virsh edit debian_guest
Тогда конфигурация обновится на лету, при условии, что машина не запущена. В противном случае нужно будет подождать, пока она остановится, и запустить ее снова.
Создадим необходимое нам виртуальное устройство.
Для начала нам нужно дать нашему пользователю возможность беспарольного обращения к системным командам. Для этого добавим в sudoers:
Cmnd_Alias QEMU = /sbin/ifconfig, /sbin/modprobe, /usr/sbin/brctl, /usr/sbin/tunctl, /sbin/sysctl, /bin/ip, /usr/bin/cgcreate, /usr/bin/cgdelete, /sbin/tc
username ALL=(ALL:ALL) NOPASSWD: QEMU
Включим возможность форвардинга и проксирования arp-запросов:
sudo sysctl net.ipv4.conf.all.forwarding=1
sudo sysctl net.ipv4.conf.all.proxy_arp=1
Также можно добавить эти параметры в /etc/sysctl.conf и применить их:
Создадим виртуальную сетевую карту и поднимем устройство:
sudo tunctl -b -u username -t debian_guest
sudo ifconfig debian_guest 0.0.0.0 up
Создадим маршрут на нужное нам устройство с нужного IP-адреса:
sudo ip route add 10.10.10.100 dev debian_guest
Теперь можно запустить VDS:
$ virsh start debian_guest
Подключившись к консоли, мы увидим, что сети нет, но у нас появилось устройство eth1, вместо eth0. Это произошло потому, что система при загрузке в /etc/udev/rules.d/70-persistent-net.rules прописывает mac-адрес сетевой карты, и если mac сменился, она создаёт ещё одну запись о сетевой карте, вроде этой:
SUBSYSTEM==»net», ACTION==»add», DRIVERS==»?*», ATTR
==»xx:xx:xx:xx:xx:xx», ATTRНужно удалить этот файл и перезагрузить VDS — после этого сетевая карта определится корректно.
Пропишем новые сетевые настройки в гостевой системе:
# ifconfig eth0 10.10.10.100 netmask 255.255.255.0
# route add default gw 10.10.10.10
10.10.10.10 — это IP-адрес хост-системы. Теперь мы сможем попинговать другие машины.
Добавим DNS-серверы в /etc/resolv.conf, и будет совсем замечательно:
К слову, замечу, что оказалось очень удобно называть сетевые устройства, принадлежащие VDS, также, как и сами VDS — отпадает необходимость искать, кому принадлежит устройство tap0 или vnet0, или как там ещё можно их обозвать.
Если понадобится выдать виртуальной машине ещё один IP-адрес, достаточно будет просто на хост-машине прописать ещё один маршрут:
# ip route add 10.10.10.101 dev debian_guest
А в гостевой системе создать алиас для сетевого устройства:
# ifconfig eth0:1 10.10.10.101
В следующей части
В следующей статье я расскажу о том, как создать образ VDS, что вообще меняется от системы к системе, и как эти параметры можно удобно менять.