Limiter le trafic réseau à l’aide du Pare-feu Azure dans Azure Kubernetes Service (AKS)

Découvrez comment utiliser le réseau sortant et les règles de nom de domaine complet pour les clusters AKS afin de contrôler le trafic de sortie à l’aide du Pare-feu Azure dans AKS. Pour simplifier cette configuration, le Pare-feu Azure fournit une étiquette de nom de domaine complet (FQDN) Azure Kubernetes Service (AzureKubernetesService) qui limite le trafic sortant depuis le cluster AKS. Cet article explique comment configurer vos règles de trafic de cluster AKS par le Pare-feu Azure.

Remarque

La balise FQDN contient tous les noms de domaine complets répertoriés dans Règles de réseau sortant et de nom de domaine complet pour les clusters AKS et est automatiquement mise à jour.

Pour les scénarios de production, nous vous recommandons d’avoir un minimum de 20 adresses IP de front-end sur le Pare-feu Azure afin d’éviter les problèmes d’épuisement des ports SNAT.

Les informations suivantes fournissent un exemple d’architecture du déploiement :

Topologie verrouillée

  • L’entrée publique est forcée à passer à travers les filtres du pare-feu
    • Les nœuds d’agent AKS sont isolés dans un sous-réseau dédié
    • Le Pare-feu Azure est déployé dans son propre sous-réseau
    • Une règle DNAT traduit l’adresse IP publique du pare-feu en adresse IP de front-end de l’équilibreur de charge
  • Les demandes sortantes vont des nœuds d’agent vers l’adresse IP interne du Pare-feu Azure suivant un itinéraire défini par l’utilisateur
    • Les demandes des nœuds d’agent AKS suivent un itinéraire défini par l’utilisateur qui a été mis en place sur le sous-réseau où le cluster AKS a été déployé
    • Le pare-feu Azure sort du réseau virtuel depuis un front-end d’adresses IP publiques
    • L’accès à l’Internet public ou à d’autres services Azure circule vers et depuis l’adresse IP du front-end du pare-feu
    • L’accès au plan de contrôle AKS peut être protégé par des plages d’adresses IP autorisées par le serveur d’API, y compris l’adresse IP de frontend publique du pare-feu
  • Trafic interne

Configurer les variables d’environnement

Définissez un ensemble de variables d’environnement à utiliser dans les créations de ressources.

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"

Créer un réseau virtuel comprenant plusieurs sous-réseaux

Approvisionnez un réseau virtuel avec deux sous-réseaux distincts, un pour le cluster et un pour le pare-feu. Si vous le souhaitez, vous pouvez en créer un pour l’entrée du service interne.

Topologie de réseau vide

  1. Créez un groupe de ressources avec la commande az group create.

    az group create --name $RG --location $LOC
    
  2. Créez un réseau virtuel comportant deux sous-réseaux pour héberger le cluster AKS et le Pare-feu Azure au moyen des commandes az network vnet create et az network vnet subnet create.

    # 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
    

Créer et configurer un pare-feu Azure

Vous devez configurer les règles de trafic entrant et sortant du Pare-feu Azure. L’objectif principal du pare-feu est de permettre aux organisations de configurer des règles de trafic entrant et sortant précises à l’intérieur et à l’extérieur du cluster AKS.

Important

Si votre cluster ou votre application crée un grand nombre de connexions sortantes dirigées vers les mêmes destinations ou une petite partie d’entre elles, il peut vous falloir davantage d’adresses IP de front-end de pare-feu pour éviter d’atteindre le maximum de ports par adresse IP de front-end.

Pour plus d’informations sur la création d’un Pare-feu Azure avec plusieurs adresses IP, consultez Créer un Pare-feu Azure avec plusieurs adresses IP publiques à l’aide de Bicep.

Pare-feu et route définie par l’utilisateur

  1. Créez une ressource IP publique de référence SKU standard à l’aide de la commande az network public-ip create. Cette ressource est utilisée comme adresse de front-end du Pare-feu Azure.

    az network public-ip create -g $RG -n $FWPUBLICIP_NAME -l $LOC --sku "Standard"
    
  2. Inscrivez l’extension CLI du Pare-feu Azure pour créer un Pare-feu Azure à l’aide de la commande az extension add.

    az extension add --name azure-firewall
    
  3. Créez un Pare-feu Azure et activez le proxy DNS à l’aide de la commande az network firewall create et définissez --enable-dns-proxy sur true.

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

