1. 程式人生 > 其它 >配置Internal Load balancer中VM的外網訪問

配置Internal Load balancer中VM的外網訪問

當在Azure中部署SQL VM時,處於安全考慮,不會配置VM的Public IP,會禁止外網的進出站訪問,只允許從內部VNET,或者特定的內部IP訪問。特別是當使用Azure Internal Load Balancer(ILB)配置了AlwaysOn AG的偵聽器後,我們本意只允許內部訪問。但是總有些特別的需求,需要VM能訪問Internet。

為什麼單機的 Azure SQL VM能訪問外網,當加入到使用了ILB的AlwaysOn AG後就不能訪問外網了?

這是最近遇到比較多的一個問題。分析這個問題前,我們需要明白 Azure 的 默認出站訪問(Default Outbound Access)

. 當一個VM或者資源沒有以下配置時,Azure會通過預設的SNAT為它們創建出站連線:

  • 例項級的Public IP
  • 出站規則
  • NAT 閘道器
  • Load Balancer

當建立單機 SQL VM後,如果沒有配置上面的內容,Azure 會提供一個動態的默認出站訪問IP用於外網訪問。當把VM加入到ILB之後,Azure 就不再為VM提供這種默認出站訪問連線。所以就不能再訪問外網了。另外,這裡的ILB特指standard ILB,因為Basic ILB不提供SLA保證,不支援HA,也不支援Avalability Zone,一般在SQL VM生產環境不建議使用。

實現ILB中VM出站訪問

實現方法有很多種:

方法 適用生產環境 對比
為VM配置Public IP Yes OK
通過出站規則,使用Public LB的前端IP出站訪問 Yes OK
直接使用Public LB的前端IP做入站和出站訪問 No Bad
分配NAT閘道器給VM所在subnet實現出站訪問 Yes Good

VNet NAT Gateway 是 Azure 推薦的方式,它的可擴充套件性,可靠性比其它幾種要好。下文就介紹一下這種方式的實現方式。

使用 VNet NAT Gateway 實現ILB中VM的僅出站訪問

VNET NAT 簡化了虛擬網路的僅出站 Internet 連線。 在子網中配置後,所有出站連線將使用指定的靜態公共 IP 地址。 無需使用負載均衡器或將公共 IP 地址直接附加到虛擬機器,即可建立出站連線。 NAT 是完全託管式的,且具有很高的復原能力。

可為使用 NAT 為每個子網定義出站連線。 同一虛擬網路中的多個子網可以使用不同的 NAT。 也可以通過指定要使用的 NAT Gateway 來配置子網。 任何虛擬機器例項中的所有 UDP 和 TCP 出站流都會使用 NAT。

NAT 可以與 Standard Public IP 地址資源和 Public IP Prefix 共用。 NAT 會將所有流量指向到字首所表示的 IP 地址範圍。 在部署中將任何 IP 加入篩選的過程現在都很簡單。

NAT 會自動處理子網的所有出站流量,而無需完成任何定製化配置。 不需要指定使用者定義的路由。 NAT 優先於其他出站方案,可替代子網的預設 Internet 目標。

如下內容將使用Azure CLI完成配置過程,主要包括:

  1. 配置VNET和NAT Gateway
  2. 配置VM和 Standard ILB

配置完成,大概如下圖所示:

RG=ILBNAT-RG

# 建立資源組
  az group create --name $RG --location chinanorth2

# 建立 NAT Gateway 出站需要使用的 public ip 資源
  az network public-ip create -g $RG --name NAT-PIP \
    --sku standard --allocation static
    
# 建立 NAT Gateway資源
  az network nat gateway create -g $RG --name myNATgateway \
    --public-ip-addresses NAT-PIP --idle-timeout 10 
    
# 建立 VNET及subnet
az network vnet create -g $RG \
    --location chinanorth2 --name myVnet \
    --address-prefix 10.1.0.0/16 --subnet-name mySubnet --subnet-prefix 10.1.0.0/24
  
# 配置對應 subnet使用NAT Gateway
az network vnet subnet update -g $RG \
    --vnet-name myVnet \
    --name mySubnet \
    --nat-gateway myNATgateway
    
