Blog

Azure Stack HCI Üzerinde Çalışan Tenant VM’ler İçin MAC Adres Atama Stratejileri

Azure Stack HCI, Windows Sunucuları (Hyper-V), Storage Spaces Direct ve Azure-inspired SDN içeren hiperbütünleşik altyapı (HCI) çözümüdür. Cluster sunucuları, Windows Server Failover Clustering özelliğini kullanarak ortak yapılandırmaları ve kaynakları paylaşır.

Bir Windows Failover Cluster, yüksek erişilebilirlik sağlamak için bir cluster’da çalışan birden fazla Windows sunucusundan oluşur; yani bir sunucu devre dışı kalırsa, başka bir node üzerindeki yükleri devralır. Failover cluster’da birden çok sanal makine oluşturabiliriz. Sanal makineler farklı tenant ağlarına bağlanabilir. Bu durumda, bir ağda statik IP ile bağlı bir VM’in cluster içinde sanal makine başka bir node’a taşındığında aynı ağ yapılandırmasını korumasını sağlamamız gerekir. Bu, VM için statik MAC/statik IP atayarak mümkündür. Ancak VM’ye atanacak boşta ve benzersiz MAC nasıl sağlanabilir. Bu sorunu çözmenin farklı yolları vardır. Bu makalede, bu sorunu çözmek için bazı yöntemleri inceleyeceğiz.

Önce, tenant VM oluşturmak için gereken temel adımları anlayalım. Stack-HCI’da tenant ağına bağlı tenant VM oluşturmak için aşağıdaki adımlar gerçekleştirilir.

  • Statik MAC atanmış vm ağ adaptörüne sahip yeni bir VM oluşturun.
  • Statik IP atanan aynı MAC’e sahip yeni bir ağ arabirimi oluşturun (SDN üzerinde çalışan ağ denetleyici hizmetinde).
  • Oluşturulan ağ adaptörünü ağ arayüz denetleyicisine bağlayarak VM’nin tenant ağı bağlantısını alın.

Yukarıdaki adımları gerçekleştirmek için aşağıdaki PowerShell komutları kullanılabilir.

# 1. vm creation with static MAC
New-VM -Generation 2 -Name "MyVM" -Path "C:\VMs\MyVM" -MemoryStartupBytes 4GB -VHDPath "C:\VMs\MyVM\Virtual Hard Disks\WindowsServer2016.vhdx" -SwitchName "SDNvSwitch"

Set-VM -Name "MyVM" -ProcessorCount 4

# Setting static MAC
Set-VMNetworkAdapter -VMName "MyVM" -StaticMacAddress "00-11-22-33-44-55"

# Creating network interface on networkcontroller with same mac/static IP
$vnet = Get-NetworkControllerVirtualNetwork -ConnectionUri $uri -ResourceId "Contoso_WebTier"
$vmnicproperties = New-Object Microsoft.Windows.NetworkController.NetworkInterfaceProperties
$vmnicproperties.PrivateMacAddress = "001122334455"
$vmnicproperties.PrivateMacAllocationMethod = "Static"
$vmnicproperties.IsPrimary = $true

$vmnicproperties.DnsSettings = New-Object Microsoft.Windows.NetworkController.NetworkInterfaceDnsSettings
$vmnicproperties.DnsSettings.DnsServers = @("24.30.1.11", "24.30.1.12")

$ipconfiguration = New-Object Microsoft.Windows.NetworkController.NetworkInterfaceIpConfiguration
$ipconfiguration.resourceid = "MyVM_IP1"
$ipconfiguration.properties = New-Object Microsoft.Windows.NetworkController.NetworkInterfaceIpConfigurationProperties
$ipconfiguration.properties.PrivateIPAddress = "24.30.1.101"
$ipconfiguration.properties.PrivateIPAllocationMethod = "Static"

$ipconfiguration.properties.Subnet = New-Object Microsoft.Windows.NetworkController.Subnet
$ipconfiguration.properties.subnet.ResourceRef = $vnet.Properties.Subnets[0].ResourceRef

$vmnicproperties.IpConfigurations = @($ipconfiguration)
New-NetworkControllerNetworkInterface –ResourceID "MyVM_Ethernet1" –Properties $vmnicproperties –ConnectionUri $uri

$nic = Get-NetworkControllerNetworkInterface -ConnectionUri $uri -ResourceId "MyVM_Ethernet1"

#Do not change the hardcoded IDs in this section, because they are fixed values and must not change.
# 3. Finally make association of vm network adapter with nic created in last step
$FeatureId = "9940cd46-8b06-43bb-b9d5-93d50381fd56"

$vmNics = Get-VMNetworkAdapter -VMName "MyVM"

$CurrentFeature = Get-VMSwitchExtensionPortFeature -FeatureId $FeatureId -VMNetworkAdapter $vmNics

