Глава 6. Виртуальные машины KVM
Содержание
На текущий момент мы познакомились с графическим интерфейсом пользователя Proxmox, файлами настройки, а также структурой каталога. Мы также изучили различные типы поддерживаемых Proxmox хранилищ и то, как их интегрировать в кластер. В этой главе мы собираемся сделать шаг вперёд и рассмотреть KVM ( Kernel-based Virtual Machine ) и всё, что они должны предложить. Мы собираемся рассмотреть следующие темы:
Обзор виртуальных машин KVM
Создание виртуальных машин KVM
Настройку виртуальных машин KVM
Миграцию виртуальных машин KVM
Встраиваемые виртуальные среды
Систему резервного копирования/ восстановления Proxmox
Моментальные снимки виртуальных машин
Обзор KVM
Создание KVM
В Proxmox мы можем создавать ВМ KVM следующими способами:
Из рабочей области с применением ISO
Применяя загрузку PXE
В этой главе мы намереваемся рассмотреть только создание ВИ из образов ISO и шаблонов.
Создание KVM с помощью образа ISO
Рисунок 6-1

Рисунок 6-2

Закладка General
Закладка General предназначается главным образом для определения идентификационной информации. Давайте взглянем на неё.
Это ниспадающий список для выбора того, на каком из узлов Proxmox следует создать данную ВМ.
Этот текстовый блок применяется для ввода численного идентификатора данной ВМ. Мы также можем увеличивать или уменьшать текущее значение VM ID применяя стрелки. Если вы назначили некий идентификатор, который уже имеется в данном кластере, текущий блок отобразит красное окаймление, указывающее что уже имеется некая ВМ с тем же самым идентификатором.
Кнопка Help откроет новую закладку с установленной документацией, созданной разработчиками Proxmox. Данная документация содержит специфичную информацию, относящуюся к данной закладке. Каждая кнопка Help в различных закладках закреплена за определённым разделом имеющейся документации. URL данной документации является https://ip_addr:8006/pve-docs/chapter-qm.html.
Закладка OS
Рисунок 6-3

Для достижения максимальных производительности и надёжности настоятельно рекомендуется выбирать соответствующий тип ОС.
Закладка CD/DVD
Рисунок 6-4

Закладка Hard Disk
В этой закладке мы определяем все настройки для своего самого первого образа диска ВМ. Снимок экрана ниже показывает блок диалога с настройкой для нашего примера ВМ.
Рисунок 6-5

Для данной опции доступно два ниспадающих меню. Одно для выбора disk image bus type (типа шины образа диска) и другое для device ID (идентификатора устройства).
Для максимальной производительности рекомендуется шина VirtIO.
Для ВМ Windows необходимо выбирать IDE, поскольку Windows не имеет встроенного драйвера для VirtIO. В подобных случаях нам мы можем воспользоваться следующими шагами для добавления возможностей VirtIO в ВМ Windows:
Создайте необходимую ВМ с IDE и установите Windows обычным образом.
Добавьте второй дисковый образ с требуемой шиной VirtIO и перезагрузитесь в Windows.
Выгрузите самый последний драйвер VirtIO для Windows со следующих ссылок и затем загрузите его через виртуальный диск CD:
Обновите соответствующий драйвер для вновь обнаруженного оборудования под устанавливаемый образ диска VirtIO.
Погасите свою ВМ Windows и зарегистрируйтесь в своей инструментальной панели Proxmox.
Рисунок 6-6

Рисунок 6-7

В этом блоке диалога мы можем выбрать желаемый тип шины и прочие варианты настроек, если они требуются.
Кликните по кнопке Add для добавления соответствующего образа диска обратно в эту ВМ.
Перечисленные шаги нужны для включения в вашей ВМ Windows использования образа диска VirtIO. Раз соответствующий драйвер уже загружен, нт необходимости загружать его для дополнительных образов дисков VirtIO.
Это ниспадающее меню для выбора соответствующего хранилища, в котором должен сохраняться необходимый образ диска. Одновременно с названием такого хранилища данное ниспадающее меню также отображает общую ёмкость и доступное пространство хранения для подключаемых устройств хранения.
Это текстовый блок для определения необходимого размера данного устройтва хранения в ГБ. Его значение может бвть только численным. Мы также можем применять стрелки данного текстового блока вверх и вниз для определения требуемого размера диска.
Если мы выбрали необходимый формат образа диска неверно или позднее наши требования изменились на другой формат, мы можем просто воспользоваться вариантом Move disk в соответствующей закладке Hardware для изменения соответствующего формата. Это также можно сделать применив CLI воспользовавшись следующим форматом:
Данная команда великолепно работает для локального хранилища и хранилищ NFS, ZFS и Gluster, однако не применима для RBD. Для изменения соответствующего формата образа диска, хранимого в RBD, воспользуйтесь опцией Move disk в своей инструментальной панели Proxmox. Помимо хранимого в RBD образа диска данный вариант Move disk может быть применён для перемещения любого образа диска хранимого в любом хранилище через имеющийся GUI вообще без применения какого- либо CLI. Этот вариант также полезен для перемещения образа диска с одного хранилища на другое без отключения соответствующей ВМ. Перемещение можно выполнять с локального хранилища на совместно используемое и наоборот. Для перемещения образа диска или изменения его формата выберите необходимый образ диска в соответствующей закладке Hardware и кликните по Move disk для открытия блока диалога:
Рисунок 6-8

