Límite del tráfico de red con Azure Firewall en Azure Kubernetes Service (AKS)

Obtenga información sobre cómo usar las reglas de red de salida y FQDN para clústeres de AKS para controlar el tráfico de salida mediante Azure Firewall en AKS. Para simplificar esta configuración, Azure Firewall proporciona una etiqueta de nombre de dominio completo (FQDN) de Azure Kubernetes Service (AzureKubernetesService) que restringe el tráfico de salida del clúster de AKS. En este artículo se muestra cómo configurar las reglas de tráfico del clúster de AKS mediante Azure Firewall.

Nota:

La etiqueta FQDN contiene todos los FQDN enumerados en Reglas de red saliente y FQDN para clústeres AKS y se actualiza automáticamente.

Para escenarios de producción, se recomienda tener un mínimo de 20 IP frontales en el Azure Firewall para evitar problemas de agotamiento de puertos SNAT.

La siguiente información proporciona un ejemplo de arquitectura de la implementación:

Detalle de la topología

  • La entrada publica se inserta en el flujo mediante filtros de firewall
    • Los nodos de agente de AKS están aislados en una subred dedicada
    • Azure Firewall se implementa en una subred propia
    • Una regla DNAT traduce la IP pública del firewall a la IP del frontend del equilibrador de carga
  • Las peticiones salientes parten de los nodos agentes hacia la IP interna del Azure Firewall mediante una ruta definida por el usuario (UDR)
    • Las solicitudes de los nodos de agente de AKS siguen una UDR que se ha colocado en la subred en la que se implementó el clúster de AKS
    • El firewall de Azure sale de la red virtual de un front-end con una IP pública.
    • El acceso a la red pública de Internet u otros servicios de Azure fluye hacia y desde la dirección IP del servidor front-end del firewall.
    • El acceso al plano de control de AKS puede protegerse mediante rangos de IP autorizados por el servidor API, incluida la dirección IP pública del frontend del firewall.
  • Tráfico interno

Configurar variables de entorno

Defina el conjunto de variables de entorno que se usarán en la creación de recursos.

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"

Creación de una red virtual con varias subredes

Aprovisione una red virtual con dos subredes separadas: una para el clúster y otra para el firewall. Opcionalmente, puede crear una para la entrada de servicios internos.

Topología de red vacía

  1. Cree un grupo de recursos con el comando az group create.

    az group create --name $RG --location $LOC
    
  2. Creación de una red virtual con dos subredes para hospedar el clúster AKS y el Azure Firewall mediante los comandos az network vnet create y 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
    

Creación y configuración de una instancia de Azure Firewall

Debe configurar las reglas de entrada y salida de Azure Firewall. El propósito principal del firewall es que las organizaciones puedan configurar reglas de tráfico de entrada y salida pormenorizadas hacia y desde el clúster de AKS.

Importante

Si el clúster o la aplicación crea un gran número de conexiones salientes dirigidas al mismo destino o a un pequeño subconjunto de destinos, es posible que necesite más IP frontales de firewall para evitar que se agoten los puertos por IP frontal.

Para más información sobre cómo crear un Azure Firewall con varias IP, consulte Crear un Azure Firewall con varias direcciones IP públicas mediante Bicep.

Firewall y UDR

  1. Cree un recurso de IP pública SKU estándar mediante el comando az network public-ip create. Este recurso se usará como dirección de frontend del Azure Firewall.

    az network public-ip create -g $RG -n $FWPUBLICIP_NAME -l $LOC --sku "Standard"
    
  2. Registre la extensión de la CLI de Azure Firewall para crear una instancia de Azure Firewall mediante el comando az extension add.

    az extension add --name azure-firewall
    
  3. Cree un Azure Firewall y habilite el proxy DNS mediante el comando az network firewall create y estableciendo el --enable-dns-proxy en true.

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

La configuración de la dirección IP pública en Azure Firewall puede tardar unos minutos. Una vez que esté listo, la dirección IP creada anteriormente se puede asignar al front-end del firewall.

Nota

Para aprovechar FQDN en las reglas de red, necesitamos que el proxy DNS esté habilitado. Cuando el proxy DNS está habilitado, el firewall escucha en el puerto 53 y reenvía las solicitudes DNS al servidor DNS especificado anteriormente. Esto permite al firewall traducir el FQDN automáticamente.

  1. Cree una configuración IP del Azure Firewall mediante el comando 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. Una vez que el comando anterior tenga éxito, guarde la dirección IP del front-end del firewall para su configuración posterior.

    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)
    

Nota

Si utiliza el acceso seguro al servidor de la API de AKS con intervalos de direcciones IP autorizados, debe agregar la dirección IP pública del firewall en el intervalo de IP autorizado.

Creación de una ruta con un salto a Azure Firewall

