Azure Kubernetes Service (AKS) で Azure Firewall を使用してネットワーク トラフィックを制限する
AKS クラスターのアウトバウンド ネットワークと FQDN の規則を使用して、AKS の Azure Firewall を使用してエグレス トラフィックを制御する方法について学習します。 この構成を簡略化するために、Azure Firewall には、AKS クラスターからの送信トラフィックを制限する Azure Kubernetes Service (AzureKubernetesService
) 完全修飾ドメイン名 (FQDN) タグが用意されています。 この記事では、Azure Firewall を介して AKS クラスターのトラフィック規則を構成する方法を示します。
Note
FQDN タグには、「AKS クラスターのアウトバウンド ネットワークと FQDN の規則」に記載されているすべての FQDN が含まれており、自動的に更新されます。
運用環境のシナリオでは、SNAT ポート不足の問題を回避するために、Azure Firewall に "少なくとも 20 個のフロントエンド IP" を用意することをお勧めします。
次の情報は、デプロイのアーキテクチャの例を示しています。
- パブリック イングレスは、強制的にファイアウォール フィルターを経由します
- AKS エージェント ノードは専用サブネットに分離されています
- Azure Firewall は独自のサブネットにデプロイされています
- DNAT 規則により、ファイアウォールのパブリック IP がロード バランサーフロントエンド IP に変換されます
- 送信要求は、ユーザー定義ルート (UDR) を使用して、エージェント ノードから Azure Firewall 内部 IP に対して開始されます
- AKS エージェント ノードからの要求は、AKS クラスターがデプロイされたサブネットに設定されている UDR に従います
- Azure Firewall は、パブリック 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"
複数のサブネットを含んだ仮想ネットワークを作成する
クラスター用とファイアウォール用の 2 つの異なるサブネットを持つ仮想ネットワークをプロビジョニングします。 必要に応じて、内部サービス イングレス用のものを作成できます。
az group create
コマンドを使用して、リソース グループを作成します。az group create --name $RG --location $LOC
az network vnet create
およびaz network vnet subnet create
コマンドを使用して、AKS クラスターと Azure Firewall をホストするための 2 つのサブネットを含む仮想ネットワークを作成します。# 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 Firewall を作成して設定する
Azure Firewall のインバウンドおよびアウトバウンド規則を構成する必要があります。 ファイアウォールの主な目的は、組織が AKS クラスターに対してきめ細かなイングレスおよびエグレス トラフィック規則を構成できるようにすることです。
重要
クラスターまたはアプリケーションにより、同じ送信先または送信先の小さいサブセットに対して多数の送信接続が作成される場合、フロントエンド IP あたりのポート数の上限に達するのを防ぐため、より多くのファイアウォール フロントエンド IP が必要になることがあります。
複数の IP を使用して Azure ファイアウォールを作成する方法の詳細については、Bicep を使用して複数のパブリック IP アドレスを含む Azure ファイアウォールを作成する方法に関する記事を参照してください。
az network public-ip create
コマンドを使用して、標準 SKU パブリック IP リソースを作成します。 このリソースは、Azure Firewall フロントエンド アドレスとして使用されます。az network public-ip create --resource-group $RG -n $FWPUBLICIP_NAME --location $LOC --sku "Standard"
Azure Firewall CLI 拡張機能を登録し、
az extension add
コマンドを使用して Azure Firewall を作成します。az extension add --name azure-firewall
az network firewall create
コマンドを使用し、--enable-dns-proxy
をtrue
に設定して、Azure ファイアウォールの作成と DNS プロキシの有効化を行います。az network firewall create --resource-group $RG --name $FWNAME --location $LOC --enable-dns-proxy true
Azure Firewall へのパブリック IP アドレスの設定には数分かかる場合があります。 準備が完了したら、以前に作成した IP アドレスをファイアウォール フロントエンドに割り当てることができます。
注意
ネットワーク規則で FQDN を利用するには、DNS プロキシを有効にする必要があります。 DNS プロキシが有効になると、ファイアウォールによって、ポート 53 がリッスンされ、上記で指定された DNS サーバーに DNS 要求が転送されます。 これにより、ファイアウォールでは FQDN を自動的に変換できます。
az network firewall ip-config create
コマンドを使用して、Azure Firewall IP 構成を作成します。az network firewall ip-config create --resource-group $RG --firewall-name $FWNAME --name $FWIPCONFIG_NAME --public-ip-address $FWPUBLICIP_NAME --vnet-name $VNET_NAME
前のコマンドが正常に完了したら、後で構成できるようにファイアウォールのフロントエンド IP アドレスを保存します。
FWPUBLIC_IP=$(az network public-ip show --resource-group $RG --name $FWPUBLICIP_NAME --query "ipAddress" -o tsv) FWPRIVATE_IP=$(az network firewall show --resource-group $RG --name $FWNAME --query "ipConfigurations[0].privateIPAddress" -o tsv)
Note
承認済み IP アドレス範囲で AKS API サーバーへのセキュリティで保護されたアクセスを使用する場合は、承認された IP 範囲にファイアウォール パブリック IP を追加する必要があります。
Azure Firewall へのホップを含むルートを作成する
Azure では、Azure のサブネット、仮想ネットワーク、およびオンプレミスのネットワーク間のトラフィックが自動的にルーティングされます。 Azure の既定のルーティングを変更する場合は、ルート テーブルを作成できます。
重要
送信の種類の UDR (userDefinedRouting
) には、ルート テーブルに 0.0.0.0/0 へのルートと、NVA のネクスト ホップ宛先が存在している必要があります。
ルート テーブルには、インターネットに対するデフォルトの 0.0.0.0/0 が既に存在します。 Azure でソース ネットワーク アドレス変換 (SNAT) に使用されるパブリック IP アドレスがない場合、このルートを追加するだけでは送信インターネット接続は提供されません。 AKS は、インターネットを指す 0.0.0.0/0 のルートが作成されておらず、ゲートウェイや NVA などを指すルートが作成されたことを検証します。送信の種類の UDR を使用する場合、loadbalancer の種類のサービスが構成されていない限り、受信要求用ロード バランサーのパブリック IP アドレスは作成されません。 送信の種類の UDR を設定した場合、送信要求用パブリック IP アドレスが AKS によって作成されることはありません。
詳細については、Azure Load Balancer のアウトバウンド規則に関するページを参照してください。
az network route-table create
コマンドを使用して、特定のサブネットに関連付ける空のルート テーブルを作成します。 ルート テーブルには、次のホップを以前の手順で作成した Azure Firewall と定義します。 各サブネットには、0 個または 1 個のルート テーブルを関連付けることができます。az network route-table create --resource-group $RG --location $LOC --name $FWROUTE_TABLE_NAME
az network route-table route create
コマンドを使用して、サブネットのルート テーブルにルートを作成します。az network route-table route create --resource-group $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 --resource-group $RG --name $FWROUTE_NAME_INTERNET --route-table-name $FWROUTE_TABLE_NAME --address-prefix $FWPUBLIC_IP/32 --next-hop-type Internet
Azure の既定のシステム ルートをオーバーライドする方法や、サブネットのルート テーブルにさらにルートを追加する方法については、仮想ネットワークのルート テーブルに関するドキュメントを参照してください。
ファイアウォール規則を追加する
注意
kube-system または gatekeeper-system 名前空間の外部にあるアプリケーションが API サーバーと通信する必要がある場合は、fqdn-tag AzureKubernetesService
に対するアプリケーション規則の追加に加えて、API サーバー IP 用のポート443 への TCP 通信を許可する追加のネットワーク規則が必要です。
このセクションでは、3 つのネットワーク規則と、ファイアウォールで構成するために使用できるアプリケーション規則について説明します。 デプロイに基づいてこれらの規則を調整することが必要な場合があります。
- 最初のネットワーク規則では、TCP 経由でのポート 9000 へのアクセスを許可します。
- 2 つ目のネットワーク規則では、UDP 経由でのポート 1194 と 123 へのアクセスを許可します。 21Vianet によって運営される Microsoft Azure にデプロイする場合は、「21Vianet によって運営される Microsoft Azure で必要なネットワーク規則」を参照してください。 どちらの規則でも、この記事の Azure リージョン CIDR (米国東部) 宛てのトラフィックのみが許可されます。
- 3 つ目のネットワーク規則では、UDP 経由の
ntp.ubuntu.com
FQDN に対してポート 123 を開きます。 ネットワーク規則として FQDN を追加することは、Azure Firewall の固有の機能の 1 つであるため、独自のオプションを使用する場合はそれを調整する必要があります。 - 4 番目と 5 番目のネットワーク規則により、GitHub Container Registry (ghcr.io) と Docker Hub (docker.io) からコンテナーをプルするためのアクセスが許可されます。
az network firewall network-rule create
コマンドを使用して、ネットワーク 規則を作成します。az network firewall network-rule create --resource-group $RG --firewall-name $FWNAME --collection-name 'aksfwnr' --name 'apiudp' --protocols 'UDP' --source-addresses '*' --destination-addresses "AzureCloud.$LOC" --destination-ports 1194 --action allow --priority 100 az network firewall network-rule create --resource-group $RG --firewall-name $FWNAME --collection-name 'aksfwnr' --name 'apitcp' --protocols 'TCP' --source-addresses '*' --destination-addresses "AzureCloud.$LOC" --destination-ports 9000 az network firewall network-rule create --resource-group $RG --firewall-name $FWNAME --collection-name 'aksfwnr' --name 'time' --protocols 'UDP' --source-addresses '*' --destination-fqdns 'ntp.ubuntu.com' --destination-ports 123 az network firewall network-rule create --resource-group $RG --firewall-name $FWNAME --collection-name 'aksfwnr' --name 'ghcr' --protocols 'TCP' --source-addresses '*' --destination-fqdns ghcr.io pkg-containers.githubusercontent.com --destination-ports '443' az network firewall network-rule create --resource-group $RG --firewall-name $FWNAME --collection-name 'aksfwnr' --name 'docker' --protocols 'TCP' --source-addresses '*' --destination-fqdns docker.io registry-1.docker.io production.cloudflare.docker.com --destination-ports '443'
az network firewall application-rule create
コマンドを使用して、アプリケーション規則を作成します。az network firewall application-rule create --resource-group $RG --firewall-name $FWNAME --collection-name 'aksfwar' --name 'fqdn' --source-addresses '*' --protocols 'http=80' 'https=443' --fqdn-tags "AzureKubernetesService" --action allow --priority 100
Azure Firewall の詳細については、Azure Firewall のドキュメントを参照してください。
ルート テーブルを AKS に関連付ける
クラスターをファイアウォールに関連付けるには、クラスターのサブネットの専用サブネットから、以前の手順で作成したルート テーブルを参照する必要があります。 az network vnet subnet update
コマンドを使用して、ルート テーブルを AKS に関連付けます。
az network vnet subnet update --resource-group $RG --vnet-name $VNET_NAME --name $AKSSUBNET_NAME --route-table $FWROUTE_TABLE_NAME
アウトバウンド規則に従って AKS クラスターをデプロイする
これで、AKS クラスターを既存の仮想ネットワークにデプロイできます。 userDefinedRouting
送信の種類を使用します。これにより、すべての送信トラフィックが強制的にファイアウォールを経由し、他のエグレス パスが存在しないようになります。 loadBalancer
送信の種類を使用することもできます。
デプロイ先のターゲット サブネットは、環境変数 $SUBNETID
で定義します。 次のコマンドを使用して、サブネット ID の値を設定します。
SUBNETID=$(az network vnet subnet show --resource-group $RG --vnet-name $VNET_NAME --name $AKSSUBNET_NAME --query id -o tsv)
サブネット上に既に存在する UDR を使用するように、送信の種類を定義します。 この構成により、AKS ではロード バランサーに対するセットアップと IP のプロビジョニングをスキップできるようになります。
ヒント
プライベート クラスターなどのさらなる機能をクラスターのデプロイに追加できます。
API サーバーの許可された IP 範囲に対して AKS 機能を追加して、API サーバーのアクセスをファイアウォールのパブリック エンドポイントのみに制限できます。 許可された IP 範囲の機能は、図ではオプションとして示されています。 許可された IP 範囲機能を有効にして API サーバーへのアクセスを制限する場合、開発者ツールでファイアウォールの仮想ネットワークからのジャンプボックスを使用するか、許可された IP 範囲にすべての開発者エンドポイントを追加する必要があります。
Note
独自の kubelet マネージド ID を指定しない場合、AKS はノード リソース グループにシステム割り当て kubelet ID を作成します。
ユーザー定義ルーティングの場合、システム割り当て ID でサポートされるのは CNI ネットワーク プラグインのみです。
az aks create
コマンドを使用して、CNI ネットワーク プラグインでシステム割り当てマネージド ID を使用する AKS クラスターを作成します。
az aks create --resource-group $RG --name $AKSNAME --location $LOC \
--node-count 3 \
--network-plugin azure \
--outbound-type userDefinedRouting \
--vnet-subnet-id $SUBNETID \
--api-server-authorized-ip-ranges $FWPUBLIC_IP \
--generate-ssh-keys
開発者の API サーバーへのアクセスを有効にする
前の手順で、許可された IP 範囲をクラスターに使用した場合、それらから API サーバーにアクセスするために、許可された IP 範囲の AKS クラスター一覧に開発者ツールの IP アドレスを追加する必要があります。 ファイアウォールの仮想ネットワーク内の別のサブネット内に必要なツールを使用してジャンプボックスを構成することもできます。
次のコマンドを使用して IP アドレスを取得します。
CURRENT_IP=$(dig @resolver1.opendns.com ANY myip.opendns.com +short)
az aks update
コマンドを使用して、許可された範囲に IP アドレスを追加します。az aks update --resource-group $RG --name $AKSNAME --api-server-authorized-ip-ranges $CURRENT_IP/32
az aks get-credentials
コマンドを使用して、AKS クラスターに接続するようにkubectl
を構成します。az aks get-credentials --resource-group $RG --name $AKSNAME
AKS にパブリック サービスをデプロイする
サービスの公開と、このクラスターへのアプリケーションのデプロイを始めることができます。 この例では、パブリック サービスを公開しますが、内部ロード バランサーを使用して内部サービスを公開することもできます。
AKS Store Demo のクイック スタート マニフェストを確認して、作成されるすべてのリソースを確認します。
kubectl apply
コマンドを使用して、サービスをデプロイします。kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/aks-store-demo/main/aks-store-quickstart.yaml
Azure Firewall 経由の受信トラフィックを許可する
重要
Azure Firewall を使用してエグレス トラフィックを制限し、すべてのエグレス トラフィックに強制するUDR を作成する場合は、イグレス トラフィックを正しく許可するために、Azure Firewall に適切な DNAT 規則を作成するようにしてください。 UDR で Azure Firewall を使用すると、非対称ルーティングによってイングレス設定が機能しなくなります AKS サブネットにファイアウォールのプライベート IP アドレスに送信される既定のルートがあるのに、種類が loadBalancer
であるイングレスまたは Kubernetes サービスのパブリック ロード バランサーを使用している場合、この問題が発生します。 この場合、ロード バランサーの受信トラフィックはパブリック IP アドレス経由で受信されますが、復路のパスはファイアウォールのプライベート IP アドレスを通過します。 ファイアウォールはステートフルであり、確立済みのセッションを認識しないため、返されるパケットは破棄されます。 Azure Firewall をイングレスまたはサービスのロード バランサーと統合する方法については、「Azure Firewall と Azure Standard Load Balancer を統合する」を参照してください。
受信接続を構成するには、DNAT 規則を Azure Firewall に記述する必要があります。 クラスターへの接続をテストするために、内部サービスによって公開されている内部 IP にルーティングされるように、ファイアウォール フロントエンド パブリック IP アドレスの規則を定義します。 宛先アドレスはカスタマイズできます。 変換されたアドレスは、内部ロード バランサーの IP アドレスである必要があります。 変換されたポートは、Kubernetes サービスの公開ポートである必要があります。 また、Kubernetes サービスによって作成されたロード バランサーに割り当てられた内部 IP アドレスを指定する必要があります。
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
kubectl get svc store-front
コマンドを使用して、サービス IP を取得します。SERVICE_IP=$(kubectl get svc store-front -o jsonpath='{.status.loadBalancer.ingress[*].ip}')
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 Firewall フロントエンド IP アドレスに移動して、接続を検証します。
AKS ストア アプリが表示されます。 この例では、ファイアウォールのパブリック IP は 52.253.228.132
でした。
このページでは、製品を表示し、カートに追加して注文することができます。
リソースをクリーンアップする
Azure リソースをクリーンアップするには、az group delete
コマンドを使用して AKS リソース グループを削除します。
az group delete --name $RG
次のステップ
この記事では、Azure Firewall を使用して送信トラフィックをセキュリティで保護する方法について説明しました。 必要に応じて、上記の手順を一般化して、送信の種類 userDefinedRoute
に関するドキュメントに従い、好みのエグレス ソリューションにトラフィックを転送できます。
Azure Kubernetes Service