Данное ниспадающее меню позволяет нам выбирать требующийся метод кэширования, применяемый для данного образа диска. Мы уже изучили различные варианты кэширования в разделе Кэширование образа виртуального диска Главы 4, Системы хранения. Мы можем изменять необходимый вариант кэширования в любое время, даже после того, как наша ВМ полностью создана и находится в рабочем состоянии. После каждого изменения варианта кэширования нам потребуется цикл отключения- включения данной ВМ для разрешения нового варианта кэширования.
Если включена данная опция, соответствующий образ виртуального диска никогда не будет включаться в резервное копирование. По умолчанию данная опция отключена.
Рисунок 6-9

Опция Discard может быть не применимой в некоторых средах, решениях хранения и операционных системах. Проведите исчерпывающее тестирование прежде чем реализовывать её в своей среде. В некоторых случаях данная опция Discard может вызывать блокирование ВМ, что потребует цикла выключения- включения. Сама ВМ потребует цикла выключения- включения чтобы разрешить эту опцию после повторного включения.
Для образов диска в KVM имеется два варианта:
По умолчанию Proxmox применяет io=native для всех образов дисков пока имеющаяся опция IO thread специально не отмечается для определённого диска.
Такая опция IO thread позволяет каждому образу диска иметь свои собственные потоки вместо ожидания в очереди с кем- нибудь ещё. Так как дисковый ввод/ вывод больше не осуществляет ожидания, поскольку имеет свои собственные потоки, он не задерживает прочие задачи или очереди, относящиеся к этой ВМ, что в свою очередь ускоряет общую производительность этой ВМ помимо всего прочего, предоставляя увеличенную производительность диска. Эта опция IO thread является относительно новой в Proxmox. Имеется несколько экземпляров сообщений, в которых из- за данной опции происходила блокировка ВМ. Таким образом, проводите тщательное тестирование прежде чем реализуете эту функцию в некоторой промышленной среде.
Закладка CPU
данная закладка позволяет настраивать виртуальные ЦПУ для виртуальных машин. Приводимый далее экранный снимок отображает блок диалога с доступными опциями ЦПУ:
Рисунок 6-10

Эта опция служит для определения общего числа сокетов, которое может применяться в данной ВМ. Для определённой ВМ мы можем использовать более одного сокета даже если её физический узел не имеет достаточного числа сокетов. Это может быть полезным только в том случае, если некое приложение в этой ВМ требует от нас более одного сокета. Но это вовсе не играет в пользу увеличения производительности ВМ в машине с единственным сокетом.
Данная опция служит для определения общего числа ядер, которое может применять данная ВМ. Хорошим практическим приёмом является начало применения какой- то ВМ с меньшим числом ядер и затем последовательно увеличивать их по мере необходимости в зависимости от нагрузки. Выделение большого числа ядер некоторой ВМ вызовет ненужную нагрузку на все доступные ресурсы в данном узле. Обычно некая ВМ может предоставлять хорошую производительность с двумя или четырьмя ядрами если только она не является ВМ с высокими запросами, такими как сервер удалённых рабочих мест или сервер SQL/ Exchange.
Любой узел с более чем одним сокетом обычно осведомлён об NUMA. Следовательно, включение NUMA для ВМ в таком узле привнесёт преимущества в производительность ВМ. NUMA всегда пытается удерживать определённую ВМ в одном и том же пакете ЦПУ. Мы можем проверять текущее состояние NUMA в своём кластере Proxmox с применением такой команды:
Эта команда отобразит все те узлы в вашем кластере, которые осведомлены о NUMA, а также их состояния производительности.
Для получения наилучшей производительности следует применять тип хоста. Тем самым ваши ВМ будут способны осуществлять прямой доступ к имеющимся ЦПУ без какого бы то ни было уровня эмуляции. Именно это является оптимальным видом для некоторой среды, в которой все узлы являются идентичными. Для получения максимальной переносимости какой- то ВМ следует выбирать типы ЦПУ KVM или Qemu.
Закладка Memory
Эта закладка позволяет настраивать выделение оперативной памяти определённой ВМ. Приводимый ниже моментальный снимок экрана отображает блок диалога для нашего примера ВМ:
Рисунок 6-11

