使用 Azure Kubernetes Service 中的 Azure 防火牆限制網路流量 (AKS)

了解如何使用 AKS 叢集的輸出網路和 FQDN 規則,以使用 AKS 中的 Azure 防火牆來控制輸出流量。 為了簡化此設定,Azure 防火牆會提供 Azure Kubernetes Service (AzureKubernetesService) 完整功能變數名稱 (FQDN) 標籤,以限制來自 AKS 叢集的輸出流量。 本文說明如何透過 Azure 防火牆設定 AKS 叢集流量規則。

注意

FQDN 標籤包含 AKS 叢集的輸出網路和 FQDN 規則中列出的所有 FQDN,並會自動更新。

針對生產案例,我們建議在 Azure 防火牆上至少有 20 個前端 IP,以避免產生 SNAT 連接埠耗盡問題。

下列資訊提供部署的範例架構:

Locked down topology

  • 系統會強制公開輸入流經防火牆篩選器
    • 已在專用子網路中隔離 AKS 代理程式節點
    • Azure 防火牆部署在其本身的子網路中
    • DNAT 規則會將防火牆公用 IP 轉譯為負載平衡器前端 IP
  • 輸出要求會利用使用者定義的路由 (UDR),從代理程式節點起始到 Azure 防火牆內部 IP
    • 來自 AKS 代理程式節點的要求會遵循已放置於部署 AKS 叢集之子網路上的 UDR
    • Azure 防火牆會從公用 IP 前端輸出虛擬網路
    • 存取公用網際網路或其他 Azure 服務,會流入和流出防火牆前端 IP 位址
    • AKS 控制平面的存取可以受到 API 伺服器授權 IP 範圍的保護,包括防火牆公用前端 IP 位址
  • 內部流量

設定環境變數

定義一組要在資源建立時使用的環境變數。

PREFIX="aks-egress"
RG="${PREFIX}-rg"
LOC="eastus"
PLUGIN=azure
AKSNAME="${PREFIX}"
VNET_NAME="${PREFIX}-vnet"
AKSSUBNET_NAME="aks-subnet"
# DO NOT CHANGE FWSUBNET_NAME - This is currently a requirement for Azure Firewall.
FWSUBNET_NAME="AzureFirewallSubnet"
FWNAME="${PREFIX}-fw"
FWPUBLICIP_NAME="${PREFIX}-fwpublicip"
FWIPCONFIG_NAME="${PREFIX}-fwconfig"
FWROUTE_TABLE_NAME="${PREFIX}-fwrt"
FWROUTE_NAME="${PREFIX}-fwrn"
FWROUTE_NAME_INTERNET="${PREFIX}-fwinternet"

建立有多個子網路的虛擬網路

佈建具有兩個個別子網路的虛擬網路:一個用於叢集,而另一個用於防火牆。 您可以選擇性地為內部服務輸入建立一個子網路。

Empty network topology

  1. 使用 az group create 命令建立資源群組。

    az group create --name $RG --location $LOC
    
  2. 使用 az network vnet createaz network vnet subnet create 命令建立具有兩個子網路的虛擬網路,以裝載 AKS 叢集和 Azure 防火牆。

    # Dedicated virtual network with AKS subnet
    az network vnet create \
        --resource-group $RG \
        --name $VNET_NAME \
        --location $LOC \
        --address-prefixes 10.42.0.0/16 \
        --subnet-name $AKSSUBNET_NAME \
        --subnet-prefix 10.42.1.0/24
    
    # Dedicated subnet for Azure Firewall (Firewall name can't be changed)
    az network vnet subnet create \
        --resource-group $RG \
        --vnet-name $VNET_NAME \
        --name $FWSUBNET_NAME \
        --address-prefix 10.42.2.0/24
    

建立並設定 Azure 防火牆

您必須設定 Azure 防火牆輸入和輸出規則。 防火牆的主要目的是讓組織能夠設定進出 AKS 叢集的細微連入與連出流量規則。

重要

如果您的叢集或應用程式建立大量輸出連線導向至相同或小型目的地子集,您可能需要更多防火牆前端 IP,以避免每個前端 IP 的連接埠上限。

如需如何建立具有多個 IP 的 Azure 防火牆的詳細資訊,請參閱使用 Bicep 建立具有多個公用IP位址的 Azure 防火牆

Firewall and UDR

  1. 使用 az network public-ip create 命令建立標準 SKU 公用 IP 資源。 此資源將作為 Azure 防火牆前端位址。

    az network public-ip create -g $RG -n $FWPUBLICIP_NAME -l $LOC --sku "Standard"
    
  2. 註冊 Azure 防火牆 CLI 擴充功能,以使用 az extension add 命令建立 Azure 防火牆。

    az extension add --name azure-firewall
    
  3. 使用 az network firewall create 命令建立 Azure 防火牆並啟用 DNS Proxy,並將 --enable-dns-proxy 設定為 true

    az network firewall create -g $RG -n $FWNAME -l $LOC --enable-dns-proxy true
    