if ($CurrentFeature -eq $null) {
$Feature = Get-VMSystemSwitchExtensionPortFeature -FeatureId $FeatureId

$Feature.SettingData.ProfileId = "{$($nic.InstanceId)}"
$Feature.SettingData.NetCfgInstanceId = "{56785678-a0e5-4a26-bc9b-c0cba27311a3}"
$Feature.SettingData.CdnLabelString = "TestCdn"
$Feature.SettingData.CdnLabelId = 1111
$Feature.SettingData.ProfileName = "Testprofile"
$Feature.SettingData.VendorId = "{1FA41B39-B444-4E43-B35A-E1F7985FD548}"
$Feature.SettingData.VendorName = "NetworkController"
$Feature.SettingData.ProfileData = 1

Add-VMSwitchExtensionPortFeature -VMSwitchExtensionFeature $Feature -VMNetworkAdapter $vmNics
} else {
$CurrentFeature.SettingData.ProfileId = "{$($nic.InstanceId)}"
$CurrentFeature.SettingData.ProfileData = 1

Set-VMSwitchExtensionPortFeature -VMSwitchExtensionFeature $CurrentFeature -VMNetworkAdapter $vmNics
}
Get-VM -Name "MyVM" | Start-VM

Windows Failover Cluster içinde taşıma işlemi yaptığınızda VM’lerin düzgün çalışmasını sağlamak için statik MAC ve statik IP atamamız gerekiyor. Burada kullanılabilir ve benzersiz MAC elde etmek kullanıcıları zorlayan bir durum. Bu sorunu çözmek için aşağıdaki yöntemleri inceleyeceğiz.

Rastgele MAC oluşturma

Bu çok basit bir yaklaşımdır, rastgele bir MAC oluşturacağız ve aynısını kullanacağız.

  • VM (veya yeni ağ arabirimi)’i oluşturmamız gereken node üzerinde geçerli bir MAC oluşturun.
  • Statik olarak aynı MAC’i vm ağ adaptörüne ayarlayın.
  • Statik IP ile birlikte aynı MAC’i ağ arabirimine ayarlayın.

Poweshell komutu

New-VM -Name $vm_name -MemoryStartupBytes $vm_memory -BootDevice VHD -VHDPath $image_path -Path $vm_data_path -Generation $vm_generation -SwitchName $switch_name

Add-ClusterVirtualMachineRole -vmname $vm_name -Name $vm_name
Start-Sleep -Seconds 3

############## Random MAC address generation and assignment
# script block for mac address assingment kept in retry block
$mac_address = Retry-Command -ScriptBlock {
# do something
# found used in az-auto-setup
#$mac_address=("{0:D12}" -f ( Get-Random -Minimum 0 -Maximum 99999 ))
$mac_address = (0..5 | ForEach-Object { '{0:x}{1:x}' -f (Get-Random -Minimum 0 -Maximum 15), (Get-Random -Minimum 0 -Maximum 15) }) -join '-'
write-host "Tring to set : $mac_address"
Set-VMNetworkAdapter -VMName $vm_name -StaticMacAddress "$mac_address"
write-host "Mac set succssfully: $mac_address"
Start-Sleep -Milliseconds 500
Write-host $( Get-VMNetworkAdapter -VMName $vm_name ).MacAddress
return $mac_address
}

write-host "Mac set succssfully: $mac_address"

Write-host 'VM created..'


##########################################################################

# network configuration starts here..
# you can refer for more info: https://learn.microsoft.com/en-us/windows-server/networking/sdn/manage/create-a-tenant-vm#prerequisites
$vnet = Get-NetworkControllerVirtualNetwork -ConnectionUri $uri -ResourceId $vnet_name



$vmnicproperties = New-Object Microsoft.Windows.NetworkController.NetworkInterfaceProperties
# give same mac address below as created before..
$mac = -join($mac_address.split("-")).toupper()
$vmnicproperties.PrivateMacAddress = $mac
Write-host $mac
$vmnicproperties.PrivateMacAllocationMethod = "Static"
$vmnicproperties.IsPrimary = $true

$vmnicproperties.DnsSettings = New-Object Microsoft.Windows.NetworkController.NetworkInterfaceDnsSettings
#$vmnicproperties.DnsSettings.DnsServers = @("192.168.1.254", "8.8.8.8")
$vmnicproperties.DnsSettings.DnsServers = $dns_server
$ipconfiguration = New-Object Microsoft.Windows.NetworkController.NetworkInterfaceIpConfiguration
$ipconfiguration.resourceid = $vm_name + "_IP1"
$ipconfiguration.properties = New-Object Microsoft.Windows.NetworkController.NetworkInterfaceIpConfigurationProperties
$ipconfiguration.properties.PrivateIPAddress = $ip_address
$ipconfiguration.properties.PrivateIPAllocationMethod = "Static"