Azure enruta automáticamente el tráfico entre redes locales, las redes virtuales y las subredes de Azure. Si desea cambiar alguno de los enrutamientos predeterminados de Azure, puede crear una tabla de rutas.

Importante

El tipo de salida de UDR (userDefinedRouting) necesita que haya una ruta para 0.0.0.0/0 y un destino del próximo salto de NVA en la tabla de rutas. La tabla de rutas ya tiene un valor predeterminado de 0.0.0.0/0 para Internet. Sin una dirección IP pública que Azure use para la traducción de direcciones de red de origen (SNAT), simplemente agregar esta ruta no le proporcionará conectividad saliente a Internet. AKS valida que no cree una ruta 0.0.0.0/0 que apunte a Internet, sino a una puerta de enlace, NVA, etc. Cuando se utiliza un tipo de salida de UDR, no se crea una dirección IP pública del equilibrador de carga para las solicitudes entrantes a menos que se configure un servicio de tipo loadbalancer. AKS nunca crea una dirección IP pública para las solicitudes de salida si se establece un tipo de salida de UDR. Para más información, consulte Reglas de salida de Azure Load Balancer.

  1. Cree una tabla de rutas vacía para asociarla a una subred determinada mediante el comando az network route-table create. La tabla de rutas definirá el próximo salto como el firewall de Azure creado anteriormente. Cada subred puede tener cero o una ruta de tablas de ruta asociada.

    az network route-table create -g $RG -l $LOC --name $FWROUTE_TABLE_NAME
    
  2. Cree rutas en la tabla de rutas para las subredes mediante el comando 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
    

Para más información sobre cómo anular las rutas de sistema predeterminadas de Azure o agregar rutas adicionales a la tabla de rutas de una subred, consulte la documentación sobre la tabla de rutas de red virtual.

Adición de reglas de firewall

Nota

Para aplicaciones fuera de los espacios de nombres kube-system o gatekeeper-system que necesitan hablar con el servidor API, se requiere una regla de red adicional para permitir la comunicación TCP al puerto 443 para la IP del servidor API además de agregar la regla de aplicación para fqdn-tag AzureKubernetesService.

Esta sección cubre tres reglas de red y una regla de aplicación que puede usar para configurar en su firewall. Puede que necesite adaptar estas reglas en función de su implementación.

  • La primera regla de red permite el acceso al puerto 9000 a través de TCP.
  • La segunda regla de red permite el acceso a los puertos 1194 y 123 a través de UDP. Si va a implementar en Microsoft Azure operado por 21Vianet, consulte las reglas de red necesarias para Azure operado por 21Vianet. Estas dos reglas solo permitirán el tráfico destinado a la región CIDR de Azure en este artículo, que es Este de EE. UU.
  • La tercera regla de red abre el puerto 123 a ntp.ubuntu.com FQDN a través de UDP. Agregar un FQDN como regla de red es una de las características específicas de Azure Firewall, por lo que tendrá que adaptarla cuando use sus propias opciones.
  • Las reglas de red cuarta y quinta permiten el acceso para extraer contenedores de GitHub Container Registry (ghcr.io) y Docker Hub (docker.io).
  1. Cree las reglas de red mediante el comando 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. Cree la regla de aplicación mediante el comando 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
    

Para más información sobre Azure Firewall, consulte la documentación de Azure Firewall.

Asociación de la tabla de rutas a AKS

Para asociar el clúster al firewall, la subred dedicada del clúster debe hacer referencia a la tabla de rutas creada anteriormente. Use el comando az network vnet subnet update para asociar la tabla de rutas a AKS.

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

Implementación de un clúster de AKS que siga las reglas de salida

Ahora puede implementar un clúster AKS en la red virtual existente. Usará el userDefinedRoutingtipo de salida, que garantiza que cualquier tráfico saliente se fuerza a través del firewall y no existirán otras rutas de salida. También se puede usar el loadBalancertipo de salida.

aks-deploy

La subred de destino en la que se va a realizar la implementación se define con la variable de entorno $SUBNETID. Establezca el valor para el ID de subred mediante el siguiente comando:

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

Definirá el tipo de salida para usar el UDR que ya existe en la subred. Esta configuración permitirá a AKS omitir la configuración y el aprovisionamiento de IP para el equilibrador de carga.

Sugerencia

Puede agregar funciones adicionales a la implementación de clústeres, como clústeres privados.

Puede agregar la característica de intervalos IP autorizados del servidor de API de AKS para limitar el acceso del servidor de API solo al punto de conexión público del firewall. La característica de intervalos IP autorizados se indica en el diagrama como opcional. Al habilitar la característica de intervalos de IP autorizados para limitar el acceso del servidor de API, las herramientas de desarrollo deben usar una JumpBox desde la red virtual del firewall, o bien debe agregar todos los puntos de conexión de desarrollador al intervalo de direcciones IP autorizado.


