Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel wird erläutert, wie Sie die Regeln für ausgehende Netzwerke und vollqualifizierte Domänennamen (Fully Qualified Domain Name, FQDN) für AKS-Cluster verwenden, um den Datenverkehr mithilfe der Azure-Firewall zu steuern. Um diese Konfiguration zu vereinfachen, stellt Azure Firewall ein FQDN-Tag (AzureKubernetesServiceAzure Kubernetes Service) bereit, das ausgehenden Datenverkehr aus dem AKS-Cluster einschränkt.
Voraussetzungen
- Ein Azure-Konto mit einem aktiven Abonnement. Falls Sie kein Abonnement besitzen, können Sie ein kostenloses Konto erstellen, bevor Sie beginnen.
- Installieren und konfigurieren Sie Terraform.
- Azure CLI installiert und bei
az loginangemeldet, zur Überprüfung der Bereitstellung verwendet. Installieren Sie Azure CLI, wenn Sie sie noch nicht haben. -
kubectlinstalliert, um eine Verbindung mit dem Cluster herzustellen. Wenn Sie Azure Cloud Shell verwenden, istkubectlbereits installiert. Um sie lokal zu installieren, verwenden Sie denaz aks install-cliBefehl.
Ip-Anforderungen für Firewall-Frontend
- Produktionsstartpunkt: Planen Sie mindestens 20 Front-End-IPs auf Azure Firewall, und legen Sie die Konfiguration für Ihre Workload fest, um die SNAT-Portausschöpfung (Source Network Address Translation) zu vermeiden.
- Cluster mit hohem Datenverkehr: Wenn Ihr Cluster viele ausgehende Verbindungen mit denselben Zielen erstellt, benötigen Sie möglicherweise mehr Front-End-IPs oder Azure Firewall Integration mit NAT-Gateway, um die SNAT-Kapazität zu erhöhen.
- API-Serverschutz: Fügen Sie die öffentliche Front-End-IP der Firewall zu den API-Server-Autorisierten-IP-Bereichen hinzu, um die Sicherheit zu erhöhen.
- Entwicklerzugriff: Wenn Sie autorisierte IP-Bereiche verwenden, verwenden Sie entweder einen Jumpbox im virtuellen Netzwerk (VNet) der Firewall oder fügen Entwicklerendpunkt-IPs zum autorisierten Bereich hinzu.
Dieser Leitfaden gilt für den gesamten in diesem Artikel beschriebenen Konfigurationsprozess.
Hinweis
Das FQDN-Tag enthält alle FQDNs, die in ausgehenden Netzwerk- und FQDN-Regeln für AKS-Cluster aufgelistet sind und automatisch aktualisiert werden.
Architekturübersicht
Das folgende Diagramm veranschaulicht die Architektur eines AKS-Clusters mit eingeschränktem Ausgangsdatenverkehr mithilfe der Azure Firewall:
Das Diagramm zeigt AKS-Agentknoten in einem dedizierten Subnetz, die ausgehenden Datenverkehr mithilfe einer UDR über Azure Firewall leiten. Bei eingehendem Datenverkehr setzt eine DNAT-Regel die öffentliche IP-Adresse der Firewall auf die Frontend-IP-Adresse des öffentlichen Lastenausgleichs um.
Zu den wichtigsten Komponenten dieser Architektur gehören:
-
Der öffentliche Eingangsvorgang wird gezwungen, durch Firewallfilter zu fließen:
- AKS-Agentknoten sind in einem dedizierten Subnetz isoliert.
- Azure Firewall wird in einem eigenen Subnetz bereitgestellt.
- Eine DNAT-Regel übersetzt die öffentliche IP der Firewall in die Frontend-IP des Lastenausgleichs.
-
Ausgehende Anforderungen werden von den Agentknoten über eine benutzerdefinierte Route (UDR) an die private IP-Adresse der Azure Firewall geleitet:
- Anforderungen von AKS-Agent-Knoten folgen einer benutzerdefinierten Route, die in dem Subnetz platziert wurde, in dem der AKS-Cluster bereitgestellt ist.
- Azure Firewall wird aus dem VNet über ein öffentliches IP-Frontend weitergeleitet.
- Datenverkehr zum öffentlichen Internet oder zu anderen Azure-Diensten fließt zur und von der Frontend-IP-Adresse der Firewall.
- Sie können den Zugriff auf die AKS-Steuerebene mithilfe autorisierter IP-Bereiche des API-Servers schützen, einschließlich der öffentlichen IP-Adresse der Firewall.
-
Interner Datenverkehr:
- Sie können einen internen Load-Balancer für internen Datenverkehr verwenden, den Sie in einem eigenen Subnetz isolieren können, entweder anstelle eines oder zusätzlich zu einem öffentlichen Load-Balancer.
Konfigurieren von Umgebungsvariablen
In der folgenden Tabelle sind die In diesem Artikel verwendeten Umgebungsvariablen aufgeführt. Legen Sie diese Variablen in Der Shell fest, bevor Sie fortfahren, oder ändern Sie die Befehle, um Ihre eigenen Werte zu verwenden.
| Variable | Description | Beispielwert |
|---|---|---|
RESOURCE_GROUP |
Name der Ressourcengruppe | aks-egress-rg |
LOCATION |
Azure-Region für Ressourcen | eastus |
CLUSTER_NAME |
Name des AKS-Clusters | aks-egress |
VNET_NAME |
Name des virtuellen Netzwerks | aks-egress-vnet |
AKS_SUBNET_NAME |
Name des Subnetzes für AKS | aks-subnet |
FW_SUBNET_NAME |
Name des Subnetzes für Azure Firewall | AzureFirewallSubnet |
FW_NAME |
Name der Azure-Firewall | aks-egress-fw |
FW_PUBLICIP_NAME |
Name der öffentlichen IP für Azure Firewall | aks-egress-fwpublicip |
FW_IPCONFIG_NAME |
Name der IP-Konfiguration für Azure Firewall | aks-egress-fwconfig |
FW_ROUTE_TABLE_NAME |
Name der Routentabelle für Azure Firewall | aks-egress-fwrt |
FW_ROUTE_NAME_1 |
Name der Route für Azure Firewall | aks-egress-fwrn |
FW_ROUTE_NAME_2 |
Name der Internetroute für Azure Firewall | aks-egress-fwrn-internet |
Erstellen einer Ressourcengruppe
Erstellen Sie mit dem Befehl
az group createeine Ressourcengruppe.az group create --name $RESOURCE_GROUP --location $LOCATION
Erstellen eines virtuellen Netzwerks mit mehreren Subnetzen
Stellen Sie ein VNet mit zwei separaten Subnetzen bereit: eines für den Cluster und eines für die Firewall. Optional können Sie eines für internen eingehenden Dienstdatenverkehr erstellen. Das folgende Diagramm veranschaulicht die leere Netzwerktopologie vor der Bereitstellung von Ressourcen:
Das Diagramm zeigt das VNet mit separaten Subnetzen für AKS und Azure Firewall, bevor Ressourcen bereitgestellt werden.
Erstellen Sie ein VNet mit dem
az network vnet createBefehl.az network vnet create \ --resource-group $RESOURCE_GROUP \ --name $VNET_NAME \ --location $LOCATION \ --address-prefixes 10.42.0.0/16 \ --subnet-name $AKS_SUBNET_NAME \ --subnet-prefix 10.42.1.0/24Erstellen Sie mithilfe des
az network vnet subnet createBefehls ein Subnetz für azure Firewall.# Dedicated subnet for Azure Firewall (subnet must be named "AzureFirewallSubnet") az network vnet subnet create \ --resource-group $RESOURCE_GROUP \ --vnet-name $VNET_NAME \ --name $FW_SUBNET_NAME \ --address-prefix 10.42.2.0/24
Erstellen einer öffentlichen IP für Azure Firewall
Erstellen Sie mithilfe des
az network public-ip create-Befehls eine öffentliche IP-Ressource der Standard-SKU. Verwenden Sie diese Ressource als Front-End-IP-Adresse für die Azure Firewall. Die Einzel-IP-Konfiguration in diesem Artikel ist für Tests vorgesehen. Verwenden Sie für die Produktion die Firewall-Frontend-IP-Anforderungen , um die SNAT-Kapazität für Ihre Workload zu planen.az network public-ip create --resource-group $RESOURCE_GROUP --name $FW_PUBLICIP_NAME --location $LOCATION --sku "Standard"
Installieren der Azure Firewall CLI-Erweiterung
Registrieren Sie die Azure Firewall CLI-Erweiterung, um mithilfe des
az extension add-Befehls eine Azure Firewall zu erstellen.az extension add --name azure-firewall
Erstellen einer Azure-Firewall und Aktivieren eines DNS-Proxys
Hinweis
Informationen zu Szenarien mit hohem Datenverkehr finden Sie im Abschnitt " Firewall-Frontend-IP-Anforderungen ".
Weitere Informationen zum Erstellen einer Azure Firewall mit mehreren IP-Adressen finden Sie unter Erstellen einer Azure Firewall mit mehreren öffentlichen IP-Adressen mittels Bicep.
Das Diagramm zeigt Azure Firewall, die in ihrem Subnetz bereitgestellt ist, wobei eine UDR den Datenverkehr vom AKS-Subnetz an die private IP-Adresse der Firewall weiterleitet.
Erstellen Sie eine Azure Firewall und aktivieren Sie den DNS Proxy mit dem
az network firewall create-Befehl, wobei--enable-dns-proxyauftruefestgelegt ist.az network firewall create --resource-group $RESOURCE_GROUP --name $FW_NAME --location $LOCATION --enable-dns-proxy trueDas Einrichten der öffentlichen IP-Adresse für die Azure-Firewall kann einige Minuten dauern. Sobald es fertig ist, können Sie die IP-Adresse dem Firewall-Front-End zuweisen.
Hinweis
Um FQDN für Netzwerkregeln zu verwenden, benötigen Sie DNS-Proxy aktiviert. Wenn DER DNS-Proxy aktiviert ist, überwacht die Firewall Port 53 und leitet DNS-Anforderungen an den von Ihnen angegebenen DNS-Server weiter. Mit dieser Einstellung kann die Firewall den FQDN automatisch übersetzen.
Erstellen einer IP-Konfiguration für Azure Firewall
Erstellen Sie mithilfe des
az network firewall ip-config create-Befehls eine Azure Firewall IP-Konfiguration.az network firewall ip-config create --resource-group $RESOURCE_GROUP --firewall-name $FW_NAME --name $FW_IPCONFIG_NAME --public-ip-address $FW_PUBLICIP_NAME --vnet-name $VNET_NAME
Abrufen der Azure Firewall-IP-Adressen
Speichern Sie die Frontend-IP-Adressen der öffentlichen und privaten Firewall zur späteren Konfiguration mittels der folgenden Befehle:
export FW_PUBLIC_IP=$(az network public-ip show --resource-group $RESOURCE_GROUP --name $FW_PUBLICIP_NAME --query "ipAddress" -o tsv) export FW_PRIVATE_IP=$(az network firewall show --resource-group $RESOURCE_GROUP --name $FW_NAME --query "ipConfigurations[0].privateIPAddress" -o tsv)Hinweis
Informationen zur API-Serversicherheit finden Sie im Abschnitt " Firewall-Frontend-IP-Anforderungen ".
Konfigurieren des virtuellen Netzwerks für die Verwendung von Azure Firewall als DNS-Server
Konfigurieren Sie das virtuelle Netzwerk so, dass die Azure Firewall private IP-Adresse mithilfe des
az network vnet updateBefehls als DNS-Server verwendet wird. Diese Konfiguration stellt sicher, dass die AKS-Knoten und Azure Firewall die Ziel-FQDNs in den Netzwerkregeln konsistent auflösen.az network vnet update \ --resource-group $RESOURCE_GROUP \ --name $VNET_NAME \ --dns-servers $FW_PRIVATE_IP
UDR-Anforderungen für den AKS-Ausgang über Azure Firewall
Azure leitet automatisch Datenverkehr zwischen Azure-Subnetzen, VNets und lokalen Netzwerken weiter. Um das Standardrouting zu ändern, erstellen Sie eine Routentabelle mit den folgenden Anforderungen:
| Kategorie | Anforderung | Wert oder Beschreibung |
|---|---|---|
| Routenparameter | Destination |
0.0.0.0/0 (gesamter Datenverkehr) |
| Routenparameter | Typ des nächsten Sprungs | Virtuelles Netzwerkgerät (Network Virtual Appliance, NVA) |
| Routenparameter | IP-Adresse für nächsten Hop | Private IP-Adresse der Azure Firewall |
| Routenparameter | Verein | Eine Routentabelle pro Subnetz (Null oder eine zulässige) |
| UDR-Beschränkung | Standard-Internetroute |
0.0.0.0/0 ist bereits vorhanden, erfordert jedoch eine öffentliche IP-Adresse für SNAT. |
| UDR-Einschränkung | Nächster Sprung | Die Route muss auf ein Gateway oder eine NVA verweisen, nicht direkt auf das Internet. |
| UDR-Einschränkung | AKS-Validierung | AKS überprüft die Routenkonfiguration und verhindert direkte Internetrouten. |
| UDR-Einschränkung | Grenzwert für Routingtabellen | Jedes Subnetz unterstützt maximal eine zugeordnete Routentabelle. |
| Auswirkungen des ausgehenden Typs | UDR (userDefinedRouting) |
Für ausgehenden Datenverkehr wird keine öffentliche IP-Adresse für den Lastenausgleich erstellt. |
| Auswirkungen des ausgehenden Typs | Öffentliche IP-Adresse des Load Balancers | Wird nur für eingehende Anforderungen erstellt, die einen LoadBalancer Dienst verwenden. |
| Auswirkungen des ausgehenden Typs | SNAT-Konfiguration | Erfordert eine ordnungsgemäß konfigurierte öffentliche IP-Adresse für ausgehende Verbindungen. |
Weitere Informationen finden Sie unter Ausgangsregeln für Azure Load Balancer.
Erstellen Sie eine Route mit einem Hop zur Azure Firewall
Erstellen Sie mithilfe des
az network route-table createBefehls eine leere Routentabelle. Die Routentabelle definiert die Azure-Firewall als nächsten Hop. Jedes Subnetz kann keine oder eine Routentabelle zugeordnet haben.az network route-table create --resource-group $RESOURCE_GROUP --location $LOCATION --name $FW_ROUTE_TABLE_NAMEErstellen Sie Routen in der Routingtabelle für die Subnetze mithilfe des
az network route-table route create-Befehls.az network route-table route create --resource-group $RESOURCE_GROUP --name $FW_ROUTE_NAME_1 --route-table-name $FW_ROUTE_TABLE_NAME --address-prefix 0.0.0.0/0 --next-hop-type VirtualAppliance --next-hop-ip-address $FW_PRIVATE_IP az network route-table route create --resource-group $RESOURCE_GROUP --name $FW_ROUTE_NAME_2 --route-table-name $FW_ROUTE_TABLE_NAME --address-prefix $FW_PUBLIC_IP/32 --next-hop-type Internet
Informationen zum Außerkraftsetzen der Standardsystemrouten von Azure oder zum Hinzufügen weiterer Routen zur Routingtabelle eines Subnetzs finden Sie in der Dokumentation zur Tabelle der virtuellen Netzwerkroute.
Erforderliche ausgehende Regeln für den AKS-Ausgang über Azure Firewall
Hinweis
Für Anwendungen außerhalb der kube-system- oder gatekeeper-system-Namespaces, die mit dem API-Server kommunizieren müssen, ist eine zusätzliche Netzwerkregel erforderlich. Diese Regel muss zusätzlich zu der Anwendungsregel für fqdn-tag von AzureKubernetesService die TCP-Kommunikation mit Port 443 für die API-Server-IP erlauben.
Die folgenden Netzwerkregeln erlauben den in diesem Artikel verwendeten ausgehenden Datenverkehr:
- Die ersten und zweiten Netzwerkregeln ermöglichen den Zugriff auf Container aus GitHub Containerregistrierung (
ghcr.io) und Docker Hub (docker.io).
AKS-Cluster, die den Konnectivity-Agent verwenden, einschließlich des in diesem Artikel erstellten Clusters, erfordern keinen ausgehenden Zugriff auf TCP-Port 9000 oder UDP-Port 1194. Nach März 2021 bereitgestellte Knoten erfordern auch keinen ausgehenden NTP-Zugriff auf UDP-Port 123. Informationen zu den Regeln, die für andere Clusterkonfigurationen und Azure Clouds erforderlich sind, finden Sie unter ausgehenden Netzwerk- und FQDN-Regeln für AKS-Cluster.
Erstellen von Netzwerkregeln in Azure Firewall
Erstellen Sie die Netzwerkregeln mithilfe der folgenden
az network firewall network-rule createBefehle.az network firewall network-rule create --resource-group $RESOURCE_GROUP --firewall-name $FW_NAME --collection-name 'aksfwnr' --name 'ghcr' --protocols 'TCP' --source-addresses '*' --destination-fqdns ghcr.io pkg-containers.githubusercontent.com --destination-ports '443' --action allow --priority 100 az network firewall network-rule create --resource-group $RESOURCE_GROUP --firewall-name $FW_NAME --collection-name 'aksfwnr' --name 'docker' --protocols 'TCP' --source-addresses '*' --destination-fqdns docker.io registry-1.docker.io production.cloudflare.docker.com --destination-ports '443'
Erstellen von Anwendungsregeln in Azure Firewall
Erstellen Sie die Anwendungsregel mithilfe des
az network firewall application-rule create-Befehls.az network firewall application-rule create --resource-group $RESOURCE_GROUP --firewall-name $FW_NAME --collection-name 'aksfwar' --name 'fqdn' --source-addresses '*' --protocols 'http=80' 'https=443' --fqdn-tags "AzureKubernetesService" --action allow --priority 100
Weitere Informationen zur Azure Firewall finden Sie in der Azure Firewall-Dokumentation.
Zuordnen der Routingtabelle zu AKS
Um den Cluster der Firewall zuzuordnen, muss das dedizierte Subnetz für das Subnetz des Clusters auf die Routentabelle verweisen.
Ordnen Sie die Routentabelle mit dem
az network vnet subnet updateBefehl AKS zu.az network vnet subnet update --resource-group $RESOURCE_GROUP --vnet-name $VNET_NAME --name $AKS_SUBNET_NAME --route-table $FW_ROUTE_TABLE_NAME
Bereitstellen eines AKS-Clusters, der Ihren ausgehenden Regeln folgt
Sie können jetzt einen AKS-Cluster im vorhandenen VNet bereitstellen. Sie verwenden den userDefinedRouting Outbound-Typ, mit dem sichergestellt wird, dass ausgehender Datenverkehr über die Firewall geleitet wird und keine anderen Egress-Pfade bestehen. Sie können auch den loadBalancer ausgehenden Typ verwenden.
Das Diagramm zeigt den im vorhandenen VNet bereitgestellten AKS-Cluster, wobei ausgehender Datenverkehr über Azure Firewall mithilfe des UDR weitergeleitet wird.
Legen Sie eine Umgebungsvariable für die Subnetz-ID des Zielsubnetz mithilfe des folgenden Befehls fest:
SUBNET_ID=$(az network vnet subnet show --resource-group $RESOURCE_GROUP --vnet-name $VNET_NAME --name $AKS_SUBNET_NAME --query id -o tsv)
Sie definieren den ausgehenden Typ, um den UDR zu verwenden, der bereits im Subnetz vorhanden ist. Mit dieser Konfiguration kann AKS die Setup- und IP-Bereitstellung für das Lastenausgleichsmodul überspringen.
Tipp
Sie können der Clusterbereitstellung zusätzliche Features hinzufügen, z. B. private Cluster.
Informationen zu autorisierten IP-Bereichen für API-Server und Überlegungen zum Entwicklerzugriff finden Sie im Abschnitt " Firewall-Frontend-IP-Anforderungen ".
Erstellen Sie einen AKS-Cluster mit einer systemseitig zugewiesenen Control-Plane-Identität
Hinweis
Dieser Cluster verwendet eine systemseitig zugewiesene Identität der Steuerungsebene. AKS erstellt eine vom Benutzer zugewiesene Kubelet-Identität in der Knotenressourcengruppe, wenn Sie keine eigene verwaltete Kubelet-Identität angeben.
Für das benutzerdefinierte Routing unterstützt die systemseitig zugewiesene Identität nur das CNI-Netzwerk-Plug-In.
Erstellen Sie einen AKS-Cluster mithilfe einer systemseitig zugewiesenen verwalteten Identität mit dem CNI-Netzwerk-Plug-In mittels dem
az aks create-Befehl.az aks create --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --location $LOCATION \ --node-count 3 \ --network-plugin azure \ --outbound-type userDefinedRouting \ --vnet-subnet-id $SUBNET_ID \ --api-server-authorized-ip-ranges $FW_PUBLIC_IP \ --generate-ssh-keys
Erstellen von vom Benutzer zugewiesenen verwalteten Identitäten
Wenn Sie nicht über benutzerseitig zugewiesene Identitäten verfügen, folgen Sie den Schritten in diesem Abschnitt. Wenn Sie bereits über benutzerseitig zugewiesene Identitäten verfügen, fahren Sie mit Erstellen eines AKS-Clusters mit benutzerseitig zugewiesenen Identitäten fort.
Erstellen Sie mithilfe des
az identity create-Befehls eine verwaltete Identität.az identity create --name myIdentity --resource-group $RESOURCE_GROUPDie Ausgabe sollte in etwa wie die folgende Beispielausgabe aussehen:
{ ... "id": "/subscriptions/<subscriptionid>/resourcegroups/aks-egress-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity", "location": "eastus", "name": "myIdentity", ... "type": "Microsoft.ManagedIdentity/userAssignedIdentities" }Erstellen Sie mithilfe des
az identity create-Befehls eine verwaltete Kubelet-Identität.az identity create --name myKubeletIdentity --resource-group $RESOURCE_GROUPDie Ausgabe sollte in etwa wie die folgende Beispielausgabe aussehen:
{ ... "id": "/subscriptions/<subscriptionid>/resourcegroups/aks-egress-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myKubeletIdentity", "location": "eastus", "name": "myKubeletIdentity", ... "resourceGroup": "aks-egress-rg", ... "type": "Microsoft.ManagedIdentity/userAssignedIdentities" }
Hinweis
Wenn Sie eine eigene VNet- und Routentabelle erstellen, in der sich die Ressourcen außerhalb der Ressourcengruppe des Arbeitsknotens befinden, fügt die CLI automatisch die Rollenzuweisung hinzu. Wenn Sie eine ARM-Vorlage oder eine andere Methode verwenden, müssen Sie die Prinzipal-ID der vom Cluster verwalteten Identität verwenden, um eine Rollenzuweisung durchzuführen.
Erstellen eines AKS-Clusters mit benutzerdefinierten Identitäten
Erstellen Sie einen AKS-Cluster mit Ihren vorhandenen benutzerseitig zugewiesenen verwalteten Identitäten im Subnetz mit dem
az aks create-Befehl. Geben Sie die Ressourcen-ID der verwalteten Identität für die Steuerungsebene und die Ressourcen-ID der Kubelet-Identität an.az aks create \ --resource-group $RESOURCE_GROUP \ --name $CLUSTER_NAME \ --location $LOCATION \ --node-count 3 \ --network-plugin azure \ --network-plugin-mode overlay \ --outbound-type userDefinedRouting \ --vnet-subnet-id $SUBNET_ID \ --api-server-authorized-ip-ranges $FW_PUBLIC_IP \ --assign-identity <identity-resource-id> \ --assign-kubelet-identity <kubelet-identity-resource-id> \ --generate-ssh-keys
Überprüfen Sie den Terraform-Code
Hinweis
Der Beispielcode für diesen Artikel befindet sich im Azure Terraform GitHub Repository. Sie können das Testergebnisprotokoll für aktuelle und frühere Versionen von Terraform anzeigen.
Sehen Sie weitere Artikel und Beispielcode, die zeigen, wie Terraform zur Verwaltung von Azure-Ressourcen verwendet wird.
Das Terraform-Beispiel stellt die folgenden Ressourcen bereit:
- Ein virtuelles Azure-Netzwerk mit zwei Subnetzen: eines für die AKS-Clusterknoten und ein dediziertes
AzureFirewallSubnetSubnetz für Azure Firewall. - Eine öffentliche SKU-Standard-IP-Adresse und eine Azure Firewall (
AZFW_VNetSKU,StandardEbene), die eine Azure Firewall-Richtlinie mit aktiviertem DNS-Proxy verwendet. - Eine Firewallrichtlinienregelsammlungsgruppe, die die Netzwerk- und Anwendungsregeln enthält, die für den AKS-Ausgang erforderlich sind: Netzwerkregeln für die API-Serverports (TCP/9000, UDP/1194), NTP (
ntp.ubuntu.comauf UDP/123), GitHub Containerregistrierung und Docker Hub sowie eine Anwendungsregel, die dasAzureKubernetesServiceFQDN-Tag an den Ports 80 und 443 verwendet. - Eine Routentabelle mit einer Standardroute (
0.0.0.0/0), die auf die private IP-Adresse der Firewall als nächster Hop einer virtuellen Appliance verweist, und eine Route, die die eigene öffentliche IP-Adresse der Firewall direkt an das Internet sendet, um asymmetrisches Routing zu vermeiden. Die Routentabelle ist nur dem AKS-Subnetz zugeordnet. - Ein AKS-Cluster, das eine systemseitig zugewiesene verwaltete Identität, das
azureNetzwerkplugin, denuserDefinedRouting-Ausgangstyp undapi_server_access_profile.authorized_ip_ranges, beschränkt auf die öffentliche IP-Adresse der Firewall, verwendet. - Eine Rollenzuweisung , die der verwalteten Identität des AKS-Clusters die
Network ContributorRolle in der Ressourcengruppe zugibt, sodass der Cluster die netzwerkressourcen verwalten kann, von denen es abhängt.
Das Beispiel erstellt weder einen Demo-Workload noch eine DNAT-Regel oder einen Load-Balancer-Dienst. Nachdem Sie den Cluster überprüft haben, verwenden Sie kubectl, um Ihre eigene Anwendung bereitzustellen, und befolgen Sie dann die weiter oben in diesem Artikel beschriebenen Anweisungen, um in Azure Firewall eine DNAT-Regel hinzuzufügen, falls Sie eingehende Verbindungen benötigen.
Erstellen Sie ein Verzeichnis, um den Terraform-Beispielcode zu testen, und machen Sie es zum aktuellen Verzeichnis.
Erstellen Sie eine Datei mit dem Namen
main.tf, und fügen Sie den folgenden Code ein:terraform { required_version = ">= 1.5.0" required_providers { azurerm = { source = "hashicorp/azurerm" version = "~> 4.0" } } } provider "azurerm" { features {} } variable "prefix" { type = string default = "aks-egress" } variable "location" { type = string default = "eastus" } variable "node_count" { type = number default = 3 } variable "vnet_cidr" { type = string default = "10.42.0.0/16" } variable "aks_subnet_cidr" { type = string default = "10.42.1.0/24" } variable "firewall_subnet_cidr" { type = string default = "10.42.2.0/24" } locals { resource_group_name = "${var.prefix}-rg" vnet_name = "${var.prefix}-vnet" aks_subnet_name = "aks-subnet" firewall_subnet_name = "AzureFirewallSubnet" firewall_name = "${var.prefix}-fw" firewall_public_ip = "${var.prefix}-fwpublicip" firewall_policy_name = "${var.prefix}-fwpolicy" firewall_ipconfig_name = "${var.prefix}-fwconfig" route_table_name = "${var.prefix}-fwrt" default_route_name = "${var.prefix}-fwrn" firewall_public_route = "${var.prefix}-fwrn-internet" aks_name = var.prefix } resource "azurerm_resource_group" "this" { name = local.resource_group_name location = var.location } resource "azurerm_virtual_network" "this" { name = local.vnet_name location = azurerm_resource_group.this.location resource_group_name = azurerm_resource_group.this.name address_space = [var.vnet_cidr] } resource "azurerm_subnet" "aks" { name = local.aks_subnet_name resource_group_name = azurerm_resource_group.this.name virtual_network_name = azurerm_virtual_network.this.name address_prefixes = [var.aks_subnet_cidr] } resource "azurerm_subnet" "firewall" { name = local.firewall_subnet_name resource_group_name = azurerm_resource_group.this.name virtual_network_name = azurerm_virtual_network.this.name address_prefixes = [var.firewall_subnet_cidr] } resource "azurerm_public_ip" "firewall" { name = local.firewall_public_ip location = azurerm_resource_group.this.location resource_group_name = azurerm_resource_group.this.name allocation_method = "Static" sku = "Standard" } resource "azurerm_firewall_policy" "this" { name = local.firewall_policy_name location = azurerm_resource_group.this.location resource_group_name = azurerm_resource_group.this.name dns { proxy_enabled = true } } resource "azurerm_firewall" "this" { name = local.firewall_name location = azurerm_resource_group.this.location resource_group_name = azurerm_resource_group.this.name sku_name = "AZFW_VNet" sku_tier = "Standard" firewall_policy_id = azurerm_firewall_policy.this.id ip_configuration { name = local.firewall_ipconfig_name subnet_id = azurerm_subnet.firewall.id public_ip_address_id = azurerm_public_ip.firewall.id } } resource "azurerm_firewall_policy_rule_collection_group" "aks_rules" { name = "aks-egress-rules" firewall_policy_id = azurerm_firewall_policy.this.id priority = 100 network_rule_collection { name = "aks-network-rules" priority = 100 action = "Allow" rule { name = "apitcp" protocols = ["TCP"] source_addresses = ["*"] destination_addresses = ["AzureCloud.${var.location}"] destination_ports = ["9000"] } rule { name = "apiudp" protocols = ["UDP"] source_addresses = ["*"] destination_addresses = ["AzureCloud.${var.location}"] destination_ports = ["1194"] } rule { name = "time" protocols = ["UDP"] source_addresses = ["*"] destination_fqdns = ["ntp.ubuntu.com"] destination_ports = ["123"] } rule { name = "ghcr" protocols = ["TCP"] source_addresses = ["*"] destination_fqdns = [ "ghcr.io", "pkg-containers.githubusercontent.com" ] destination_ports = ["443"] } rule { name = "docker" protocols = ["TCP"] source_addresses = ["*"] destination_fqdns = [ "docker.io", "registry-1.docker.io", "production.cloudflare.docker.com" ] destination_ports = ["443"] } } application_rule_collection { name = "aks-application-rules" priority = 200 action = "Allow" rule { name = "fqdn" source_addresses = ["*"] destination_fqdn_tags = ["AzureKubernetesService"] protocols { type = "Http" port = 80 } protocols { type = "Https" port = 443 } } } } resource "azurerm_route_table" "this" { name = local.route_table_name location = azurerm_resource_group.this.location resource_group_name = azurerm_resource_group.this.name } resource "azurerm_route" "default_to_firewall" { name = local.default_route_name resource_group_name = azurerm_resource_group.this.name route_table_name = azurerm_route_table.this.name address_prefix = "0.0.0.0/0" next_hop_type = "VirtualAppliance" next_hop_in_ip_address = azurerm_firewall.this.ip_configuration[0].private_ip_address } resource "azurerm_route" "firewall_public_ip_to_internet" { name = local.firewall_public_route resource_group_name = azurerm_resource_group.this.name route_table_name = azurerm_route_table.this.name address_prefix = "${azurerm_public_ip.firewall.ip_address}/32" next_hop_type = "Internet" } resource "azurerm_subnet_route_table_association" "aks" { subnet_id = azurerm_subnet.aks.id route_table_id = azurerm_route_table.this.id } resource "azurerm_kubernetes_cluster" "this" { name = local.aks_name location = azurerm_resource_group.this.location resource_group_name = azurerm_resource_group.this.name dns_prefix = "${var.prefix}-dns" default_node_pool { name = "system" vm_size = "Standard_D2s_v3" node_count = var.node_count vnet_subnet_id = azurerm_subnet.aks.id upgrade_settings { max_surge = "10%" drain_timeout_in_minutes = 0 node_soak_duration_in_minutes = 0 } } identity { type = "SystemAssigned" } network_profile { network_plugin = "azure" outbound_type = "userDefinedRouting" } api_server_access_profile { authorized_ip_ranges = [ "${azurerm_public_ip.firewall.ip_address}/32" ] } depends_on = [ azurerm_route.default_to_firewall, azurerm_subnet_route_table_association.aks, azurerm_firewall_policy_rule_collection_group.aks_rules ] } resource "azurerm_role_assignment" "network_contributor" { scope = azurerm_resource_group.this.id role_definition_name = "Network Contributor" principal_id = azurerm_kubernetes_cluster.this.identity[0].principal_id } output "resource_group_name" { value = azurerm_resource_group.this.name } output "aks_cluster_name" { value = azurerm_kubernetes_cluster.this.name } output "firewall_public_ip" { value = azurerm_public_ip.firewall.ip_address } output "firewall_private_ip" { value = azurerm_firewall.this.ip_configuration[0].private_ip_address }
Terraform initialisieren
Führen Sie terraform init aus, um die Bereitstellung der Terraform zu initialisieren. Dieser Befehl lädt den zum Verwalten Ihrer Azure-Ressourcen erforderlichen azurermAnbieter herunter.
terraform init -upgrade
Formatieren und Überprüfen der Konfiguration
Führen Sie die Ausführung terraform fmt aus, um die Konfigurationsdatei zu formatieren, und terraform validate um zu bestätigen, dass die Konfiguration syntaktisch gültig ist.
terraform fmt
terraform validate
Terraform-Ausführungsplan erstellen
Ausführen terraform plan , um einen Ausführungsplan zu erstellen.
terraform plan -out main.tfplan
Wenden Sie einen Terraform-Ausführungsplan an
Führen Sie diesen terraform apply Befehl aus, um den Ausführungsplan auf Ihr Azure-Abonnement anzuwenden.
terraform apply main.tfplan
Das Erstellen des virtuellen Netzwerks, Azure Firewall und des AKS-Clusters dauert mehrere Minuten.
Überprüfen der Konfiguration von Ausgangs-, Firewall- und Routenkonfigurationen
Rufen Sie den Ressourcengruppennamen, den Clusternamen und die öffentliche IP-Adresse der Firewall aus den Terraform-Ausgaben ab.
RESOURCE_GROUP=$(terraform output -raw resource_group_name) CLUSTER_NAME=$(terraform output -raw aks_cluster_name) FW_PUBLIC_IP=$(terraform output -raw firewall_public_ip)Vergewissern Sie sich, dass der Cluster den
userDefinedRoutingausgehenden Typ verwendet und mithilfe desaz aks showBefehls auf die öffentliche IP-Adresse der Firewall beschränkt ist.az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query "{outboundType:networkProfile.outboundType, authorizedIpRanges:apiServerAccessProfile.authorizedIpRanges}"Vergewissern Sie sich, dass die Route-Tabelle des AKS-Subnetzes den Standarddatenverkehr an die private IP-Adresse der Firewall sendet. Rufen Sie den Namen der Routentabelle mithilfe des
az network route-table listBefehls ab, und listen Sie dann die Routen mithilfe desaz network route-table route listBefehls auf.ROUTE_TABLE_NAME=$(az network route-table list --resource-group $RESOURCE_GROUP --query "[0].name" -o tsv) az network route-table route list --resource-group $RESOURCE_GROUP --route-table-name $ROUTE_TABLE_NAME --output tableVergewissern Sie sich, dass die Netzwerk- und Anwendungsregeln vorhanden sind. Rufen Sie den Namen der Firewallrichtlinie mithilfe des
az network firewall policy listBefehls ab, und zeigen Sie dann die Regelsammlungsgruppe mithilfe desaz network firewall policy rule-collection-group showBefehls an.FW_POLICY_NAME=$(az network firewall policy list --resource-group $RESOURCE_GROUP --query "[0].name" -o tsv) az network firewall policy rule-collection-group show --resource-group $RESOURCE_GROUP --policy-name $FW_POLICY_NAME --name aks-egress-rules --query "ruleCollections[].name" -o tsv
Herstellen einer Verbindung mit dem Cluster
Konfigurieren Sie kubectl so, dass eine Verbindung mit Ihrem Cluster hergestellt wird, mithilfe des Befehls az aks get-credentials, und überprüfen Sie dann die Verbindung mithilfe des Befehls kubectl get nodes.
az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME
kubectl get nodes
Der aus dem Cluster ausgehende Datenverkehr wird jetzt über die Azure Firewall geleitet. Die Firewallrichtlinie ermöglicht die erforderlichen AKS-Endpunkte und blockiert standardmäßig alle anderen ausgehenden Verbindungen.
Ermöglichen des Entwicklerzugriffs auf den API-Server
Wenn Sie im vorherigen Schritt autorisierte IP-Adressbereiche für Ihren Cluster verwendet haben, müssen Sie die IP-Adressen Ihrer Entwicklertools der AKS-Clusterliste mit den genehmigten IP-Adressbereichen hinzufügen, d. h. Sie greifen von dort aus auf den API-Server zu. Sie können auch einen Jumpbox mit den erforderlichen Tools in einem separaten Subnetz im VNet der Firewall konfigurieren.
Rufen Sie Ihre IP-Adresse mit dem folgenden Befehl ab:
CURRENT_IP=$(dig @resolver1.opendns.com ANY myip.opendns.com +short)Fügen Sie die IP-Adresse mithilfe des
az aks updateBefehls zu den genehmigten Bereichen hinzu. Die--api-server-authorized-ip-rangesOption ersetzt die aktuelle Liste. Schließen Sie also die öffentliche IP-Adresse der Firewall ein, wenn Sie die Entwickler-IP-Adresse hinzufügen.az aks update --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --api-server-authorized-ip-ranges $FW_PUBLIC_IP,$CURRENT_IP/32
Herstellen einer Verbindung mit dem AKS-Cluster
Konfigurieren Sie
kubectl, um mithilfe des Befehlsaz aks get-credentialseine Verbindung mit Ihrem AKS-Cluster herzustellen.az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME
Einen öffentlichen Dienst auf AKS einrichten
Nun können Sie damit beginnen, Dienste verfügbar zu machen und Anwendungen in diesem Cluster bereitzustellen. In diesem Beispiel wird ein öffentlicher Dienst verfügbar gemacht, sie können aber auch einen internen Dienst mithilfe eines internen Lastenausgleichs verfügbar machen.
Das Diagramm zeigt eingehenden öffentlichen Datenverkehr, der an die öffentliche IP-Adresse der Firewall gelangt, durch die DNAT-Regel umgesetzt und an die Frontend-IP-Adresse des öffentlichen Lastenausgleichs für den AKS-Dienst weitergeleitet wird.
Überprüfen Sie das AKS Store Demo-Schnellstartmanifest , um die bereitgestellten Komponenten zu verstehen.
Stellen Sie den Dienst mithilfe des
kubectl applyBefehls bereit.kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/aks-store-demo/main/aks-store-quickstart.yaml
Öffentliche Frontend-IP-Adresse des Lastenausgleichs abrufen
Rufen Sie die öffentliche Front-End-IP-Adresse ab, die dem Lastenausgleichsmodul zugewiesen ist, indem Sie den
kubectl get servicesBefehl verwenden.kubectl get servicesDie IP-Adresse sollte in der
EXTERNAL-IPSpalte aufgeführt werden, wie in der folgenden Beispielausgabe gezeigt: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 10sSpeichern Sie die Frontend-IP-Adresse des öffentlichen Load Balancers mit dem Befehl
kubectl get svc store-front.SERVICE_IP=$(kubectl get svc store-front -o jsonpath='{.status.loadBalancer.ingress[*].ip}')
Erstellen einer DNAT-Regel in Azure Firewall
Wichtig
Wenn Sie Azure Firewall verwenden, um den Ausgehenden Datenverkehr einzuschränken und einen UDR zu erstellen, um den gesamten Ausgangsverkehr zu erzwingen, stellen Sie sicher, dass Sie eine entsprechende DNAT-Regel in Azure Firewall erstellen, um den Eingehenden Datenverkehr korrekt zuzulassen. Durch die Verwendung von Azure Firewall mit einer UDR wird das Setup für eingehenden Datenverkehr aufgrund von asymmetrischem Routing unterbrochen. Das Problem tritt auf, wenn das AKS-Subnetz über eine Standardroute verfügt, die zur privaten IP-Adresse der Firewall führt, Sie aber einen öffentlichen Lastenausgleich verwenden – eingehend oder Kubernetes-Dienst vom Typ loadBalancer. In diesem Fall wird der eingehende Load Balancer-Datenverkehr über die öffentliche IP-Adresse empfangen, während der Rückpfad über die private IP-Adresse der Firewall verläuft. Da Azure Firewall zustandsbehaftet ist, verwirft sie das zurückkehrende Paket, weil Azure Firewall keine Kenntnis von einer bestehenden Sitzung hat. Informationen zur Integration von Azure Firewall in ihren Eingangs- oder Service Dienst-Load Balancer finden Sie unter Integrieren von Azure Firewall mit Azure Load Balancer Standard.
Um eingehende Konnektivität zu konfigurieren, erstellen Sie eine DNAT-Regel für Azure Firewall. Um die Konnektivität zu Ihrem Cluster zu testen, übersetzt die Regel die öffentliche Frontend-IP-Adresse der Firewall in die öffentliche Frontend-IP-Adresse des Lastenausgleichs-Frontend, die unter $SERVICE_IP gespeichert ist. Sie können die Zieladresse anpassen. Der übersetzte Port muss der verfügbar gemachte Port für Ihren Kubernetes-Dienst sein. Konfigurieren Sie für eine Topologie, die stattdessen eine private Frontend-IP-Adresse verwendet, einen internen Lastenausgleichsdienst, und verwenden Sie dessen private IP-Adresse als umgesetzte Adresse.
Fügen Sie die NAT-Regel mithilfe des
az network firewall nat-rule create-Befehls hinzu.az network firewall nat-rule create --collection-name exampleset --destination-addresses $FW_PUBLIC_IP --destination-ports 80 --firewall-name $FW_NAME --name inboundrule --protocols Any --resource-group $RESOURCE_GROUP --source-addresses '*' --translated-port 80 --action Dnat --priority 100 --translated-address $SERVICE_IP
Überprüfen der Konnektivität
Navigieren Sie in einem Browser zur IP-Adresse des Azure Firewall-Front-Ends, um die Konnektivität zu überprüfen. Die AKS Store-App sollte angezeigt werden. In diesem Beispiel lautete
52.253.228.132die öffentliche IP-Adresse der Firewall:Auf dieser Seite können Sie Produkte anzeigen und ihrem Warenkorb hinzufügen und dann eine Bestellung aufgeben.
Bereinigen von Ressourcen
Wenn Sie die in diesem Artikel erstellten Ressourcen nicht mehr benötigen, können Sie sie löschen, um zukünftige Kosten zu vermeiden.
Löschen Sie die AKS-Ressourcengruppe mithilfe des
az group deleteBefehls.az group delete --name $RESOURCE_GROUP
Azure Firewall wird stündlich abgerechnet, unabhängig davon, ob der Datenverkehr aktiv verarbeitet wird oder nicht, zuzüglich Gebühren für die Datenverarbeitung. Lassen Sie die Firewall (oder den Rest dieses Beispiels) nicht länger laufen als nötig.
Warning
Wenn Sie mit vorhandenen oder Produktionsressourcen im selben Arbeitsverzeichnis arbeiten, überprüfen Sie den Ausführungsplan sorgfältig, bevor Sie sie zerstören. Beim Ausführen terraform destroy wird jede Ressource entfernt, die in der Terraform-Zustandsdatei für diese Konfiguration nachverfolgt wird, einschließlich des virtuellen Netzwerks, der Subnetze, Azure Firewall, der Firewallrichtlinie und -regeln, der Routentabelle, des AKS-Clusters und der Rollenzuweisung. Vermeiden Sie, es auf gemeinsam genutzter Infrastruktur auszuführen, es sei denn, Sie sind sicher, dass es gefahrlos entfernt werden kann.
Führen Sie terraform plan mit der -destroy Kennzeichnung aus, um zu überprüfen, was Terraform entfernt.
terraform plan -destroy -out main.destroy.tfplan
Führen Sie die Ausführung terraform apply aus, um den Zerstörungsplan anzuwenden und alle von diesem Beispiel erstellten Ressourcen zu entfernen, einschließlich Azure Firewall.
terraform apply main.destroy.tfplan