La configuration de l’adresse IP publique sur le Pare-feu Azure peut prendre quelques minutes. Une fois qu’elle est prête, l’adresse IP créée précédemment peut être affectée au front-end de pare-feu.

Notes

Pour tirer parti du nom de domaine complet sur les règles réseau, le proxy DNS doit être activé. Lorsque le proxy DNS est activé, le pare-feu écoute le port 53 et transfère les requêtes DNS au serveur DNS spécifié ci-dessus. Le pare-feu peut ensuite traduire automatiquement le nom de domaine complet.

  1. Créez une configuration IP de Pare-feu Azure à l’aide de la commande az network firewall ip-config create.

    az network firewall ip-config create -g $RG -f $FWNAME -n $FWIPCONFIG_NAME --public-ip-address $FWPUBLICIP_NAME --vnet-name $VNET_NAME
    
  2. Une fois que la commande précédente a réussi, enregistrez l’adresse IP du front-end du pare-feu pour la configurer ultérieurement.

    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)
    

Notes

Si vous utilisez un accès sécurisé au serveur d’API AKS avec des plages d’adresses IP autorisées, vous devez ajouter l’adresse IP publique du pare-feu dans la plage d’adresses IP autorisées.

Créer une route avec un tronçon vers le pare-feu Azure

Azure achemine automatiquement le trafic entre les sous-réseaux, les réseaux virtuels et les réseaux locaux Azure. Si vous souhaitez modifier un routage par défaut d’Azure, vous pouvez créer une table de routage.

Important

Le type sortant UDR (userDefinedRouting) requiert un itinéraire pour 0.0.0.0/0 et une destination du tronçon suivant NVA dans la table de routage. La table de routage contient déjà une valeur par défaut 0.0.0.0/0 vers Internet. Sans adresse IP publique pour Azure à utiliser pour la traduction d’adresses réseau sources (SNAT), le simple fait d’ajouter cet itinéraire ne fournit pas de connectivité Internet sortante. AKS vérifie que l’itinéraire 0.0.0.0/0 que vous créez ne pointe pas vers Internet, mais vers une passerelle, une appliance réseau virtuelle, etc. Quand vous utilisez un type sortant UDR, aucune adresse IP publique d’équilibreur de charge pour les demandes entrantes n’est créée, sauf si vous configurez un service de type loadbalancer. AKS ne crée jamais d’adresse IP publique pour les demandes sortantes si vous définissez un type sortant UDR. Pour plus d'informations, consultez Règles sortantes pour Azure Load Balancer.

  1. Créez une table de routage vide à associer à un sous-réseau donné au moyen de la commande az network route-table create. La table de routage définit le tronçon suivant comme étant le pare-feu Azure créé plus haut. Chaque sous-réseau peut avoir zéro ou une table de routage associée.

    az network route-table create -g $RG -l $LOC --name $FWROUTE_TABLE_NAME
    
  2. Créez des itinéraires dans la table de routage pour les sous-réseaux à l’aide de la commande 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
    

Pour plus d’informations sur la façon de remplacer les itinéraires système par défaut d’Azure ou d’ajouter des itinéraires à la table de routage d’un sous-réseau, consultez la documentation de la table de routage de réseau virtuel.

Ajouter des règles de pare-feu

Notes

Pour les applications situées en dehors des espaces de noms kube-system ou gatekeeper-system qui doivent communiquer avec le serveur d’API, une règle réseau supplémentaire est nécessaire pour autoriser la communication TCP sur le port 443 pour l’adresse IP du serveur d’API, en plus de l’ajout d’une règle d’application pour la fqdn-tag AzureKubernetesService.