將公用 IP 位址設定為 Azure 防火牆可能需要幾分鐘的時間。 備妥之後,先前建立的 IP 位址可以指派給防火牆前端。

注意

若要在網路規則上運用 FQDN,我們需要啟用 DNS Proxy。 啟用 DNS Proxy 時,防火牆會在埠 53 上接聽,並將 DNS 要求轉送至上面指定的 DNS 伺服器。 這可讓防火牆自動轉譯 FQDN。

  1. 使用 az network firewall ip-config create 命令建立 Azure 防火牆 IP 組態。

    az network firewall ip-config create -g $RG -f $FWNAME -n $FWIPCONFIG_NAME --public-ip-address $FWPUBLICIP_NAME --vnet-name $VNET_NAME
    
  2. 在上一個命令成功之後,請儲存防火牆前端 IP 位址,以供稍後設定。

    FWPUBLIC_IP=$(az network public-ip show -g $RG -n $FWPUBLICIP_NAME --query "ipAddress" -o tsv)
    FWPRIVATE_IP=$(az network firewall show -g $RG -n $FWNAME --query "ipConfigurations[0].privateIPAddress" -o tsv)
    

注意

如果您使用具有授權 IP 位址範圍的 AKS API 伺服器安全存取,則必須將防火牆公用 IP 新增至授權的 IP 範圍。

建立具有躍點至 Azure 防火牆的路由

Azure 會自動路由傳送 Azure 子網路、虛擬網路及內部部署網路之間的流量。 如果您想要變更任何 Azure 的預設路由,您可以建立路由表。

重要

UDR (userDefinedRouting) 輸出類型在路由表中需要有路由 0.0.0.0/0,以及 NVA 的下一個躍點目的地。 路由表已經具備連到網際網路的預設 0.0.0.0/0。 如果沒有公用 IP 位址可供 Azure 用於來源網路位址轉換 (SNAT),只新增此路由,將不會為您提供輸出網際網路連線能力。 AKS 會驗證您並未建立指向網際網路的 0.0.0.0/0 路由,而是指向閘道、NVA 等。使用 UDR 的輸出類型時,除非您設定 loadbalancer 類型的服務,否則不會建立用於輸入要求的負載平衡器公用 IP 位址。 如果您設定了 UDR 的輸出類型,則 AKS 永遠都不會建立用於輸出要求的公用 IP 位址。 如需詳細資訊,請參閱 Azure Load Balancer 的輸出規則。

  1. 使用 az network route-table create 命令建立空路由表,以與指定的子網路產生關聯。 路由表會將下一個躍點定義為上面建立的 Azure 防火牆。 每個子網路可以有零個或一個與其相關聯的路由表。

    az network route-table create -g $RG -l $LOC --name $FWROUTE_TABLE_NAME
    
  2. 使用 az network route-table route create 命令,在子網路的路由表中建立路由。

    az network route-table route create -g $RG --name $FWROUTE_NAME --route-table-name $FWROUTE_TABLE_NAME --address-prefix 0.0.0.0/0 --next-hop-type VirtualAppliance --next-hop-ip-address $FWPRIVATE_IP
    
    az network route-table route create -g $RG --name $FWROUTE_NAME_INTERNET --route-table-name $FWROUTE_TABLE_NAME --address-prefix $FWPUBLIC_IP/32 --next-hop-type Internet
    

如需如何覆寫 Azure 預設系統路由或將其他路由新增至子網路由表的資訊,請參閱虛擬網路路由表文件

新增防火牆規則

注意

針對需要與 API 伺服器通訊之 kube-system 或 gatekeeper-system 命名空間外部的應用程式,除了為 fqdn-tag AzureKubernetesService 新增應用程式規則之外,還需要額外的網路規則,以允許 API 伺服器 IP 的 TCP 通訊埠 443。