# 建立網線安全組(NSG),因為 Standard LB 要求加入的 VM 的 NIC 屬於一個NSG
az network nsg create -g $RG --name myNSG

# 為NSG建立規則,這裡以80埠為例,SQL可能需要開放1433
az network nsg rule create -g $RG --nsg-name myNSG \
    --name myNSGRuleHTTP \
    --protocol '*' \
    --direction inbound \
    --source-address-prefix '*' \
    --source-port-range '*' \
    --destination-address-prefix '*' \
    --destination-port-range 80 \
    --access allow \
    --priority 200
    
# 為VM建立 NIC,使用前面的NSG
for i in {1,2}
do
    az network nic create -g $RG --name vmnic$i --vnet-name myVNet \
        --subnet mySubnet --network-security-group myNSG   
done

# 建立 VM,使用前面的NIC
for i in {1,2}
do
    az vm create -g $RG \
        --name VM$i \
        --nics vmnic$i\
        --image win2016datacenter \
        --admin-username azureuser \
        --no-wait
done

# 為VM安裝IIS. 注意,這需要確認VM建立成功後才能執行,create vm 時使用了 --no-wait 引數,讓操作在後臺執行,不會馬上建立成功。
az vm list -g $RG --query "[].{vmName:name,vmState:provisioningState}"

for i in {1,2}
do
    az vm extension set \
           --publisher Microsoft.Compute \
           --version 1.8 \
           --name CustomScriptExtension \
           --vm-name VM$i \
           -g $RG --no-wait
           --settings '{"commandToExecute":"powershell Add-WindowsFeature Web-Server; powershell Add-Content -Path \"C:\\inetpub\\wwwroot\\Default.htm\" -Value $($env:computername)"}'
done

# 建立ILB
az network lb create -g $RG --name myILB \
    --sku Standard --vnet-name myVnet \
    --subnet mySubnet --frontend-ip-name myFrontEnd \
    --backend-pool-name myBackEndPool

# 建立ILB的health probe rule 
az network lb probe create -g $RG \
    --lb-name myILB \
    --name myHealthProbe \
    --protocol tcp \
    --port 80

# 建立ILB的負載均衡規則
az network lb rule create -g $RG \
    --lb-name myILB \
    --name myHTTPRule \
    --protocol tcp \
    --frontend-port 80 \
    --backend-port 80 \
    --frontend-ip-name myFrontEnd \
    --backend-pool-name myBackEndPool \
    --probe-name myHealthProbe \
    --idle-timeout 15 \
    --enable-tcp-reset true

# 將VM加入到ILB
for i in {1,2}
do
az network nic ip-config address-pool add \
   --address-pool myBackendPool \
   --ip-config-name ipconfig1 \
   --nic-name vmnic$i \
   -g $RG --lb-name myILB
done


# 在相同的subnet建立一臺VM,並配置 Public IP, 做為零時測試用的跳板機
# 生產環境,RDP和SSH連線可以考慮使用Azure Bastion方案,更安全和可靠
# 建立成功後,會看到返回的Public IP,然後RDP連線
az vm create -g $RG \
    --name VMTEST \
    --image Win2016Datacenter \
    --public-ip-sku Standard \
    --vnet-name myVnet --subnet mySubnet \
    --admin-username azureuser --admin-password 'Str1ngPa$$w0rd'

# 獲取VM的Private IP,用於後續RDP連線
az vm list-ip-addresses -g $RG --query "[].{name:virtualMachine.name,privateip:virtualMachine.network.privateIpAddresses}"

驗證VM1和VM2的外網出站IP,是否是NAT的Public IP

# 獲取NAT使用Public IP 地址
az network public-ip show -g $RG -n NAT-PIP --query "ipAddress"

先RDP到跳板機VMTEST,在跳板機中再RDP到VM1,然後在IE中開啟地址 https://whatsmyip.com/ . 如下圖,證明VM的出站訪問的外網地址是NAT的外網地址

總結

  • 具體問題解決的總結

  • 環境是China Azure, Azure CLI最新版本

  • 本文內容僅代表個人觀點,與任何公司和組織無關

-------------------------------------

作者:Joe.TJ

Joe's Blog:http://www.cnblogs.com/Joe-T/