Cette section couvre trois règles réseau et une règle d’application que vous pouvez utiliser pour la configuration sur votre pare-feu. Vous devrez peut-être adapter ces règles en fonction de votre déploiement.

  • La première règle réseau autorise l’accès au port 9000 via TCP.
  • La deuxième règle réseau autorise l’accès aux ports 1194 et 123 via UDP. Si vous effectuez un déploiement sur Microsoft Azure géré 21Vianet, consultez les règles réseau requises d’Azure géré par 21Vianet. Ces deux règles autorisent uniquement le trafic destiné au CIDR de la région Azure que nous utilisons, dans ce cas USA Est.
  • La troisième règle de réseau ouvre le port 123 au nom de domaine complet ntp.ubuntu.com via UDP. L’ajout d’un nom de domaine complet comme règle de réseau est l’une des fonctionnalités spécifiques du Pare-feu Azure. Vous devrez l’adapter quand vous utiliserez vos propres options.
  • La quatrième et la cinquième règles réseau permettent d’extraire des conteneurs depuis GitHub Container Registry (ghcr.io) et Docker Hub (docker.io).
  1. Créez les règles réseau à l’aide de la commande 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. Créez la règle d’application à l’aide de la commande 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
    

Pour en savoir plus sur le Pare-feu Azure, consultez la documentation du Pare-feu Azure.

Associer la table de routage à AKS

Pour associer le cluster au pare-feu, le sous-réseau dédié pour le sous-réseau du cluster doit référencer la table de routage créée ci-dessus. Utilisez la commande az network vnet subnet update pour associer la table de routage à AKS.

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

Déployer un cluster AKS qui suit vos règles de trafic sortant

Vous pouvez maintenant déployer un cluster AKS dans le réseau virtuel existant. Vous allez utiliser le type sortant userDefinedRouting, qui garantit que tout trafic sortant est forcé à travers le pare-feu et qu’aucun autre chemin de sortie n’existera. Vous pouvez également utiliser le type sortant loadBalancer.

aks-deploy

Le sous-réseau cible où effectuer le déploiement est défini avec la variable d’environnement $SUBNETID. Définissez la valeur de l’ID de sous-réseau à l’aide de la commande suivante :

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

Vous allez définir le type sortant de façon à utiliser la route définie par l’utilisateur qui existe déjà sur le sous-réseau. Cette configuration permet à AKS d’ignorer l’installation et le provisionnement IP pour l’équilibreur de charge.

Conseil

Vous pouvez ajouter des fonctionnalités au déploiement de cluster, telles que des clusters privés.

Vous pouvez ajouter la fonctionnalité AKS des plages d’adresses IP autorisées du serveur d’API pour limiter l’accès du serveur d’API au point de terminaison public du pare-feu uniquement. Elle est indiquée comme facultative dans le diagramme. Quand vous activez la fonctionnalité de plage d’adresses IP autorisées pour limiter l’accès au serveur d’API, vos outils de développement doivent utiliser une jumpbox à partir du réseau virtuel du pare-feu, ou vous devez ajouter tous les points de terminaison de développeur à la plage d’adresses IP autorisées.


Remarque

AKS crée une identité kubelet affectée par le système dans le groupe de ressources Node si vous ne spécifiez pas votre propre identité managée kubelet.

Pour le routage défini par l’utilisateur, l’identité attribuée par le système prend uniquement en charge le plug-in réseau CNI.

Créez un cluster AKS en utilisant une identité managée attribuée par le système avec le plug-in réseau CNI au moyen de la commande az aks create.

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

Activer l’accès des développeurs au serveur d’API

Si vous avez utilisé les plages d’adresses IP autorisées pour votre cluster à l’étape précédente, vous devez ajouter les adresses IP de vos outils de développement à la liste de clusters AKS des plages d’adresses IP approuvées pour pouvoir accéder au serveur d’API à partir de cet emplacement. Vous pouvez également configurer une jumpbox avec les outils nécessaires à l’intérieur d’un sous-réseau distinct dans le réseau virtuel du pare-feu.

  1. Récupérez votre adresse IP à l’aide de la commande suivante :

    CURRENT_IP=$(dig @resolver1.opendns.com ANY myip.opendns.com +short)
    
  2. Ajoutez l’adresse IP aux plages approuvées au moyen de la commande az aks update.

    az aks update -g $RG -n $AKSNAME --api-server-authorized-ip-ranges $CURRENT_IP/32
    
  3. Configurez kubectl pour qu’il se connecte à votre cluster AKS à l’aide de la commande az aks get-credentials.

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

