1. 程式人生 > >Azure Load Balancer : 支持 IPv6

Azure Load Balancer : 支持 IPv6

pools sna shel adb span publisher ORC mic home

越來越多的網站開始支持 IPv6,即使是哪些只提供 api 服務的站點也需要支持 IPv6,比如蘋果應用商店中的 app 早就強制要求服務器端支持 IPv6 了。
筆者在前文《Azure Load Balancer : 簡介》中介紹了通過 Azure 門戶站點創建基礎的 Azure Load Balancer 配置,本文將接著介紹如何創建支持 IPv6 的 Azure Load Balancer。

關於 IPv6 的一些限制

讓我們先來了解一下 Azure Load Balancer 在 IPv6 支持方面的一些限制(完整的限制列表請參考這裏):

  • 無法在 Azure 門戶中添加 IPv6 負載均衡規則。 只能通過模板、CLI 或 PowerShell 創建規則。
  • 無法將現有 VM 升級為使用 IPv6 地址。 為此必須部署新 VM。
  • 無法將公共 IPv6 地址分配給 VM, 只能分配給負載均衡器。

這三條限制看起來讓人很沮喪!其中第一條意味著我們沒辦法通過 UI 簡單的創建支持 IPv6 的 Load Balancer;第二條則讓老機器失去了升級的機會;第三條則把 IPv6 的支持完全綁死到了 Load Balancer 上!

換個角度看問題也許能讓人心情愉快些:
不支持 UI 操作就是逼著我們寫腳本,剛好可以朝著基礎架構即代碼的方向前進!
不支持現有虛機的升級,可以拋掉歷史的包袱輕裝上陣!
不支持將公共 IPv6 地址分配給 VM,那就只用在 Load Balancer 上維護 IPv6 的配置!

使用 PowerShell 腳本創建 Load Balancer

既然無法通過 Azure 門戶站點上的 UI 創建支持 IPv6 的 Load Balancer,筆者就選擇通過 PowerShell 腳本完成這個任務, 我們來創建一個具有兩臺後端虛機的 Load Balancer,下面是腳本中的主要邏輯。

定義腳本中所需的變量
為了能更好的重用該腳本,筆者把所需的變量都定義到了腳本的開頭處,雖然變量的數目很多,但是只要修改 prodNamePrefix、userName、sshPublicKey 和 location 等幾個關鍵變量的值腳本就可以工作了:

# 資源名稱的前綴
$prodNamePrefix
= "Nick" $lowerProdNamePrefix = $prodNamePrefix.ToLower() # vm user name $userName = "nick" # vm user public key $sshPublicKey = "xxxxxxxxxx" # resource loacation $location = "japaneast" # resource group name $rgName = $prodNamePrefix + "LBGroup" ...

創建 Resource Group、虛擬網絡及其虛擬子網

# 創建 Resource Group
New-AzureRmResourceGroup -Name $rgName -location $location

# 虛擬網絡及其虛擬子網
$backendSubnet = New-AzureRmVirtualNetworkSubnetConfig `
                 -Name $subnetName `
                 -AddressPrefix $subnetPrefix
$vnet = New-AzureRmvirtualNetwork -Name $vnetName `
                                  -ResourceGroupName $rgName `
                                  -Location $location `
                                  -AddressPrefix $vnetPrefix `
                                  -Subnet $backendSubnet

創建 Load Balancer

# 創建 Load Balancer 的公共 IP
$publicIPv4 = New-AzureRmPublicIpAddress `
              -Name $publicIpv4Name `
              -ResourceGroupName $rgName `
              -Location $location `
              -AllocationMethod Static `
              -IpAddressVersion IPv4 `
              -DomainNameLabel $dnsLabelv4
$publicIPv6 = New-AzureRmPublicIpAddress `
              -Name $publicIpv6Name `
              -ResourceGroupName $rgName `
              -Location $location `
              -AllocationMethod Dynamic `
              -IpAddressVersion IPv6 `
              -DomainNameLabel $dnsLabelv6

# 創建 Load Balancer 的 Frontend IP
$FEIPConfigv4 = New-AzureRmLoadBalancerFrontendIpConfig `
                -Name $frontendV4Name `
                -PublicIpAddress $publicIPv4
$FEIPConfigv6 = New-AzureRmLoadBalancerFrontendIpConfig `
                -Name $frontendV6Name `
                -PublicIpAddress $publicIPv6