$ipconfiguration.properties.Subnet = New-Object Microsoft.Windows.NetworkController.Subnet

# do: programatically decide subnet full ref, or form path directly
# $ipconfiguration.properties.subnet.ResourceRef = $vnet.Properties.Subnets[0].ResourceRef
$ipconfiguration.properties.subnet.ResourceRef = "/virtualNetworks/" + $vnet_name + "/subnets/" + $subnet_name
$vmnicproperties.IpConfigurations = @($ipconfiguration)
$NIC_name = $vm_name + "_Eth1"
New-NetworkControllerNetworkInterface -ResourceID $NIC_name -Properties $vmnicproperties -ConnectionUri $uri -Confirm:$false -force
Write-host 'NIC config created..'
Start-Sleep -Seconds 8

$nic = Get-NetworkControllerNetworkInterface -ConnectionUri $uri -ResourceId $NIC_name

#########################################################################

#Do not change the hardcoded IDs in this section, because they are fixed values and must not change.

$FeatureId = "9940cd46-8b06-43bb-b9d5-93d50381fd56"

$vmNics = Get-VMNetworkAdapter -VMName $vm_name

$CurrentFeature = Get-VMSwitchExtensionPortFeature -FeatureId $FeatureId -VMNetworkAdapter $vmNics

if ($CurrentFeature -eq $null)
{
$Feature = Get-VMSystemSwitchExtensionPortFeature -FeatureId $FeatureId

$Feature.SettingData.ProfileId = "{$( $nic.InstanceId )}"
$Feature.SettingData.NetCfgInstanceId = "{56785678-a0e5-4a26-bc9b-c0cba27311a3}"
$Feature.SettingData.CdnLabelString = "TestCdn"
$Feature.SettingData.CdnLabelId = 1111
$Feature.SettingData.ProfileName = "Testprofile"
$Feature.SettingData.VendorId = "{1FA41B39-B444-4E43-B35A-E1F7985FD548}"
$Feature.SettingData.VendorName = "NetworkController"
$Feature.SettingData.ProfileData = 1

Add-VMSwitchExtensionPortFeature -VMSwitchExtensionFeature $Feature -VMNetworkAdapter $vmNics
}
else
{
$CurrentFeature.SettingData.ProfileId = "{$( $nic.InstanceId )}"
$CurrentFeature.SettingData.ProfileData = 1

Set-VMSwitchExtensionPortFeature -VMSwitchExtensionFeature $CurrentFeature -VMNetworkAdapter $vmNics
}
Write-host 'finally applying setting..'
Start-Sleep -Seconds 5



Get-VM -Name $vm_name | Start-VM

Ancak bu çözüm aşağıdaki sorunları beraberinde getiriyor.

  • Aynı cluster’da çalışan iki VM’nin aynı MAC’e sahip olma olasılığı vardır ve taşıma sonra MAC çakışma sorunu yaratabilir.
  • Belirli bir MAC aralığının atanmasına izin verilmez, bu durumda rastgele oluşturmayı sürekli tekrarlamanız gerekir.
  • Kullanılan MAC adreslerini takip etmek çok zordur.

Her node için özel benzersiz MAC adres havuzu aralığı atama ve node MAC adres aralığı havuzundan MAC adresi oluşturma

Her node (hyper-v) özel benzersiz MAC adres havuz aralığı atayabiliriz. Böylece yeni bir ağ arabirimi oluşturmak istediğimizde, VM’nin çalışacağı node havuzundan önce boşta bir MAC alırız. Aynı MAC, vm ağ adaptörü ve ağ arabirimi üzerinde statik IP ile aynı yapılır.

  • Node MAC havuz aralığından boşta MAC adresi alın.
  • Aynı statik MAC’i VM ağ adaptörüne atayın.
  • Statik IP ile birlikte aynı MAC’i ağ arabirimine ayarlayın.
Following is an example of MAC pool range distribution plan for 255 clusters, 16 hosts each:

00-15-5D-[c1][c2]-[h1][v1]-[v2][v3]
field c1, c2: will indicate a cluster. 00 to FF : Max 255 clusters can be created.

field h1 - will be for host/node identification in a cluster. 0 to F = max 16 hosts in a cluster.

field v1,v2,v3 will be used for vms. 000 to FFF = 16*16*16 = total 4096 possible vms/network interfaces per node can be created.

Ancak buradaki zorluk, node havuzundan boşta MAC almak için kullanılabilecek herhangi bir API veya komut bulunmamasıdır. Çözüm olarak MAC’in havuzdan atanmış olması için boşta dinamik MAC’i almak için geçici bir ağ adaptörü oluşturmak ve VM’yi bir an için başlatmak. Ardından VM’yi durdurmalı ve değişikliği geri almalı ve aynı MAC’i kullanarak statik bir MAC oluşturmalı ve aynı adımları takip etmelisiniz.