Déploiement d’un service public sur AKS

Vous pouvez maintenant commencer à exposer des services et à déployer des applications sur ce cluster. Dans cet exemple, nous allons exposer un service public, mais vous pouvez également choisir d’exposer un service interne au moyen d’un équilibreur de charge interne.

Règle DNAT de service public

  1. Examinez le manifeste de démarrage rapide de démonstration AKS Store pour voir toutes les ressources à créer.

  2. Déployez le service à l’aide de la commande kubectl apply.

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

Autoriser le trafic entrant par le Pare-feu Azure

Important

Lorsque vous utilisez le Pare-feu Azure pour limiter le trafic de sortie et créer un itinéraire défini par l’utilisateur (UDR) afin de forcer tout le trafic de sortie, veillez à créer une règle DNAT appropriée dans le Pare-feu Azure pour autoriser le trafic d’entrée. L’utilisation du Pare-feu Azure avec une UDR perturbe la configuration d’entrée en raison d’un routage asymétrique Ce problème se produit si le sous-réseau AKS a un itinéraire par défaut qui conduit à l’adresse IP privée du pare-feu, alors que vous utilisez un service d’équilibreur de charge public, d’entrée ou Kubernetes de type loadBalancer. Dans ce cas, le trafic d’équilibreur de charge entrant est reçu par le biais de son adresse IP publique, mais le chemin de retour passe par l’adresse IP privée du pare-feu. Le pare-feu étant avec état, il supprime le paquet de retour, car le pare-feu n’a pas connaissance d’une session établie. Pour découvrir comment intégrer un Pare-feu Azure avec votre équilibreur de charge d’entrée ou de service, voir Intégrer un pare-feu Azure avec Azure Standard Load Balancer.

Pour configurer la connectivité entrante, vous devez écrire une règle DNAT sur le Pare-feu Azure. Pour tester la connectivité au cluster, une règle est définie de sorte que l’adresse IP publique front-end du pare-feu soit acheminée vers l’adresse IP interne exposée par le service interne. Vous pouvez personnaliser l’adresse de destination. L’adresse traduite doit être l’adresse IP de l’équilibreur de charge interne. Le port traduit doit être le port exposé pour votre service Kubernetes. Vous devez également spécifier l’adresse IP interne attribuée à l’équilibreur de charge créé par le service Kubernetes.

  1. Obtenez l’adresse IP interne attribuée à l’équilibreur de charge à l’aide de la commande kubectl get services.

    kubectl get services
    

    L’adresse IP est répertoriée dans la colonne EXTERNAL-IP, comme indiqué dans l’exemple de sortie suivant :

    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. Obtenez l’adresse IP du service à l’aide de la commande kubectl get svc voting-app.

    SERVICE_IP=$(kubectl get svc store-front -o jsonpath='{.status.loadBalancer.ingress[*].ip}')
    
  3. Ajoutez la règle NAT à l’aide de la commande az network firewall nat-rule create.

    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
    

Valider la connectivité

Accédez à l’adresse IP du front-end du pare-feu Azure dans un navigateur pour valider la connectivité.

L’application de stockage AKS s’affiche. Dans cet exemple, l’IP publique du pare-feu était 52.253.228.132.

Capture d’écran montrant l’application Azure Store Front ouverte dans un navigateur local.

Sur cette page, vous pouvez afficher les produits, les ajouter à votre panier, puis passer une commande.

Nettoyer les ressources

Pour effacer les ressources Azure, supprimez le groupe de ressources AKS à l’aide de la commande az group delete.

az group delete -g $RG

Étapes suivantes

Dans cet article, vous avez appris à sécuriser votre trafic sortant à l’aide du Pare-feu Azure. Si nécessaire, vous pouvez généraliser la procédure ci-dessus pour transférer le trafic vers votre solution de sortie préférée, en suivant la documentation sur userDefinedRoute de type sortant.