В Proxmox мы можем устанавливать для ВМ фиксированную или динамическую оперативную память. Автоматический диапазон также именуется как раздувание (ballooning) памяти. При установленном варианте с фиксированной памятью вся оперативная память выделяется одномоментно. При установке динамической памяти оперативная память выделяется на основе требований ВМ, но в рамках установленного диапазона. Автоматическое выделение памяти великолепно работает вВМ Linux, однако для ВМ Windows раздувание памяти потребляет боле высокие объёмы ресурсов ЦПУ, что вызывает замедление такой ВМ. Таким образом, для ВМ Windows рекомендуется везде где это возможно применять фиксированную память.
Закладка Network
Данная закладка делает возможной настройку текущего виртуального сетевого интерфейса для определённой ВМ. Приводимый далее снимок экрана отображает блок диалога настройки сети для нашего примера ВМ:
Рисунок 6-12

Чтобы разрешить межсетевой экран для сетевых интерфейсов следует пометить данную опцию. Без данной опции никаие правила межсетевого экрана не будут применяться к данному интерфейсу ВМ. Более подробно мы рассмотрим имеющийся межсетевой экран Proxmox в Главе 9, Межсетевой экран Proxmox VE.
Это режим предоставляет ВМ прямой доступ ко внешним сетевым средам. Сентевой обмен не пропускается ни через какие мосты. Если в данной сетевой среде применяется VLAN, он должен быть настроен внутри такой ВМ чтобы иметь все пакеты данных помеченными или не помеченными. Опция межсетевого экрана Proxmox не доступна при использовании режима NAT.
Данный вариант создаст определённую ВМ без каког бы то ни было настроенного сетевого интерфейса.
Это ниспадающее меню для выбора типа интерфейса виртуальной сетевой среды. Для максимальной сетевой производительности настоятельно рекомендуется применение VirtIO. Windows не поставляется с каким бы то ни было драйвером VirtIO. Следовательно, если он применяется к ВМ Windows, нам следует вручную загрузить этот драйвер из ISO, который мы выгрузили в разделе Закладка Hard Disk этой главы. Для ВМ Windows мы также можем воспользоваться Intel E1000. Начиная с Windows 7 и выше этот драйвер для Intel включён в поставку.
По умолчанию все MAC адреса для виртуальных сетевых интерфейсов назначаются автоматически. Набрав некий MAC адрес в данном текстовом блоке мы можем определить конкретный MAC адрес для данного интерфейса. Это может быть полезным в случае, когда определённому приложению в данной гостевой ВМ требуется какой- то специфический MAC адрес.
Именно этот текстовый блок служит для определения максимально допустимой скорости сетевого интерфейса, определяемой в Мегабайтах в секунду. Это очень полезная опция для ограничения сетевых ресурсов в ВМ. Без установки какого бы то ни было значения данная ВМ будет пытаться использовать максимальную доступную полосу пропускания.
Имейте в виду, что Множественные очереди также увеличивают использование ЦПУ данной ВМ, так как каждая очередь находится в зависимости от каждого vCPU.
Если включена данная опция, определяемый виртуальный сетевой интерфейс будет создан совместно с данной ВМ, однако не будет активирован.
Создание ВМ клонированием
При развёртывании множества ВМ с идентичными настройками их индивидуальное создание может стать временеёмким процессом. В данном случае мы можем клонировать некую имеющуюся ВМ или какой- то шаблон. Клонирование создаёт полностью независимую ВМ с идентичной конфигурацией. Такая клонированная ВМ ни коим образом не связана с той ВМ из которой она клонирована. К такой опции клонирования можно получить доступ из меню контекста кликнув правой кнопкой по той ВМ, которая подлежит клонированию:
Рисунок 6-13