# creating new network adapter with dynamic MAC
Add-VMNetworkAdapter -VMName $vm_name -SwitchName $switch_name -Name $adapter_name

# starting and stopping vm to get free MAC from node pool
Start-VM -VMName $vm_name; Stop-VM -VMName $vm_name -Force

# reading assigned dynamic MAC
$mac_address = (Get-VMNetworkAdapter -VMName $vm_name -Name $adapter_name).MacAddress

# make same MAC as static
Set-VMNetworkAdapter -VMName $vm_name -Name $adapter_name -StaticMacAddress $mac_address

# rest steps are same for network interface creation

Network controller servisinden boşta MAC alın ve aynısını VM ağ adaptöründe kullanın

Her Stack-hci cluster özel bir merkezi ağ denetleyici servisi bulunmaktadır. Burada, ağ denetleyici servisinde global MAC adres aralığı havuzunu kurabiliriz. Ağ denetleyici servisinde dinamik yapılandırmaya sahip yeni bir ağ arabirimi oluşturduğumuzda, global havuzdan bir MAC atanır. Bu, merkezi bir servis olduğundan çok güvenilir bir çözümdür.

  • Global MAC aralığından atanmış boşta MAC’i almak için ağ denetleyici servisinde dinamik MAC atama yapılandırmasına sahip bir ağ arabirimi oluşturun.
  • Ağ arabiriminde atanmış MAC’i note edin.
  • Aynı MAC adresini vm ağ adaptörüne statik olarak atayın.
# Creating network interface with dynamic MAC config on network controller
$vmnicproperties = New-Object Microsoft.Windows.NetworkController.NetworkInterfaceProperties
$vmnicproperties.PrivateMacAllocationMethod = "Dynamic"
$vmnicproperties.IsPrimary = $true

$vmnicproperties.DnsSettings = New-Object Microsoft.Windows.NetworkController.NetworkInterfaceDnsSettings
$vmnicproperties.DnsSettings.DnsServers = $dns_server
$ipconfiguration = New-Object Microsoft.Windows.NetworkController.NetworkInterfaceIpConfiguration
$ipconfiguration.resourceid = $vm_name + "_IP1"
$ipconfiguration.properties = New-Object Microsoft.Windows.NetworkController.NetworkInterfaceIpConfigurationProperties
$ipconfiguration.properties.PrivateIPAddress = $ip_address
$ipconfiguration.properties.PrivateIPAllocationMethod = "Static"

$ipconfiguration.properties.Subnet = New-Object Microsoft.Windows.NetworkController.Subnet

$ipconfiguration.properties.subnet.ResourceRef = "/virtualNetworks/" + $vnet_name + "/subnets/" + $subnet_name
$vmnicproperties.IpConfigurations = @($ipconfiguration)
$NIC_name = $vm_name + "_Eth1"
New-NetworkControllerNetworkInterface -ResourceID $NIC_name -Properties $vmnicproperties -ConnectionUri $uri -Confirm:$false -force
Write-host 'NIC config created..'
Start-Sleep -Seconds 8

$nic = Get-NetworkControllerNetworkInterface -ConnectionUri $uri -ResourceId $NIC_name
# Read obtained free MAC from global pool
$mac_address = $nic.Properties.PrivateMacAddress -replace '..(?!$)', '$&-'

###### Vm creation flow starts from here. We will set static MAC here
New-VM -Name $vm_name -MemoryStartupBytes $vm_memory -BootDevice VHD -VHDPath $image_path -Path $vm_data_path -Generation $vm_generation -SwitchName $switch_name
Add-ClusterVirtualMachineRole -vmname $vm_name -Name $vm_name
Set-VMNetworkAdapter -VMName $vm_name -StaticMacAddress "$mac_address"
write-host "Mac set succssfully: $mac_address"

Hakan Uzuner

2002 yılından beri aktif olarak bilişim sektöründe çalışmaktayım. Bu süreç içerisinde özellikle profesyonel olarak Microsoft teknolojileri üzerinde çalıştım. Profesyonel kariyerim içerisinde eğitmenlik, danışmanlık ve yöneticilik yaptım. Özellikle danışmanlık ve eğitmenlik tecrübelerimden kaynaklı pek çok farklı firmanın alt yapısının kurulum, yönetimi ve bakımında bulundum. Aynı zamanda ÇözümPark Bilişim Portalı nın Kurucusu olarak portal üzerinde aktif olarak rol almaktayım. Profesyonel kariyerime ITSTACK Bilgi Sistemlerinde Profesyonel Hizmetler Direktörü olarak devam etmekteyim.

İlgili Makaleler

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Başa dön tuşu