本節涵蓋三個網路規則和可用來在防火牆上設定的應用程式規則。 您可能需要根據您的部署來調整這些規則。

  • 第一個網路規則允許透過 TCP 存取 9000 連接埠。
  • 第二個網路規則允許透過 UDP 存取埠 1194 和 123。 如果您要部署至由 21Vianet 營運的 Microsoft Azure,請參閱由 21Vianet 營運的 Azure 必要網路規則。 這兩個規則只會允許本文中目的地為 Azure 區域 CIDR 的流量,也就是美國東部。
  • 第三個網路規則會透過 UDP 開啟連接埠 123 至 ntp.ubuntu.com FQDN。 將 FQDN 新增為網路規則是 Azure 防火牆的其中一個特定功能,因此您必須在使用自己的選項時加以調整。
  • 第四和第五個網路規則允許從 GitHub Container Registry (ghcr.io) 和 Docker Hub (docker.io) 提取容器。
  1. 使用 az network firewall network-rule create 命令建立網路規則。

    az network firewall network-rule create -g $RG -f $FWNAME --collection-name 'aksfwnr' -n 'apiudp' --protocols 'UDP' --source-addresses '*' --destination-addresses "AzureCloud.$LOC" --destination-ports 1194 --action allow --priority 100
    
    az network firewall network-rule create -g $RG -f $FWNAME --collection-name 'aksfwnr' -n 'apitcp' --protocols 'TCP' --source-addresses '*' --destination-addresses "AzureCloud.$LOC" --destination-ports 9000
    
    az network firewall network-rule create -g $RG -f $FWNAME --collection-name 'aksfwnr' -n 'time' --protocols 'UDP' --source-addresses '*' --destination-fqdns 'ntp.ubuntu.com' --destination-ports 123
    
    az network firewall network-rule create -g $RG -f $FWNAME --collection-name 'aksfwnr' -n 'ghcr' --protocols 'TCP' --source-addresses '*' --destination-fqdns ghcr.io pkg-containers.githubusercontent.com --destination-ports '443'
    
    az network firewall network-rule create -g $RG -f $FWNAME --collection-name 'aksfwnr' -n 'docker' --protocols 'TCP' --source-addresses '*' --destination-fqdns docker.io registry-1.docker.io production.cloudflare.docker.com --destination-ports '443'
    
  2. 使用 az network firewall application-rule create 命令建立應用程式規則。

    az network firewall application-rule create -g $RG -f $FWNAME --collection-name 'aksfwar' -n 'fqdn' --source-addresses '*' --protocols 'http=80' 'https=443' --fqdn-tags "AzureKubernetesService" --action allow --priority 100
    

若要深入了解 Azure 防火牆,請參閱 Azure 防火牆文件

將路由表關聯至 AKS

若要將叢集與防火牆建立關聯,叢集子網路的專用子網路必須參考上面建立的路由表。 使用 az network vnet subnet update 命令將路由表與 AKS 產生關聯。

az network vnet subnet update -g $RG --vnet-name $VNET_NAME --name $AKSSUBNET_NAME --route-table $FWROUTE_TABLE_NAME

部署遵循輸出規則的 AKS 叢集

現在,您可以將 AKS 叢集部署到現有的虛擬網路。 您將使用 userDefinedRouting 輸出類型,以確保任何輸出流量都會透過防火牆強制使用,而且沒有任何其他輸出路徑存在。 您也可以使用輸出 loadBalancer 類型

aks-deploy

要部署到的目標子網路是使用環境變數 $SUBNETID 來定義。 使用下列命令設定子網路識別碼的值:

SUBNETID=$(az network vnet subnet show -g $RG --vnet-name $VNET_NAME --name $AKSSUBNET_NAME --query id -o tsv)

您將定義輸出類型,以使用已存在於子網路上的 UDR。 此設定可讓 AKS 略過負載平衡器的安裝和 IP 佈建。

提示

您可以將其他功能新增至叢集部署,例如 私人叢集

您可以針對 API 伺服器授權的 IP 範圍新增 AKS 功能,以將 API 伺服器存取限制為僅限防火牆的公用端點。 授權的 IP 範圍功能在圖表中表示為選用。 啟用授權的 IP 範圍功能以限制 API 伺服器存取時,您的開發人員工具必須使用來自防火牆虛擬網路的 Jumpbox,或者您必須將所有開發人員端點新增至授權 IP 範圍。


注意

如果您未指定自己的 kubelet 受控識別,AKS 會在節點資源群組中建立系統指派的 kubelet 身分識別。

對於使用者定義的路由,系統指派的身分識別僅支援 CNI 網路外掛程式。

使用系統指派的受控識別,使用 az aks create 命令搭配 CNI 網路外掛程式建立 AKS 叢集。

az aks create -g $RG -n $AKSNAME -l $LOC \
  --node-count 3 \
  --network-plugin azure \
  --outbound-type userDefinedRouting \
  --vnet-subnet-id $SUBNETID \
  --api-server-authorized-ip-ranges $FWPUBLIC_IP

讓開發人員能夠存取 API 伺服器