Одним из вариантов применения клонирования является некая стратегия резервного копирования. Какая- то ВМ может клонироваться в отдельные узлы, и даже в отдельную систему хранения, на постоянной основе. В случае возникновения события, при котором её основной узел становится недоступным, такая клонированная ВМ может быть поднята и запущена за считанные минуты без какой либо необходимости осуществления процесса восстановления. Следующий моментальный снимок отображает блок диалога подобного клонирования после клика по Clone в меню имеющегося контекста:
Рисунок 6-14

Создание ВМ из шаблона
Аналогично клонированию некий шаблон также является быстрым способом развёртывания полностью настроенных ВМ без прохождения через процесс полного создания ВМ и установки вручную ОС и приложений. Мы можем создать некую новую ВМ и установить необходимые ОС и прочие необходимые программы перед их преобразованием в какой- то шаблон. Таким образом, все вновь создаваемые из данного шаблона ВМ будут с полностью настроенными ОС и программами. Что устанавливает отличие шаблона от простого клонирования, так это то, что после преобразования какой- то ВМ в шаблон она не может быть вновь включена. Если для данного шаблона ВМ требуются какие- либо изменения, необходимо создать новую ВМ, настроить её и затем преобразовать в шаблон. Однако, мы можем изменять имеющиеся аппаратные ресурсы конкретного шаблона. Основным преимуществом применения шаблона в сравнении с клонированными ВМ состоит в том, что шаблон допускает для нас как создание полностью клонированных ВМ, так и ВМ с присоединённым клоном.
для создания ВМ из какого- то клона нам потребуется вначале создать такой шаблон. Мы можем выполнить это преобразовав некую настроенную ВМ в шаблон. Для данного варианта мы можем пойти путём выбора необходимой ВМ с последующим кликом по ней правой кнопкой и выбором Convert to template для открытия блока диалога:
Рисунок 6-15

Рисунок 6-16

Рисунок 6-17