# 創建 Load Balancer 的 Backend pools
$backendpoolipv4 = New-AzureRmLoadBalancerBackendAddressPoolConfig `
                   -Name $backendAddressPoolV4Name
$backendpoolipv6 = New-AzureRmLoadBalancerBackendAddressPoolConfig `
                   -Name $backendAddressPoolV6Name

# 創建 Load Balancer 的 Inbound NAT rules
$inboundNATRule1v4 = New-AzureRmLoadBalancerInboundNatRuleConfig `
                     -Name $natRule1V4Name `
                     -FrontendIpConfiguration $FEIPConfigv4 `
                     -Protocol TCP `
                     -FrontendPort 10022 `
                     -BackendPort 22
$inboundNATRule2v4 = New-AzureRmLoadBalancerInboundNatRuleConfig `
                     -Name $natRule2V4Name `
                     -FrontendIpConfiguration $FEIPConfigv4 `
                     -Protocol TCP `
                     -FrontendPort 20022 `
                     -BackendPort 22

# 創建 Load Balancer 的 Health probes
$healthProbe = New-AzureRmLoadBalancerProbeConfig -Name $probeV4V6Name `
                                                  -Protocol Tcp `
                                                  -Port 22 `
                                                  -IntervalInSeconds 15 `
                                                  -ProbeCount 2

# 創建 Load Balancer 的 Load balancing rules
$lbrule1v4http = New-AzureRmLoadBalancerRuleConfig `
                 -Name $lbRule1V4HTTPName `
                 -FrontendIpConfiguration $FEIPConfigv4 `
                 -BackendAddressPool $backendpoolipv4 `
                 -Probe $healthProbe `
                 -Protocol Tcp `
                 -FrontendPort 80 `
                 -BackendPort 80
$lbrule1v6http = New-AzureRmLoadBalancerRuleConfig `
                 -Name $lbRule1V6HTTPName `
                 -FrontendIpConfiguration $FEIPConfigv6 `
                 -BackendAddressPool $backendpoolipv6 `
                 -Probe $healthProbe `
                 -Protocol Tcp `
                 -FrontendPort 80 `
                 -BackendPort 80
$lbrule1v4https = New-AzureRmLoadBalancerRuleConfig `
                  -Name $lbRule1V4HTTPSName `
                  -FrontendIpConfiguration $FEIPConfigv4 `
                  -BackendAddressPool $backendpoolipv4 `
                  -Probe $healthProbe `
                  -Protocol Tcp `
                  -FrontendPort 443 `
                  -BackendPort 443
$lbrule1v6https = New-AzureRmLoadBalancerRuleConfig `
                  -Name $lbRule1V6HTTPSName `
                  -FrontendIpConfiguration $FEIPConfigv6 `
                  -BackendAddressPool $backendpoolipv6 `
                  -Probe $healthProbe `
                  -Protocol Tcp `
                  -FrontendPort 443 `
                  -BackendPort 443

# 創建 Load Balancer
$loadbalancer = New-AzureRmLoadBalancer `
                -ResourceGroupName $rgName `
                -Name $lbName `
                -Location $location `
                -FrontendIpConfiguration $FEIPConfigv4,$FEIPConfigv6 `
                -InboundNatRule $inboundNATRule2v4,$inboundNATRule1v4 `
                -BackendAddressPool $backendpoolipv4,$backendpoolipv6 `
                -Probe $healthProbe `
                -LoadBalancingRule $lbrule1v4http,$lbrule1v6http,`
                $lbrule1v4https,$lbrule1v6https

創建兩個虛擬網卡

# 重新獲得虛擬網絡及其虛擬子網的實例,
# 否則創建網卡時會提示沒有指定虛擬子網
$vnet = Get-AzureRmVirtualNetwork -Name $vnetName `
                                  -ResourceGroupName $rgName
$backendSubnet = Get-AzureRmVirtualNetworkSubnetConfig `
                 -Name $subnetName `
                 -VirtualNetwork $vnet

$nic1IPv4 = New-AzureRmNetworkInterfaceIpConfig `
            -Name "IPv4IPConfig" `
            -PrivateIpAddressVersion "IPv4" `
            -Subnet $backendSubnet `
            -LoadBalancerBackendAddressPool $backendpoolipv4 `
            -LoadBalancerInboundNatRule $inboundNATRule1v4
$nic1IPv6 = New-AzureRmNetworkInterfaceIpConfig `
            -Name "IPv6IPConfig" `
            -PrivateIpAddressVersion "IPv6" `
            -LoadBalancerBackendAddressPool $backendpoolipv6
