Ни для кого не секрет, что в Windows Server 2016 появилась вложенная виртуализация Hyper-V. Несмотря на то, что на момент написания статьи доступна лишь версия Technical Preview 5, уже в ней можно очень близко познакомиться с новым функционалом, о котором я и постараюсь коротко рассказать в этой статье.
Хочу отметить, что все сказанное относится к предрелизной версии и может сильно отличаться от официального релиза.
Если вам интересна тематика Windows Server, рекомендую обратиться к тегу Windows Server на моем блоге.
Содержание
Вложенная виртуализация Hyper-V
Функция вложенной виртуализации в гипервизорах разных производителей доступна достаточно давно. Например у VMWare поддержка 64х-битных вложенных виртуальных машин была реализована в версии ESXi 5.1 и это было аж в 2011 году, не говоря о поддержке 32х-битных вложенных ОС, доступных ещё ранее. Другие вендоры также не отставали. Тем не менее, у Microsoft мы не могли увидеть такого функционала до сегодняшнего дня. Почему? Официального ответа мне найти не удалось, но можно говорить как об общей позиции (неприоритетная на то время задача), так и о чисто логических рассуждениях – в 2008 году с выходом Windows Server 2008 и последующей 2008 R2 говорить о вложенной виртуализации было не совсем актуально, ведь гипервизор был ещё во многом сыроват по многим направлениям (например max. vCPU упиралось в 4 шт.), а ситуация с конкурентами была такова, что Microsoft по сути вынужден был активно их догонять.
Архитектура
Классическая виртуализация первого типа представляет из себя гипервизор, разграничивающий доступ к оборудованию между единственным родительским и множеством гостевых разделов. При этом доступен только один уровень виртуализации – Level 1 – и использование вложенных виртуальных машин (VM внутри VM) не подразумевается. В общем виде архитектура выглядит следующим образом 1:
Раньше попытка развернуть роль Hyper-V внутри виртуальной машины непременно заканчивалась ошибкой:
Так происходило потому, что гипервизор намеренно маскировал от гостевых ОС наборы аппаратных инструкций (Virtualization Extensions), отвечающих за виртуализацию 2 – Intel VT-x и AMD-V (все мы помним, что Hyper-V – это система именно аппаратной виртуализации и без поддержки функционала со стороны “железа” работать не будет).
Теперь же архитектура изменилась таким образом, что появилась возможность передачи наборов аппаратных инструкций в гостевые ОС (по умолчанию этот функционал отключен):
Все это открывает возможности для вложенной виртуализации, которая при этом не ограничена вторым уровнем (Level 2 на рис. вверху).
Но как и у любой свежей технологии (в данном случае свежей именно для Microsoft), у неё есть некоторые ограничения, о которых ниже.
Ограничения
Условно можно разделить на аппаратные и программные.
Аппаратные
Аппаратные ограничения упираются в обязательную поддержку процессором Intel технологий VT-x 3 и EPT. Если наличие VT-x было стандартным требованиям и для ранних версий Hyper-V, то необходимость в EPT появилась только сейчас и только для вложенной виртуализации 4:
И я ничего не забыл, не написав про процессоры AMD. Дело в том, что в Windows Server 2016 TP5 вложенная виртуализация на процессорах AMD пока что не поддерживается.
Программные
Программных ограничений значительно больше:
- Использование Windows Server 2016 или Windows 10 как в родительском, так и в гостевых разделах;
- Виртуальная машина с версией конфигурации 8.0 и выше;
Для вложенных виртуальных машин не поддерживается:
- Динамическая память;
- Динамическая миграция;
- Снимки виртуальных машин и состояния Save/Restore;
Важно помнить, что если вы собрались выпускать вложенные виртуальные машины во внешнюю сеть, то на виртуальном адаптере “хостовой” виртуальной машины будет поднят виртуальный свитч и на нем будут несколько виртуальных сетевых адаптеров, а значит несколько MAC-адресов, а значит надо включать спуфинг MAC-адресов на адаптере. Это тоже в некотором смысле ограничение.
Есть и обходной вариант – использовать NAT (это тоже новый функционал, о котором расскажу ниже).
Применение
У тех, кто встретился с вложенной виртуализацией впервые, может возникнуть вопрос об области её применения. Остановимся на этом более подробно.
Наиболее адекватными сценариями представляются тестирование и разработка. В продакшене вы конечно можете использовать полностью вложенную виртуальную инфраструктуру, но непременно столкнетесь с падением производительности вложенных экземпляров.
Мне стало интересно проверить на реальной среде падение производительности ЦП внутри виртуальных машин разной степени вложенности. Для этого я использовал Hot CPU Tester Pro. Хоть и тестирование получилось исключительно субъективное, но оно как минимум намекает на существенное падение отдачи CPU:
Моего терпения хватило только для развертывания экземпляра третьей вложенности.
Настройка
Для возможности использовать вложенную виртуализацию, необходимо выполнить ряд настроек на хостовой ОС. Приступаем.
Обновление версии VM
Если по каким-либо причинам ваша виртуальная машина имеет версию конфигурации ниже 7.1 (например она смигрировала на ваш Hyper-V с предыдущих версий Technical Preview), то обязательно обновляем конфигурацию вручную, нажав правой кнопкой по VM и выбрав Обновить версию конфигурации:
Или через Powershell:
1 |
Update-VMVersion -Name "vm_name" |
Последний вариант удобен при массовом обновлении виртуальных машин. Обновить все VM враз можно командой Get-VM | Update-VMVersion.
Активирование вложенной виртуализации
По умолчанию гипервизор все также маскирует аппаратные наборы инструкций, отвечающих за виртуализацию, не передавая их гостевым ОС, как я и упоминал ранее. Чтобы изменить это поведение, необходимо выполнить команду:
1 |
Set-VMProcessor -VMName VMName -ExposeVirtualizationExtensions $true |
Изменение опции ExposeVirtualizationExtensions доступно только через Powershell.
Спуфинг MAC-адресов / NAT
Если вы планируете настроить сеть вложенных виртуальных машин таким образом, чтобы все они находились в реальной локальной сети, то на одном единственном сетевом адаптере “хостовой” виртуальной машины будут висеть несколько MAC-адресов. Это ожидаемо вызовет проблемы со связью, если не активирована настройка Включить спуфинг MAC-адресов (а она не активирована по умолчанию).
Ставим галочку вручную:
Или через Powershell:
1 |
Get-VMNetworkAdapter -VMName "vm_name" | Set-VMNetworkAdapter -MacAddressSpoofing On |
Если же вы не планируете выпускать вложенные VM в локальную сеть, но все же хотите обеспечить их возможностью коммуникаций по сети, можно поднять NAT 7. Для этого необходимо создать виртуальный коммутатор внутреннего типа командой (на данный момент настройка NAT возможна только через Powershell):
1 |
New-VMSwitch -Name "NAT 01" -SwitchType Internal |
Создаем NAT:
1 |
New-NetNat -Name "name" –InternalIPInterfaceAddressPrefix 'ip-address/netmask' |
Обратите внимание, что на этом этапе нужно определиться с подсетью, которая будет использоваться за NAT-ом. Разумеется диапазон адресов не должен пересекаться с реальными диапазонами в вашей локальной сети.
Назначаем адрес для интерфейса:
1 |
Get-NetAdapter "name" | New-NetIPAddress -IPAddress ip_address -AddressFamily IPv4 -PrefixLength number |
На этом шаге внутреннему интерфейсу нужно присвоить адрес, который будет использоваться вложенными виртуальными машинами как шлюз. Конструкция команд, используемая на скриншоте выше, совсем необязательна, вы можете обойтись и без Get-NetAdapter 8, указав командлету New-NetIPAddress 9 индекс сетевого интерфейса (поле ifIndex). В этом случае моя команда выглядела бы таким образом: New-NetIPAddress -IPAddress 172.16.0.1 -AddressFamily IPv4 -PrefixLength 24 -InterfaceIndex 9.
Ну а теперь дело за малым: сконфигурируем сеть на вложенной виртуальной машине:
И проверим связь с внешним миром:
Переходим к последнему этапу.
Отключение динамической памяти
Динамическая память для виртуальных машин, внутри которых будет развернута роль Hyper-V, не поддерживается, а потому позоботьтесь о том, чтобы она была полностью отключена. Сделать это можно через консоль Hyper-V:
Или через Powershell командой:
1 |
Set-VMMemory "vm_name" -DynamicMemoryEnabled $false |
На этом базовая подготовка виртуальной машины для использования вложенной виртуализации завершена и можно переходить к установке роли Hyper-V внутри VM. Этот процесс ничуть не отличается от обычной подготовки хоста, поэтому подробно рассматривать его я не собираюсь, только для большей убедительности покажу скриншот получившегося чуда:
Разумеется все те настройки, которые вы проводили на хосте, чтобы запустить вложенные виртуалки, нужно выполнять и внутри самих виртуалок, если вы планируете использовать вложенную виртуализацию на них.
Notes:
- Windows Insider Preview: Nested Virtualization ↩
- Поддержка вложенной виртуализации (Nested Virtualization) в Hyper-V ↩
- VT-x ↩
- http://ark.intel.com/ ↩
- Аппаратная виртуализация в процессорах Intel и AMD – технологии для ускорения виртуальных машин. ↩
- Upgrade virtual machine version in Hyper-V on Windows 10 or Windows Server 2016 ↩
- Настройка сети NAT ↩
- Get-NetAdapter ↩
- New-NetIPAddress ↩