Nota:

AKS creará una identidad de kubelet asignada por el sistema en el grupo de recursos de nodos si no especifica su propia identidad administrada de kubelet.

Para el enrutamiento definido por el usuario, la identidad asignada por el sistema solo admite el complemento de red CNI.

Cree un clúster AKS con una identidad administrada asignada por el sistema con el complemento de red CNI mediante el comando 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

Habilitación del acceso de desarrollador al servidor de API

Si en el paso anterior usó rangos de IP autorizados para su clúster, deberá agregar las direcciones IP de sus herramientas de desarrollo a la lista de rangos de IP autorizados del clúster AKS para poder acceder al servidor API desde allí. También puede configurar un jumpbox con las herramientas necesarias dentro de una subred independiente en la red virtual del firewall.

  1. Recupere su dirección IP mediante el siguiente comando:

    CURRENT_IP=$(dig @resolver1.opendns.com ANY myip.opendns.com +short)
    
  2. Agregue la dirección IP a los rangos aprobados mediante el comando az aks update.

    az aks update -g $RG -n $AKSNAME --api-server-authorized-ip-ranges $CURRENT_IP/32
    
  3. Configure kubectl para conectarse a su clúster AKS mediante el comando az aks get-credentials.

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

Implementación de un servicio público en AKS

Ahora puede empezar a exponer servicios e implementar aplicaciones en este clúster. En este ejemplo, expondremos un servicio público, pero es posible que también desee exponer un servicio interno mediante un equilibrador de carga interno.

DNAT de servicio público

  1. Revise el inicio rápido Demostración de la Tienda de AKS para ver todos los recursos que se crearán.

  2. Implemente el servicio mediante el comando kubectl apply.

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

Permiso para el tráfico de entrada a través de Azure Firewall

Importante

Cuando se usa Azure Firewall para restringir el tráfico de salida y se crea un UDR para forzar todo el tráfico de salida, asegúrese de crear una regla DNAT adecuada en Azure Firewall para permitir correctamente el tráfico de entrada. El uso de Azure Firewall con una UDR interrumpe la configuración de entrada debido al enrutamiento asimétrico. El problema se produce si la subred de AKS tiene una ruta predeterminada que va a la dirección IP privada del firewall, pero está usando un equilibrador de carga público, de entrada o de servicio de Kubernetes del tipo loadBalancer. En este caso, el tráfico entrante del equilibrador de carga se recibe a través de su dirección IP pública, pero la ruta de vuelta pasa a través de la dirección IP privada del firewall. Dado que el firewall es con estado, quita el paquete de vuelta porque el firewall no tiene conocimiento de una sesión establecida. Para aprender a integrar Azure Firewall con el equilibrador de carga de entrada o de servicio, consulte Integración de Azure Firewall con Azure Standard Load Balancer.

Para configurar la conectividad entrante, debe escribir una regla DNAT en Azure Firewall. Para probar la conectividad con el clúster, se define una regla para la dirección IP pública de front-end del firewall que se va a enrutar a la dirección IP interna expuesta por el servicio interno. La dirección de destino puede personalizarse. La dirección traducida debe ser la dirección IP del equilibrador de carga interno. El puerto traducido debe ser el puerto expuesto para el servicio Kubernetes. También es necesario especificar la dirección IP interna asignada al equilibrador de carga creado por el servicio Kubernetes.

  1. Obtenga la dirección IP interna asignada al equilibrador de carga mediante el comando kubectl get services.

    kubectl get services
    

    La dirección IP aparecerá en la columna EXTERNAL-IP, como se muestra en el siguiente ejemplo:

    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. Obtenga la IP del servicio mediante el comando kubectl get svc voting-app.

    SERVICE_IP=$(kubectl get svc store-front -o jsonpath='{.status.loadBalancer.ingress[*].ip}')
    
  3. Agregue la regla NAT mediante el comando 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
    

Validar conectividad

Vaya a la dirección IP de front-end del firewall de Azure en un explorador para validar la conectividad.

Debería ver la aplicación de la tienda de AKS. En este ejemplo, la dirección IP pública del firewall es 52.253.228.132.

Captura de pantalla que muestra la aplicación front-end de Azure Store abierta en un explorador local.

En esta página, puede ver los productos, agregarlos al carro y, a continuación, realizar un pedido.

Limpieza de recursos

Para limpiar los recursos Azure, elimine el grupo de recursos AKS mediante el comando az group delete.

az group delete -g $RG

Pasos siguientes

En este artículo, aprendió cómo asegurar su tráfico saliente mediante Azure Firewall. Si es necesario, puede generalizar los pasos anteriores para reenviar el tráfico a la solución de salida preferida, si sigue la documentación del tipo de salida userDefinedRoute.