$nic1 = New-AzureRmNetworkInterface `
        -Name $nic1Name `
        -IpConfiguration $nic1IPv4,$nic1IPv6 `
        -ResourceGroupName $rgName `
        -Location $location

$nic2IPv4 = New-AzureRmNetworkInterfaceIpConfig `
            -Name "IPv4IPConfig" `
            -PrivateIpAddressVersion "IPv4" `
            -Subnet $backendSubnet `
            -LoadBalancerBackendAddressPool $backendpoolipv4 `
            -LoadBalancerInboundNatRule $inboundNATRule2v4
$nic2IPv6 = New-AzureRmNetworkInterfaceIpConfig `
            -Name "IPv6IPConfig" `
            -PrivateIpAddressVersion "IPv6" `
            -LoadBalancerBackendAddressPool $backendpoolipv6
$nic2 = New-AzureRmNetworkInterface `
        -Name $nic2Name `
        -IpConfiguration $nic2IPv4,$nic2IPv6 `
        -ResourceGroupName $rgName `
        -Location $location

創建虛擬機並分配新建的 NIC

# 創建 Availability Set
New-AzureRmAvailabilitySet -Name $availabilitySetName `
                           -Sku Aligned `
                           -PlatformFaultDomainCount 2 `
                           -PlatformUpdateDomainCount 5 `
                           -ResourceGroupName $rgName `
                           -location $location
$availabilitySet = Get-AzureRmAvailabilitySet `
                   -Name $availabilitySetName `
                   -ResourceGroupName $rgName

# 創建用戶 Credential
$securePassword = ConvertTo-SecureString $userPassword `
                                         -AsPlainText -Force
$userCred = New-Object System.Management.Automation.PSCredential `
            ($userName, $securePassword)

# 創建第一臺虛機,可以以同樣的方式創建第二臺虛機
$vm1 = New-AzureRmVMConfig -VMName $vm1Name `
                           -VMSize $vmSize `
                           -AvailabilitySetId $availabilitySet.Id
$vm1 = Set-AzureRmVMOperatingSystem `
       -VM $vm1 `
       -Linux `
       -ComputerName $vm1ComputerHostName `
       -Credential $userCred `
       -DisablePasswordAuthentication
$vm1 = Set-AzureRmVMSourceImage `
       -VM $vm1 `
       -PublisherName Canonical `
       -Offer UbuntuServer `
       -Skus $vmVersion `
       -Version "latest"
$vm1 = Set-AzureRmVMBootDiagnostics `
       -VM $vm1 `
       -Disable
$vm1 = Add-AzureRmVMNetworkInterface `
       -VM $vm1 `
       -Id $nic1.Id `
       -Primary
$vm1 = Set-AzureRmVMOSDisk `
       -VM $vm1 `
       -Name $vm1DiskName `
       -CreateOption FromImage `
       -StorageAccountType $storageAccountTypeName
Add-AzureRmVMSshPublicKey `
    -VM $vm1 `
    -KeyData $sshPublicKey `
    -Path "/home/$userName/.ssh/authorized_keys"
New-AzureRmVM -ResourceGroupName $rgName `
              -Location $location `
              -VM $vm1

到這裏我們的 Load Balancer 已經創建完成了,完整的腳本代碼請參考這裏。

在 Azure 門戶上的 Cloud Shell 中執行腳本

假設你已經編輯好了自己的 Load Balancer 創建腳本,並命名為 azureloadbalancer.sp1。讓我們先把腳本上傳到 Azure 門戶上的 Cloud Shell 中,然後在 Cloud Shell 中執行該腳本:

技術分享圖片

腳本執行完成後,一個支持 IPv6 的 Load Balancer 就部署成功了:

技術分享圖片

總結

雖然寫腳本比 UI 操作的難度要高一些,但是一旦這些腳本寫好了今後就可以通過重用這些腳本來提升自動化的程度,絕對是物有所值!在後續的文章中,筆者將介紹如何使用 PowerShell 腳本擴展支持 IPv6 的 Load Balancer 後端的虛機池。

參考:
用 PowerShell 創建支持 IPv6 的 Azure Load Balancer
Powershell load balancer
Azure Load Balancer 對 IPv6 的支持

Azure Load Balancer : 支持 IPv6