«Любишь Hyper-V – люби и PowerShell»
Первое правило Сообщества Hyper-V в Телеграм
«А если любишь VMware ESXi, то люби PowerShell на пару с ESXi CLI и REST API»
Дополнено мной
Живая миграция (live migration) – популярная функция в Hyper-V. Она позволяет переносить работающие виртуальные машины без видимого простоя. В сети много инструкций по переносу ВМ, но многие из них устарели. Вдобавок не все заглядывают в расширенные настройки и правильно используют возможности Live Migration.
Я собрал нюансы и неочевидные параметры для быстрого переноса ВМ внутри кластера и между кластерами. Заодно поделюсь маленькими секретами в настройке и проектировании. Надеюсь, статья будет полезна начинающим админам.
Как обычно происходит миграция ВМ с одного узла на другой внутри кластера Hyper-V:
Это и называется живой миграцией. Схема справедлива для любого гипервизора.
Чем больше оперативной памяти у ВМ и чем интенсивнее она изменяется, тем дольше будет переезд. Поэтому трафик живой миграции требует хорошего канала и тщательной настройки.
Разберем основные нюансы по настройке интерфейсов.
Как было раньше. Старые мануалы по переносу ВМ Hyper-V описывают сценарии с использованием технологии тиминга Load Balancing/Fail Over (LBFO). LBFO позволяла группировать физические сетевые адаптеры и создавать поверх них интерфейсы. Но были и минусы, например: не было поддержки RDMA, нельзя было выяснить, через какой порт тима будет идти трафик. А поскольку трафик живой миграции требует довольно жирного канала, это превращалось в проблему, когда все сетевые ворклоады ломились в один физический порт.
Как сейчас. В Windows Server 2019 даже нельзя создать виртуальный свитч поверх LBFO Team. Единственным поддерживаемым решением для объединения портов сетевой карты в Hyper-V остался Switch Embedded Team (SET).
SET агрегирует адаптеры, как и vSwitch у ESXi. Физические сетевые порты становятся патч-кордом для разных типов трафика (в том числе для ВМ), а поверх них нарезаются виртуальные интерфейсы.
В новых версиях SET позволяет создавать разные виртуальные интерфейсы для разных нагрузок поверх группы физических интерфейсов. По сути, это виртуальные сетевые адаптеры корневого раздела, которыми мы можем управлять наподобие виртуальных адаптеров ВМ.
Как это влияет на процесс настройки. В Hyper-V, помимо менеджмент-интерфейса, мы обычно создаем интерфейсы для живой миграции и интерфейсы для CSV-трафика кластера. Для этого нам нужно знать количество сетевых портов, входящих в SET, – именно столько виртуальных интерфейсов нужно будет создать. Также учитываем расположение сетевых портов на PCI-шине, количество сокетов для последующего маппинга интерфейсов по NUMA-нодам и количество физических ядер на каждом процессоре.
Посмотрим на процесс пошагово
Со стороны Failover Cluster дополнительно выкрутим настройки таймаутов кластера:
Для высоконагруженных машин важно выкрутить оба параметра. Если не уложимся, то с большой вероятностью такая машинка не переедет.
Чтобы трафик живой миграции использовался только на определенной сети, также оставим отдельную сеть в настройках Failover Cluster:
Собственно, это и есть минимальный джентльменский набор настроек для корректной работы Live Migration в Hyper-V.
Первое правило Сообщества Hyper-V в Телеграм
«А если любишь VMware ESXi, то люби PowerShell на пару с ESXi CLI и REST API»
Дополнено мной
Живая миграция (live migration) – популярная функция в Hyper-V. Она позволяет переносить работающие виртуальные машины без видимого простоя. В сети много инструкций по переносу ВМ, но многие из них устарели. Вдобавок не все заглядывают в расширенные настройки и правильно используют возможности Live Migration.
Я собрал нюансы и неочевидные параметры для быстрого переноса ВМ внутри кластера и между кластерами. Заодно поделюсь маленькими секретами в настройке и проектировании. Надеюсь, статья будет полезна начинающим админам.
Дисклеймер: Все описанные шаги желательно сделать ДО ввода сервера Hyper-V в прод. Hyper-V никогда не прощает ошибок проектирования и подведет вас при первом удобном случае. То есть уже на следующий день.
Вспоминаем матчасть
Как обычно происходит миграция ВМ с одного узла на другой внутри кластера Hyper-V:
- Конфигурация ВМ копируется с одного узла кластера на другой.
- Страницы памяти виртуальной машины помечаются для копирования на целевой хост, и начинается процесс их перемещения в режиме онлайн.
- Поскольку виртуальная машина все еще работает, страницы памяти постоянно меняются. Во время миграции Hyper-V отслеживает измененные страницы памяти и переносит их на другой хост. Процесс повторяется до тех пор, пока на первом узле кластера не останется только несколько измененных страниц.
Копирование страниц памяти с одного узла на другой и их синхронизация. - ВМ на исходном хосте выключается, оставшиеся страницы памяти копируются на целевой хост, и виртуальная машина на нем включается. Переключение происходит за доли секунды. Процесс достаточно быстрый, чтобы ни один клиент не заметил простоя.
Это и называется живой миграцией. Схема справедлива для любого гипервизора.
Чем больше оперативной памяти у ВМ и чем интенсивнее она изменяется, тем дольше будет переезд. Поэтому трафик живой миграции требует хорошего канала и тщательной настройки.
По такой схеме работает классическая живая миграция внутри Failover Cluster. Для нее нужен общий том CSV, поданный всем хостам кластера.
Помимо этого есть второй вид Live Migration, живая миграция в режиме «ничего общего» (Shared-Nothing Live Migration). Этот сценарий обычно используется для миграции ВМ без простоя между кластерами. Помимо страниц памяти с одного хоста Hyper-V на другой копируется диск VHD(X) с переносом и синхронизацией дельты данных, записанных на него.
Разберем основные нюансы по настройке интерфейсов.
Задаем настройки протоколов
- Для начала зайдем в Hyper-V manager и откроем правым кликом настройки Hyper-V. В настройках Live Migration укажем адреса сетевых интерфейсов, к которым будет обращаться гипервизор:
- Заглянем в Advanced features. Нас интересуют оба пункта: протокол аутентификации и транспорт, который используют наши ВМ.
- Authentication protocol: по умолчанию установлен протокол CredSSP – Credential Security Support Provider Protocol. Он прост в использовании, но, если в инфраструктуре несколько кластеров, мы не сможем перенести ВМ между кластерами.
Мы выберем Kerberos как более безопасный и подходящий для переноса ВМ между различными кластерами.
- Performance options: здесь выбираем сетевой протокол. Живая миграция у нас будет работать поверх Switch Embedded Team по протоколу SMB (Server Message Block).
Возможность использовать этот протокол появилась в Windows Server 2016. SMB по умолчанию отдает трафик в несколько портов (SMB Multi-channel). Также он прекрасно работает с RDMA – адаптером удаленного прямого доступа к памяти. Это полезно для ускорения переноса кластеров.
- Authentication protocol: по умолчанию установлен протокол CredSSP – Credential Security Support Provider Protocol. Он прост в использовании, но, если в инфраструктуре несколько кластеров, мы не сможем перенести ВМ между кластерами.
- Kerberos позволяет переносить ВМ между кластерами, но требует настройки ограниченного делегирования (Kerberos Constrained Delegation) на объектах Computer в Active Directory.
Начиная с Windows Server 2016, службы работают в контексте NETWORK SERVICE, который не может имперсонироваться в AD. Так что в этом случае выбираем неограниченное делегирование (Unconstrained Delegation), но учитываем, что это довольно небезопасно:
Если живая миграция инициируется через System Center Virtual Machine Manager (SC VMM), то дополнительной настройки не нужно. SC VMM является доверенным сервисом для переноса машин по Shared-Nothing Live Migration. - Протокол SMB не требует особой настройки. Если мы находимся в доверенной среде, можно немного ускорить процесс Live Migration и отключить сквозное шифрование данных SMB:
Set-SmbServerConfiguration -EncryptData $false -RejectUnencryptedAccess $false
Так мы совершим меньше действий при передаче трафика и не потратим лишнее время на шифрование. В случае с кластерами оно может нам понадобиться.
Эти же настройки в более модном Windows Admin Center:
Разбираемся с конфигурацией сети
Сетевая оптимизация Hyper-V – это крайне дискуссионная тема в сообществе и безграничное поле для экспериментов (предела совершенству в нем нет по определению). Так что перед пошаговой настройкой сети разберемся, как технологии изменились за последнее время и как можно это использовать.Как было раньше. Старые мануалы по переносу ВМ Hyper-V описывают сценарии с использованием технологии тиминга Load Balancing/Fail Over (LBFO). LBFO позволяла группировать физические сетевые адаптеры и создавать поверх них интерфейсы. Но были и минусы, например: не было поддержки RDMA, нельзя было выяснить, через какой порт тима будет идти трафик. А поскольку трафик живой миграции требует довольно жирного канала, это превращалось в проблему, когда все сетевые ворклоады ломились в один физический порт.
Как сейчас. В Windows Server 2019 даже нельзя создать виртуальный свитч поверх LBFO Team. Единственным поддерживаемым решением для объединения портов сетевой карты в Hyper-V остался Switch Embedded Team (SET).
SET агрегирует адаптеры, как и vSwitch у ESXi. Физические сетевые порты становятся патч-кордом для разных типов трафика (в том числе для ВМ), а поверх них нарезаются виртуальные интерфейсы.
Тут нужно добавить, что в типах гипервизоров есть небольшой рассинхрон. Англоязычные авторы считают, что есть только 2 типа, но на самом деле их 3 (подробно мы с коллегами описывали их в этом посте). Когда-то гипервизоры ESX были гибридного типа (1+). Это был такой модернизированный Red Hat c ролью гипервизора. VMware ушла от этого в vSphere 4.1 и стала честным гипервизором типа 1 (bare-metal).
Microsoft взяла опыт VMware на вооружение и реализовала Switch Embedded Team в Windows Server 2016. Эта схема показывает большую производительность и гибкость в управлении трафиком в рамках тиминга.
В новых версиях SET позволяет создавать разные виртуальные интерфейсы для разных нагрузок поверх группы физических интерфейсов. По сути, это виртуальные сетевые адаптеры корневого раздела, которыми мы можем управлять наподобие виртуальных адаптеров ВМ.
Как это влияет на процесс настройки. В Hyper-V, помимо менеджмент-интерфейса, мы обычно создаем интерфейсы для живой миграции и интерфейсы для CSV-трафика кластера. Для этого нам нужно знать количество сетевых портов, входящих в SET, – именно столько виртуальных интерфейсов нужно будет создать. Также учитываем расположение сетевых портов на PCI-шине, количество сокетов для последующего маппинга интерфейсов по NUMA-нодам и количество физических ядер на каждом процессоре.
Посмотрим на процесс пошагово
- Для начала опишем сети, которые будем использовать. Предположим, у нас стандартная двухпортовая on-board сетевая карта и двухсокетная материнская плата.
Имя сети
Назначение
Сеть
Шлюз
VLAN ID
Количество виртуальных адаптеров
Management
Управляющий интерфейс
192.168.1.0/24
192.168.1.1
0 (Native)
1
LiveMigration
Живая миграция
192.168.2.0/24
2
2
CSV
CSV-трафик
192.168.3.0/24
3
2
- Создать SET через стандартный интерфейс можно с помощью Virtual Switch в VMM (Virtual Machine Manager). Если VMM нет, выполняем следующий скрипт PowerShell на каждом хосте Hyper-V:
New-VMSwitch -Name "SET" –NetAdapterName "NIC1","NIC2" -EnableEmbeddedTeaming $True -AllowManagementOS $true -MinimumBandwidthMode Weight
В результате мы создадим свитч с менеджмент-интерфейсом. MinimumBandwidthMode обязательно сразу задаем как weight, иначе после создания SET мы не сможем изменить этот параметр. Так пропускная способность сети будет указана в относительных числах. Это понадобится для настройки Network QoS Policies (а иначе они не будут работать).
Если мы настраиваем SET поверх RDMA-адаптеров, то MinimumBandwidthMode работать не будет ни в каком режиме. Следовательно, Network QoS Policies при включенном RDMA тоже работать не будут.
- Алгоритм балансировки выставляем в Dynamic вместо дефолтного Hyper-V Port (в Windows Server 2019). Dynamic использует лучшие аспекты режимов Address Hash и Hyper-V Port и хорошо обрабатывает и входящий, и исходящий трафик:
Set-VMSwitchTeam "SET" -LoadBalancingAlgorithm Dynamic
Здесь нужно быть очень внимательным, особенно если мы создаем SET через SC VMМ и оставляем балансировку Host Default. В Windows Server 2016 алгоритмом по умолчанию был Dynamic. В Windows Server 2019 дефолтный алгоритм по непонятным причинам изменили на Hyper-V Port, так что можно и ошибиться.
- Когда мы создали свитч, IP-адрес первого физического интерфейса мигрирует на виртуальный интерфейс свитча.
После этого мы создаем сетевые интерфейсы по количеству физических портов на сетевой карте и «прибиваем» CSV-трафик и трафик живой миграции к каждому порту:
# Создаем виртуальные сетевые адаптеры Live Migration Add-VMNetworkAdapter –ManagementOS –Name "LiveMigration01" –SwitchName MGMT-Switch -NumaAwarePlacement $true Add-VMNetworkAdapter –ManagementOS –Name "LiveMigration02" –SwitchName MGMT-Switch -NumaAwarePlacement $true # Задаем VLAN Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName "LiveMigration*" -VlanId 2 -Access #Задаем IP-адреса для адаптеров New-NetIPAddress –InterfaceAlias "vEthernet (LiveMigration01)" -IPAddress 192.168.2.2 -PrefixLength 24 -Confirm:$false New-NetIPAddress –InterfaceAlias "vEthernet (LiveMigration02)" -IPAddress 192.168.2.3 -PrefixLength 24 -Confirm:$false # Создаем виртуальные сетевые адаптеры CSV-трафика Add-VMNetworkAdapter –ManagementOS –Name "CSV01" –SwitchName MGMT-Switch -NumaAwarePlacement $true Add-VMNetworkAdapter –ManagementOS –Name "CSV02" –SwitchName MGMT-Switch -NumaAwarePlacement $true # Задаем VLAN Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName "CSV*" -VlanId 3 -Access # Задаем IP-адреса для адаптеров New-NetIPAddress –InterfaceAlias "vEthernet (CSV01)" -IPAddress 192.168.3.2 -PrefixLength 24 -Confirm:$false New-NetIPAddress –InterfaceAlias "vEthernet (CSV02)" -IPAddress 192.168.3.3 -PrefixLength 24 -Confirm:$false
- Теперь мы должны утилизировать все доступные нам оффлоады. Например, я выкручиваю Jumbo Frames до 9K для всех типов трафика, кроме Management.
Тут без помощи сетевых инженеров не обойтись: потребуется настройка портов на сетевом оборудовании.
Set-NetAdapterAdvancedProperty -Name "NIC1" -DisplayName "Jumbo Packet" -DisplayValue 9014 Set-NetAdapterAdvancedProperty -Name "NIC2" -DisplayName "Jumbo Packet" -DisplayValue 9014 Set-NetAdapterAdvancedProperty -Name "vEthernet (CSV01)" -DisplayName "Jumbo Packet" -DisplayValue "9014 Bytes" Set-NetAdapterAdvancedProperty -Name "vEthernet (CSV02)" -DisplayName "Jumbo Packet" -DisplayValue "9014 Bytes" Set-NetAdapterAdvancedProperty -Name "vEthernet (LiveMigration01)" -DisplayName "Jumbo Packet" -DisplayValue "9014 Bytes" Set-NetAdapterAdvancedProperty -Name "vEthernet (LiveMigration02)" -DisplayName "Jumbo Packet" -DisplayValue "9014 Bytes"
Названия свойств сильно зависят от модели сетевой карты, так как это не статические фичи Windows Server, а фичи конкретной модели сетевой карты. Чтобы использовать эти фичи, нужно ОБЯЗАТЕЛЬНО ставить драйверы от производителя сетевой карты и ни в коем случае не использовать стандартный драйвер Windows. Иначе сразу после создания SET может отвалиться сеть по Management’у. Список всех свойств сетевой карты можно получить через командлет Get-NetAdapterAdvancedProperties.
- Проверим, что метрики сетевых интерфейсов равны:
Синхронизируем метрики интерфейсов и снизим приоритет интерфейсов CSV-трафика. В моем случае задавал так:
Set-NetIPInterface -InterfaceIndex 16 -InterfaceMetric 10000 Set-NetIPInterface -InterfaceIndex 3 -InterfaceMetric 10000 Set-NetIPInterface -InterfaceIndex 9 -InterfaceMetric 10500 Set-NetIPInterface -InterfaceIndex 6 -InterfaceMetric 10500
Это нужно, чтобы трафик равномерно распределялся между физическими портами на равных. - Если карта поддерживает RDMA, то трафик живой миграции уместно перенести на нее. RDMA позволяет двум хостам обмениваться данными в их памяти без обращения к ОС хостов и без нагрузки на CPU. Поддержку RDMA на карте проверяем с помощью командлета Get-NetAdapterRdma.
Пример: что можно получить с помощью командлета. Скрин со statemigration.com.
При этом сетевые ворклоады машин лучше оставить на встроенном или внешнем адаптере без RDMA (но, опять же, эта тема дискуссионная). - На сетевую производительность влияет расстояние до сокета процессора от конкретного порта и PCI-шины. Поэтому перейдем к маппингу виртуальных адаптеров и настройке Virtual Machine Queues (VMQ).
Маппинг необходим, чтобы трафик гарантированно выходил из определенного сетевого порта и не произошла ситуация, когда все сетевые нагрузки уходят в один случайный порт.
Set-VMNetworkAdapterTeamMapping -ManagementOS -PhysicalNetAdapterName "NIC1" -VMNetworkAdapterName "LiveMigration01" Set-VMNetworkAdapterTeamMapping -ManagementOS -PhysicalNetAdapterName "NIC2" -VMNetworkAdapterName "LiveMigration02" Set-VMNetworkAdapterTeamMapping -ManagementOS -PhysicalNetAdapterName "NIC1" -VMNetworkAdapterName "CSV01" Set-VMNetworkAdapterTeamMapping -ManagementOS -PhysicalNetAdapterName "NIC2" -VMNetworkAdapterName "CSV02"
- Настройка VMQ помогает учесть расположение на PCI-шине. По умолчанию, очереди обрабатываются нулевым ядром нулевого процессора. Это не очень хорошо: во-первых, мы его ОЧЕНЬ сильно греем, во-вторых, так мы просто не сможем выжать из сетевого порта больше 3 Гб. Это относится к трафику ВМ. Но у нас же другой трафик (SMB)! Значит, имеет смысл настроить RSS.
До Windows Server 2019 настройка VMQ была обязательна, пока не появился dVMMQ. Он автоматически балансирует трафик и перекидывает его с ядра на ядро, как только нагрузка доходит 90%. Так что на Windows Server 2019 сидеть и высчитывать ядра для VMQ не нужно.
Настраиваем так:
Set-NetAdapterRss -Name "NIC1" -BaseProcessorGroup 0 -BaseProcessorNumber 2 -MaxProcessors 8 -MaxProcessorNumber 16 Set-NetAdapterRss -Name "NIC2" -BaseProcessorGroup 0 -BaseProcessorNumber 16 -MaxProcessors 8 -MaxProcessorNumber 30
Посмотрим наглядно, как это работает. Предположим, у нас есть 2 процессора с 16 физическими ядрами. Это 32 логических ядра с учетом многопоточности. Открываем Excel и выписываем по порядку ядра от 0 до 31:
Для первого порта сетевого адаптера назначаем Base Processor Number 2. Для количества ядер берем степень двойки. В четвертой степени получим 16 – это значение задаем для MaxProcessorNumber.
BaseProcessor для второго адаптера тоже будет равен 16 (опять берем степень двойки). На картинке хорошо виден перехлест для обработки трафика на шестнадцатом ядре. Ситуация не критичная, так как нулевое ядро мы разгрузили и не используем для обработки Live Migration.
Через эти же командлеты можно задать и количество RSS-очередей (RSS Queues). Их количество зависит от конкретной модели сетевой карты, поэтому перед настройкой RSS Queues нужно изучить документацию к сетевой карте.
Настраиваем миграцию для кластеризованного сценария
Со стороны Failover Cluster дополнительно выкрутим настройки таймаутов кластера:
(Get-Cluster).SameSubnetDelay = 2000
(Get-Cluster).SameSubnetThreshold = 30
- SameSubnetDelay указывает, сколько раз в какое время мы посылаем хартбиты. По умолчанию он выставлен в 1 секунду.
Если узлы кластера находятся в одной сети, этого достаточно. Если они в разных сетях, то нужно настроить CrossSubnetDelay с теми же значениями. - SameSubnetThreshold показывает, сколько хартбитов мы можем максимально пропустить. По дефолту это 5 хартбитов, максимум – 120. Мы поставим оптимальное значение – 30 хартбитов.
Для высоконагруженных машин важно выкрутить оба параметра. Если не уложимся, то с большой вероятностью такая машинка не переедет.
Чтобы трафик живой миграции использовался только на определенной сети, также оставим отдельную сеть в настройках Failover Cluster:
Собственно, это и есть минимальный джентльменский набор настроек для корректной работы Live Migration в Hyper-V.