Узел назначения
Это ниспадающее меню для выбора того, в каком узле мы желаем создать клонированную ВМ. Это может быть тот же самый узел или любой другой узел в данном кластере с достаточными ресурсами.
Режим
В Proxmox 5.0 имеются два режима клонирования:
Full Clone (Полное клонирование)
Linked Clone (Присоединённое клонирование)
Полное клонирование создаёт идентичную копию данной ВМ, включая её образ виртуального диска. Это действительно изолированная ВМ, так как она никоим образом не зависит от своего шаблона или ВМ источника. Даже если мы удалим сам шаблон или ВМ источника, наша вновь созданная ВМ всё ещё будет работать без каких- то проблем. Full Clone потребляет столько же пространства хранения, сколько и его первоначальная ВМ, так как его виртуальный диск также клонируется. Полные клоны полезны когда выделяемые ресурсы идентичны для всех оснащаемых ВМ, однако гостевые операционные системы могут отличаться, а могут и быть теми же самыми.
Присоединённый клон создаёт некий дубликат первоначальной ВМ за вычетом самого первоначального образа виртуального диска. Это создаёт некий дополнительный пустой образ диска, который ссылается на свой первоначальный виртуальный диск, причём в такой присоединённый образ клонированного диска помещаются только новые данные. Все запросы на чтение, за исключением касающихся новых данных, автоматически перенаправляются в его первоначальный образ диска. Linked Clone существенным образом зависит от своего шаблона или ВМ источника. Такой режим клонирования полезен в том случае, когда все клонированные ВМ будут иметь в точности те же самые конфигурации оборудования и программного обеспечения, в том числе и гостевую операционную систему. Linked Clone потребляет намного меньше пространства хранения, так как первоначальный или базовый образ никогда не дублируется, а всего лишь применяется в качестве ссылки в получаемом новом Присоединённом клоне ВМ.
Хотя мы и не можем включить имеющийся шаблон, мы всё ещё можем производить изменения его ресурсов, такие как ЦПУ или Оперативная память. Однако это не рекомендуется при практическом применении, так как любое изменение оборудования может создавать проблемы при включении какой- то клонированной ВМ. Также очень важно гарантировать, что получаемый шаблон источника никоим образом не разрушается. Любое нарушение шаблона вызывает отказ всех присоединённых клонов.
Расширенные параметры настройки для ВМ
Теперь мы рассмотрим некоторые дополнительные варианты настройки, которые мы можем применять для расширения имеющихся возможностей виртуальных машин KVM.
QEMU-KVM и NUMA-архитектура
Кратко о NUMA-архитектуре.
Представьте себе довольно типичный двух-процессорный сервер. Можете представить четырех-процессорный, это не принципиально, главное что бы соккетов было больше одного, иначе эта статья для вас не актуальна)
Так вот, у каждого процессора(не ядра а именно процессора), есть встроенный контроллер памяти(либо он совсем близко) и подключенный через него банк памяти к которому у этого процессора есть максимально быстрый доступ. Это собственно и есть NUMA-нода №0.
У других процессоров(при наличии таковых) так же есть встроенный контроллер и «локальная» память и это такие же NUMA-ноды №N в рамках одного сервера.
Проблема NUMA в том, что доступ процессора из ноды 0 к памяти ноды 1 в два раза медленнее чем к своей, локальной памяти.
Так же, обращаясь к памяти из другой ноды, процессор выполняет в два раза больше тактов чем обращаясь к своей памяти.
Кроме этого, общий кеш процессора 2-го и 3-го уровней, становится менее эффективен если процесс выполняется на процессорах нескольких нод.
В общем, в идеале, каждый из процессов должен выполняться в рамках одной какой то ноды и не «прыгать» между ними.
Вот сервер с двумя NUMA-нодами:
QEMU и NUMA. Как это работает по умолчанию
pid=13622 — ВМ 1CPU4Gb. использована вся память(внутри ВМ).
pid=14477 — ВМ 1CPU4Gb. без нагрузки
Здесь, у виртуалок всего по одному ядру но при этом память размазана по двум нодам.
Дело в том, что vCPU QEMU это процесс ОС и он периодически выполняется на разных физических ядрах(тут как карта ляжет). Таким образом, ОС распределяет всю вычислительную нагрузку по всем ядрам системы.
Память же, выделяется на той ноде на процессоре которой в данный момент выполняется процесс, в итоге получается вот такая печальная картина.
И это еще маленькие виртуалки на совершенно пустой ноде!
статистика для всех процессов в системе:
Что можно сделать?
Можно привязывать vCPU к физическим ядрам на одной ноде, что приведет к выделению памяти на этой же ноде. Но это требует сложной логики и некого внешнего механизма(скрипта) который будет выполнять привязку средствами cgroups или утилиты numactl.
Есть более простой путь, привязывать виртуалки к нодам а не к ядрам.
Привязать процесс к определенной ноде можно примерно так:
В результате получаем виртуалку чей процесс а так же его треды и все что она может породить помещенную в одну ноду:
Есть еще более простой путь, использовать numad.
Это демон, который появился в RHEL 6.3 для решения обсуждаемых здесь проблем и особенно эффективен в контексте виртуализации.l
numad старается максимально эффективно распределять жирные процессы по нодам. В низах использует /cgroup/cpuset/….
Конечно, с очень большими виртуалками это особо не поможет, но зато кучу тех что по меньше разбалансирует и тем самым немного повысит производительность и снизит накладные расходы на обслуживание ВМ.
Про KSM
Вот тут все написано тут.
If KSM is in use on a NUMA system, change the value of the /sys/kernel/mm/ksm/merge_nodes parameter to 0 to avoid merging pages across NUMA nodes. Otherwise, KSM increases remote memor accesses as it merges pages across nodes. Furthermore, kernel memory accounting statistics can eventually contradict each other after large amounts of cross-node merging. As such, numad can become confused about the correct amounts and locations of available memory, after the KSM daemon merges many memory pages. KSM is beneficial only if you are overcommitting the memory on your system. If your system has sufficient free memory, you may achieve higher performance by turning off and disabling the KSM daemon.
Тесты
Для теста использовалась ВМ m1.xlarge(3CPU11Gb) с CentOS 6.
На неё была установлена БД Redis а нагрузка генерировалась с помощью redis-benchmark со следующими параметрами:
Данный тест приводит к 100% утилизации всех трех ядер и памяти ВМ!
Результаты теста без numad:
====== SET ======
10000000 requests completed in 167.83 seconds
59582.68 requests per second
====== GET ======
10000000 requests completed in 136.58 seconds
73216.09 requests per second
Результаты теста с numad:
====== SET ======
10000000 requests completed in 146.33 seconds
68339.16 requests per second
====== GET ======
10000000 requests completed in 130.54 seconds
76607.22 requests per second
Результаты теста с numad и с выключенным hyper threading(чисто ради интереса):
====== SET ======
10000000 requests completed in 208.99 seconds
47849.64 requests per second
====== GET ======
10000000 requests completed in 140.59 seconds
71130.33 requests per second
Все таки включенный hyper threading дает заметный прирост.