如果您已在先前步驟中對叢集授權使用 IP 範圍,您需要將開發人員工具的 IP 位址新增至已核准 IP 範圍的 AKS 叢集清單,才能在此存取 API 伺服器。 您也可以在防火牆虛擬網路中的個別子網路內,使用所需的工具來設定 Jumpbox。

  1. 使用下列命令擷取您的 IP 位址:

    CURRENT_IP=$(dig @resolver1.opendns.com ANY myip.opendns.com +short)
    
  2. 使用 az aks update 命令,將 IP 位址新增至核准的範圍。

    az aks update -g $RG -n $AKSNAME --api-server-authorized-ip-ranges $CURRENT_IP/32
    
  3. 使用 az aks get-credentials 命令,設定 kubectl 以連線到您的 AKS 叢集。

    az aks get-credentials -g $RG -n $AKSNAME
    

在 AKS 上部署公共服務

您現在可以起始公用服務,並將應用程式部署至此叢集。 在此範例中,我們將公開公用服務,但您可能也想要使用內部負載平衡器公開內部服務。

Public Service DNAT

  1. 檢閱 AKS Store 示範快速入門指令清單,以查看將建立的所有資源。

  2. 使用 kubectl apply 命令部署服務。

    kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/aks-store-demo/main/aks-store-quickstart.yaml
    

允許透過 Azure 防火牆的輸入流量

重要

當您使用 Azure 防火牆來限制連出流量,並建立 UDR 來強制執行所有連出流量時,請務必在 Azure 防火牆中建立適當的 DNAT 規則,以正確地允許連入流量。 將 Azure 防火牆搭配 UDR 使用,會因為非對稱式路由而中斷連入設定。 如果 AKS 子網路的預設路由會前往防火牆私人 IP 位址,但是您使用的是公用負載平衡器 - 類型為 LoadBalancer 的連入或 Kubernetes 服務loadBalancer。 在此情況下,系統會透過傳入負載平衡器流量的公用 IP 位址接收它,但傳回路徑則會通過防火牆的私人 IP 位址。 由於防火牆是具狀態,其會捨棄傳回封包,因為防火牆並不知道已建立的工作階段。 若要了解如何整合 Azure 防火牆與您的連入或服務負載平衡器,請參閱整合 Azure 防火牆與 Azure Standard Load Balancer \(部分機器翻譯\)。

若要設定輸入連線能力,您必須將DNAT規則寫入 Azure 防火牆。 為了測試與叢集的連線能力,會針對防火牆前端公用 IP 位址定義規則,以將其路由傳送到內部服務所公開的內部 IP。 您可以自訂目的地位址。 轉譯的位址必須是內部負載平衡器的 IP 位址。 轉譯的連接埠必須是針對您 Kubernetes 服務公開的連接埠。 您也必須指定已指派給 Kubernetes 服務所建立的負載平衡器內部 IP 位址。

  1. 使用 kubectl get services 命令取得指派給負載平衡器的內部 IP 位址。

    kubectl get services
    

    IP 位址會列在資料行中 EXTERNAL-IP,如下列範例輸出所示:

    NAME              TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)              AGE
    kubernetes        ClusterIP      10.0.0.1       <none>        443/TCP              9m10s
    order-service     ClusterIP      10.0.104.144   <none>        3000/TCP             11s
    product-service   ClusterIP      10.0.237.60    <none>        3002/TCP             10s
    rabbitmq          ClusterIP      10.0.161.128   <none>        5672/TCP,15672/TCP   11s
    store-front       LoadBalancer   10.0.89.139    20.39.18.6    80:32271/TCP         10s
    
  2. 使用 kubectl get svc voting-app 命令取得服務IP。

    SERVICE_IP=$(kubectl get svc store-front -o jsonpath='{.status.loadBalancer.ingress[*].ip}')
    
  3. 使用 az network firewall nat-rule create 命令新增 NAT 規則。

    az network firewall nat-rule create --collection-name exampleset --destination-addresses $FWPUBLIC_IP --destination-ports 80 --firewall-name $FWNAME --name inboundrule --protocols Any --resource-group $RG --source-addresses '*' --translated-port 80 --action Dnat --priority 100 --translated-address $SERVICE_IP
    

驗證連線能力

在瀏覽器中瀏覽至 Azure 防火牆前端 IP 位址,以驗證連線能力。

您應該會看到 AKS 市集應用程式。 在此範例中,防火牆公用 IP 是 52.253.228.132

Screenshot showing the Azure Store Front App opened in a local browser.

在此頁面上,您可以檢視產品、將其新增至購物車,然後下訂單。

清除資源

若要清除 Azure 資源,請使用 az group delete 命令刪除 AKS 資源群組。

az group delete -g $RG

下一步

在本文中,您已了解如何使用 Azure 防火牆保護您的輸出流量。 如有需要,您可以依照輸出類型 userDefinedRoute 文件,將上述步驟一般化,並將流量轉送至您慣用的輸出解決方案。