Compartir a través de


Implementación de una aplicación web de Amazon Web Services (AWS) en Azure

En este artículo, implementará la aplicación Yelb en el clúster de Azure Kubernetes Service (AKS) que creó en el artículo anterior.

Comprobación del entorno

Antes de implementar la aplicación, asegúrese de que el clúster de AKS esté configurado correctamente mediante los siguientes comandos:

  1. Enumere los espacios de nombres del clúster mediante el comando kubectl get namespace.

    kubectl get namespace
    

    Si instaló el controlador de entrada NGINX mediante el complemento de enrutamiento de aplicaciones, debería ver el espacio de nombres app-routing-system en la salida:

    NAME                 STATUS   AGE
    app-routing-system   Active   4h28m
    cert-manager         Active   109s
    dapr-system          Active   4h18m
    default              Active   4h29m
    gatekeeper-system    Active   4h28m
    kube-node-lease      Active   4h29m
    kube-public          Active   4h29m
    kube-system          Active   4h29m
    

    Si instaló el controlador de entrada NGINX a través de Helm, debería ver el espacio de nombres ingress-basic en la salida:

    NAME                STATUS   AGE
    cert-manager        Active   7m42s
    dapr-system         Active   11m
    default             Active   21m
    gatekeeper-system   Active   20m
    ingress-basic       Active   7m19s
    kube-node-lease     Active   21m
    kube-public         Active   21m
    kube-system         Active   21m
    prometheus          Active   8m9s
    
  2. Obtenga los detalles del servicio del espacio de nombres app-routing-system o ingress-basic mediante kubectl get service command.

    kubectl get service --namespace <namespace-name> -o wide
    

    Si usó el complemento de enrutamiento de aplicación, debería ver que el EXTERNAL-IP del servicio nginx es una dirección IP privada. Esta dirección es la dirección IP privada de una configuración de IP de front-end en el kubernetes-internal equilibrador de carga privado del clúster de AKS:

    NAME    TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE     SELECTOR
    nginx   LoadBalancer   172.16.55.104   10.240.0.7    80:31447/TCP,443:31772/TCP,10254:30459/TCP   4h28m   app=nginx
    

    Si utilizó Helm, debería ver que el EXTERNAL-IP del servicio nginx-ingress-ingress-nginx-controller es una dirección IP privada. Esta dirección es la IP privada de una configuración IP de front-end en el kubernetes-internal equilibrador de carga privado del clúster de AKS.

    NAME                                               TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
    nginx-ingress-ingress-nginx-controller             LoadBalancer   172.16.42.152    10.240.0.7    80:32117/TCP,443:32513/TCP   7m31s
    nginx-ingress-ingress-nginx-controller-admission   ClusterIP      172.16.78.85     <none>        443/TCP                      7m31s
    nginx-ingress-ingress-nginx-controller-metrics     ClusterIP      172.16.109.138   <none>        10254/TCP                    7m31s
    

Preparación para implementar la aplicación Yelb

Si desea implementar el ejemplo mediante la terminación TLS en Application Gateway e invocar Yelb a través de HTTP, puede encontrar los scripts de Bash y las plantillas YAML para implementar la aplicación Yelb en la carpeta http.

Si desea implementar el ejemplo mediante la arquitectura Implementación de TLS de extremo a extremo utilizando Azure Application Gateway, puede encontrar los scripts de Bash y las plantillas YAML para implementar la aplicación web en la carpeta https.

En las secciones restantes de este artículo, le guiaremos a través del proceso de implementación de la aplicación de ejemplo mediante el enfoque TLS de un extremo a otro.

Personalización de variables

  1. Antes de ejecutar los scripts, debe personalizar los valores de las variables en el 00-variables.sh archivo. Este archivo se incluye en todos los scripts y contiene las siguientes variables:

    # Azure subscription and tenant
    RESOURCE_GROUP_NAME="<aks-resource-group>"
    SUBSCRIPTION_ID="$(az account show --query id --output tsv)"
    SUBSCRIPTION_NAME="$(az account show --query name --output tsv)"
    TENANT_ID="$(az account show --query tenantId --output tsv)"
    AKS_CLUSTER_NAME="<aks-name>"
    AGW_NAME="<application-gateway-name>"
    AGW_PUBLIC_IP_NAME="<application-gateway-public-ip-name>"
    DNS_ZONE_NAME="<your-azure-dns-zone-name-eg-contoso.com>"
    DNS_ZONE_RESOURCE_GROUP_NAME="<your-azure-dns-zone-resource-group-name>"
    DNS_ZONE_SUBSCRIPTION_ID="<your-azure-dns-zone-subscription-id>"
    
    # NGINX ingress controller installed via Helm
    NGINX_NAMESPACE="ingress-basic"
    NGINX_REPO_NAME="ingress-nginx"
    NGINX_REPO_URL="https://kubernetes.github.io/ingress-nginx"
    NGINX_CHART_NAME="ingress-nginx"
    NGINX_RELEASE_NAME="ingress-nginx"
    NGINX_REPLICA_COUNT=3
    
    # Specify the ingress class name for the ingress controller
    # - nginx: Unmanaged NGINX ingress controller installed via Helm
    # - webapprouting.kubernetes.azure.com: Managed NGINX ingress controller installed via AKS application routing add-on
    INGRESS_CLASS_NAME="webapprouting.kubernetes.azure.com"
    
    # Subdomain of the Yelb UI service
    SUBDOMAIN="<yelb-application-subdomain>"
    
    # URL of the Yelb UI service
    URL="https://$SUBDOMAIN.$DNS_ZONE_NAME"
    
    # Secret provider class
    KEY_VAULT_NAME="<key-vault-name>"
    KEY_VAULT_CERTIFICATE_NAME="<key-vault-resource-group-name>"
    KEY_VAULT_SECRET_PROVIDER_IDENTITY_CLIENT_ID="<key-vault-secret-provider-identity-client-id>"
    TLS_SECRET_NAME="yelb-tls-secret"
    NAMESPACE="yelb"
    
  2. Puede ejecutar el siguiente comando az aks show para recuperar la clientId de la identidad gestionada asignada por el usuario utilizada por el Azure Key Vault Provider for Secrets Store CSI Driver. El módulo keyVault.bicep con el rol de administrador de Key Vault a la identidad administrada asignada por el usuario del complemento para permitirle recuperar el certificado utilizado por la entrada de Kubernetes utilizado para exponer el servicio yelb-ui a través del controlador de entrada NGINX.

    az aks show \
      --name <aks-name> \
      --resource-group <aks-resource-group-name> \
      --query addonProfiles.azureKeyvaultSecretsProvider.identity.clientId \
      --output tsv \
      --only-show-errors
    
  3. Si ha implementado la infraestructura de Azure mediante los módulos de Bicep proporcionados con este ejemplo, puede continuar con la implementación de la aplicación Yelb. Si desea implementar la aplicación en el clúster de AKS, puede usar los siguientes scripts para configurar el entorno. Puede usar 02-create-nginx-ingress-controller.sh para instalar el controlador de entrada NGINX con el firewall de aplicaciones web de código abierto ModSecurity (WAF) habilitado.

    #!/bin/bash
    
    # Variables
    source ./00-variables.sh
    
    # Check if the NGINX ingress controller Helm chart is already installed
    result=$(helm list -n $NGINX_NAMESPACE | grep $NGINX_RELEASE_NAME | awk '{print $1}')
    
    if [[ -n $result ]]; then
      echo "[$NGINX_RELEASE_NAME] NGINX ingress controller release already exists in the [$NGINX_NAMESPACE] namespace"
    else
      # Check if the NGINX ingress controller repository is not already added
      result=$(helm repo list | grep $NGINX_REPO_NAME | awk '{print $1}')
    
      if [[ -n $result ]]; then
        echo "[$NGINX_REPO_NAME] Helm repo already exists"
      else
        # Add the NGINX ingress controller repository
        echo "Adding [$NGINX_REPO_NAME] Helm repo..."
        helm repo add $NGINX_REPO_NAME $NGINX_REPO_URL
      fi
    
      # Update your local Helm chart repository cache
      echo 'Updating Helm repos...'
      helm repo update
    
      # Deploy NGINX ingress controller
      echo "Deploying [$NGINX_RELEASE_NAME] NGINX ingress controller to the [$NGINX_NAMESPACE] namespace..."
      helm install $NGINX_RELEASE_NAME $NGINX_REPO_NAME/$nginxChartName \
        --create-namespace \
        --namespace $NGINX_NAMESPACE \
        --set controller.nodeSelector."kubernetes\.io/os"=linux \
        --set controller.replicaCount=$NGINX_REPLICA_COUNT \
        --set defaultBackend.nodeSelector."kubernetes\.io/os"=linux \
        --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz
    fi
    
    # Get values
    helm get values $NGINX_RELEASE_NAME --namespace $NGINX_NAMESPACE
    

Implementación de la aplicación

  1. Ejecute el siguiente 03-deploy-yelb.sh script para implementar la aplicación Yelb y un objeto de entrada de Kubernetes para que el yelb-ui servicio sea accesible para la red pública de Internet.

    #!/bin/bash
    
    # Variables
    source ./00-variables.sh
    
    # Check if namespace exists in the cluster
    result=$(kubectl get namespace -o jsonpath="{.items[?(@.metadata.name=='$NAMESPACE')].metadata.name}")
    
    if [[ -n $result ]]; then
      echo "$NAMESPACE namespace already exists in the cluster"
    else
      echo "$NAMESPACE namespace does not exist in the cluster"
      echo "creating $NAMESPACE namespace in the cluster..."
      kubectl create namespace $NAMESPACE
    fi
    
    # Create the Secret Provider Class object
    echo "Creating the secret provider class object..."
    cat <<EOF | kubectl apply -f -
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      namespace: $NAMESPACE
      name: yelb
    spec:
      provider: azure
      secretObjects:
        - secretName: $TLS_SECRET_NAME
          type: kubernetes.io/tls
          data: 
            - objectName: $KEY_VAULT_CERTIFICATE_NAME
              key: tls.key
            - objectName: $KEY_VAULT_CERTIFICATE_NAME
              key: tls.crt
      parameters:
        usePodIdentity: "false"
        useVMManagedIdentity: "true"
        userAssignedIdentityID: $KEY_VAULT_SECRET_PROVIDER_IDENTITY_CLIENT_ID
        keyvaultName: $KEY_VAULT_NAME
        objects: |
          array:
            - |
              objectName: $KEY_VAULT_CERTIFICATE_NAME
              objectType: secret
        tenantId: $TENANT_ID
    EOF
    
    # Apply the YAML configuration
    kubectl apply -f yelb.yml
    
    echo "waiting for secret $TLS_SECRET_NAME in namespace $namespace..."
    
    while true; do
      if kubectl get secret -n $NAMESPACE $TLS_SECRET_NAME >/dev/null 2>&1; then
        echo "secret $TLS_SECRET_NAME found!"
        break
      else
        printf "."
        sleep 3
      fi
    done
    
    # Create chat-ingress
    cat ingress.yml |
      yq "(.spec.ingressClassName)|="\""$INGRESS_CLASS_NAME"\" |
      yq "(.spec.tls[0].hosts[0])|="\""$SUBDOMAIN.$DNS_ZONE_NAME"\" |
      yq "(.spec.tls[0].secretName)|="\""$TLS_SECRET_NAME"\" |
      yq "(.spec.rules[0].host)|="\""$SUBDOMAIN.$DNS_ZONE_NAME"\" |
      kubectl apply -f -
    
    # Check the deployed resources within the yelb namespace:
    kubectl get all -n yelb
    
  2. Actualice el manifiesto yelb-ui YAML para incluir la definición csi volume y volume mount para leer el certificado como secreto desde Azure Key Vault.

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: yelb
  name: yelb-ui
spec:
  replicas: 1
  selector:
    matchLabels:
      app: yelb-ui
      tier: frontend
  template:
    metadata:
      labels:
        app: yelb-ui
        tier: frontend
    spec:
      containers:
        - name: yelb-ui
          image: mreferre/yelb-ui:0.7
          ports:
            - containerPort: 80
          volumeMounts:
            - name: secrets-store-inline
              mountPath: "/mnt/secrets-store"
              readOnly: true
      volumes:
        - name: secrets-store-inline
          csi:
            driver: secrets-store.csi.k8s.io
            readOnly: true
            volumeAttributes:
              secretProviderClass: yelb
  1. Ahora puede implementar la aplicación. El script usa el yelb.yml manifiesto de YAML para implementar la aplicación y el ingress.yml para crear el objeto de entrada. Si usa una zona DNS pública de Azure para la resolución de nombres de dominio, puede emplear el 04-configure-dns.sh script. Este script asocia la dirección IP pública del controlador de entrada NGINX con el dominio usado por el objeto de entrada, que expone el yelb-ui servicio. Este script lleva a cabo los pasos siguientes:

    1. Recupera la dirección pública de la IP pública de Azure utilizada por la configuración de la IP del frontend del Application Gateway.
    2. Comprueba si existe un A registro para el subdominio usado por el yelb-ui servicio.
    3. Si el A registro no existe, el script lo crea.
source ./00-variables.sh

# Get the address of the Application Gateway Public IP
echo "Retrieving the address of the [$AGW_PUBLIC_IP_NAME] public IP address of the [$AGW_NAME] Application Gateway..."
PUBLIC_IP_ADDRESS=$(az network public-ip show \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $AGW_PUBLIC_IP_NAME \
    --query ipAddress \
    --output tsv \
    --only-show-errors)
if [[ -n $PUBLIC_IP_ADDRESS ]]; then
    echo "[$PUBLIC_IP_ADDRESS] public IP address successfully retrieved for the [$AGW_NAME] Application Gateway"
else
    echo "Failed to retrieve the public IP address of the [$AGW_NAME] Application Gateway"
    exit
fi
# Check if an A record for todolist subdomain exists in the DNS Zone
echo "Retrieving the A record for the [$SUBDOMAIN] subdomain from the [$DNS_ZONE_NAME] DNS zone..."
IPV4_ADDRESS=$(az network dns record-set a list \
    --zone-name $DNS_ZONE_NAME \
    --resource-group $DNS_ZONE_RESOURCE_GROUP_NAME \
    --subscription $DNS_ZONE_SUBSCRIPTION_ID \
    --query "[?name=='$SUBDOMAIN'].ARecords[].IPV4_ADDRESS" \
    --output tsv \
    --only-show-errors)
if [[ -n $IPV4_ADDRESS ]]; then
    echo "An A record already exists in [$DNS_ZONE_NAME] DNS zone for the [$SUBDOMAIN] subdomain with [$IPV4_ADDRESS] IP address"
    if [[ $IPV4_ADDRESS == $PUBLIC_IP_ADDRESS ]]; then
        echo "The [$IPV4_ADDRESS] ip address of the existing A record is equal to the ip address of the ingress"
        echo "No additional step is required"
        continue
    else
        echo "The [$IPV4_ADDRESS] ip address of the existing A record is different than the ip address of the ingress"
    fi
    # Retrieving name of the record set relative to the zone
    echo "Retrieving the name of the record set relative to the [$DNS_ZONE_NAME] zone..."
    RECORDSET_NAME=$(az network dns record-set a list \
        --zone-name $DNS_ZONE_NAME \
        --resource-group $DNS_ZONE_RESOURCE_GROUP_NAME \
        --subscription $DNS_ZONE_SUBSCRIPTION_ID \
        --query "[?name=='$SUBDOMAIN'].name" \
        --output tsv \
        --only-show-errors 2>/dev/null)
    if [[ -n $RECORDSET_NAME ]]; then
        echo "[$RECORDSET_NAME] record set name successfully retrieved"
    else
        echo "Failed to retrieve the name of the record set relative to the [$DNS_ZONE_NAME] zone"
        exit
    fi
    # Remove the A record
    echo "Removing the A record from the record set relative to the [$DNS_ZONE_NAME] zone..."
    az network dns record-set a remove-record \
        --ipv4-address $IPV4_ADDRESS \
        --record-set-name $RECORDSET_NAME \
        --zone-name $DNS_ZONE_NAME \
        --resource-group $DNS_ZONE_RESOURCE_GROUP_NAME \
        --subscription $DNS_ZONE_SUBSCRIPTION_ID \
        --only-show-errors 1>/dev/null
    if [[ $? == 0 ]]; then
        echo "[$IPV4_ADDRESS] ip address successfully removed from the [$RECORDSET_NAME] record set"
    else
        echo "Failed to remove the [$IPV4_ADDRESS] ip address from the [$RECORDSET_NAME] record set"
        exit
    fi
fi
# Create the A record
echo "Creating an A record in [$DNS_ZONE_NAME] DNS zone for the [$SUBDOMAIN] subdomain with [$PUBLIC_IP_ADDRESS] IP address..."
az network dns record-set a add-record \
    --zone-name $DNS_ZONE_NAME \
    --resource-group $DNS_ZONE_RESOURCE_GROUP_NAME \
    --subscription $DNS_ZONE_SUBSCRIPTION_ID \
    --record-set-name $SUBDOMAIN \
    --ipv4-address $PUBLIC_IP_ADDRESS \
    --only-show-errors 1>/dev/null
if [[ $? == 0 ]]; then
    echo "A record for the [$SUBDOMAIN] subdomain with [$PUBLIC_IP_ADDRESS] IP address successfully created in [$DNS_ZONE_NAME] DNS zone"
else
    echo "Failed to create an A record for the $SUBDOMAIN subdomain with [$PUBLIC_IP_ADDRESS] IP address in [$DNS_ZONE_NAME] DNS zone"
fi

Nota:

Antes de implementar la aplicación Yelb y crear el ingress objeto, el script genera un SecretProviderClass para recuperar el certificado TLS de Azure Key Vault y generar el secreto de Kubernetes para el ingress objeto. Es importante tener en cuenta que el controlador del almacén de secretos CSI para Key Vault crea el secreto de Kubernetes que contiene el certificado TLS solo cuando la definición de SecretProviderClass y volumen se incluye en el deployment. Para asegurarse de que el certificado TLS se recupera correctamente de Azure Key Vault y se almacena en el secreto de Kubernetes usado por el ingress objeto , es necesario realizar las siguientes modificaciones en el manifiesto YAML de la yelb-ui implementación:

  • Agregue la definición csi volume mediante el controlador secrets-store.csi.k8s.io, que hace referencia al objeto SecretProviderClass responsable de recuperar el certificado TLS de Azure Key Vault.
  • Incluya volume mount para leer el certificado como un secreto de Azure Key Vault.

Para obtener más información, consulte Configurar el Secrets Store CSI Driver para habilitar el Ingress Controller NGINX con TLS.

Prueba de la aplicación

Use el 05-call-yelb-ui.sh script para invocar el servicio, simular la yelb-ui inyección de CÓDIGO SQL, los ataques XSS y observar cómo el conjunto de reglas administradas de ModSecurity bloquea las solicitudes malintencionadas.

#!/bin/bash
# Variables
source ./00-variables.sh
# Call REST API
echo "Calling Yelb UI service at $URL..."
curl -w 'HTTP Status: %{http_code}\n' -s -o /dev/null $URL
# Simulate SQL injection
echo "Simulating SQL injection when calling $URL..."
curl -w 'HTTP Status: %{http_code}\n' -s -o /dev/null $URL/?users=ExampleSQLInjection%27%20--
# Simulate XSS
echo "Simulating XSS when calling $URL..."
curl -w 'HTTP Status: %{http_code}\n' -s -o /dev/null $URL/?users=ExampleXSS%3Cscript%3Ealert%28%27XSS%27%29%3C%2Fscript%3E
# A custom rule blocks any request with the word blockme in the querystring.
echo "Simulating query string manipulation with the 'blockme' word in the query string..."
curl -w 'HTTP Status: %{http_code}\n' -s -o /dev/null $URL/?users?task=blockme

El script de Bash debe generar la siguiente salida, donde la primera llamada se realiza correctamente, mientras que las reglas ModSecurity bloquean las dos llamadas siguientes:

Calling Yelb UI service at https://yelb.contoso.com...
HTTP Status: 200
Simulating SQL injection when calling https://yelb.contoso.com...
HTTP Status: 403
Simulating XSS when calling https://yelb.contoso.com...
HTTP Status: 403
Simulating query string manipulation with the 'blockme' word in the query string...
HTTP Status: 403

Supervisar la aplicación

En la solución propuesta, el proceso de implementación configura automáticamente el recurso de Azure Application Gateway para recopilar logs de diagnóstico y métricas en un espacio de trabajo de Azure Log Analytics. Al habilitar los registros, puede obtener información valiosa sobre las evaluaciones, las coincidencias y los bloqueos realizados por el Azure Web Application Firewall (WAF) dentro de Application Gateway. Para más información, consulte Registros de diagnóstico para Application Gateway. También puede usar Log Analytics para examinar los datos de los registros del firewall. Cuando tenga los registros del firewall en el área de trabajo de Log Analytics, puede ver datos, escribir consultas, crear visualizaciones y agregarlas al panel del portal. Para obtener información detallada sobre las consultas de registro, consulte Introducción a las consultas de registro en Azure Monitor.

Exploración de datos con consultas de Kusto

En la solución propuesta, el proceso de implementación configura automáticamente el recurso de Azure Application Gateway para recopilar registros de diagnóstico y métricas en un área de trabajo de Azure Log Analytics. Al habilitar los registros, puede obtener información sobre las evaluaciones, las coincidencias y los bloques realizados por Azure Web Application Firewall (WAF) dentro de Application Gateway. Para más información, consulte Registros de diagnóstico para Application Gateway.

También puede usar Log Analytics para examinar los datos de los registros del firewall. Cuando tenga los registros del firewall en el área de trabajo de Log Analytics, puede ver datos, escribir consultas, crear visualizaciones y agregarlas al panel del portal. Para más información sobre las consultas de registro, consulte Introducción a las consultas de registro en Azure Monitor.

AzureDiagnostics 
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog"
| limit 10

Como alternativa, cuando se trabaja con la tabla específica de recursos, se puede acceder a los datos de registro de firewall sin procesar mediante la siguiente consulta. Para más información sobre las tablas específicas de recursos, consulte la documentación de referencia de datos de supervisión .

AGWFirewallLogs
| limit 10

Una vez que tenga los datos, puede profundizar y crear gráficos o visualizaciones. Estos son algunos ejemplos adicionales de consultas KQL que se pueden usar:

Solicitudes emparejadas o bloqueadas por IP

AzureDiagnostics
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog"
| summarize count() by clientIp_s, bin(TimeGenerated, 1m)
| render timechart

Solicitudes emparejadas o bloqueadas por URI

AzureDiagnostics
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog"
| summarize count() by requestUri_s, bin(TimeGenerated, 1m)
| render timechart

Principales reglas emparejadas

| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog"
| summarize count() by ruleId_s, bin(TimeGenerated, 1m)
| where count_ > 10
| render timechart

Principales cinco grupos de reglas emparejadas

AzureDiagnostics
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog"
| summarize Count=count() by details_file_s, action_s
| top 5 by Count desc
| render piechart

Revisión de los recursos implementados

Puede usar la CLI de Azure o Azure PowerShell para enumerar los recursos implementados en el grupo de recursos.

Enumere los recursos implementados en el grupo de recursos mediante el comando [az resource list][az-resource-list].

az resource list --resource-group <resource-group-name>

Puede usar la CLI de Azure o Azure PowerShell para eliminar el grupo de recursos cuando ya no necesite los recursos que creó en este tutorial.

Elimine el grupo de recursos y sus recursos asociados mediante el az group delete comando .

az group delete --name <resource-group-name>

Pasos siguientes

Puede aumentar la seguridad y la protección contra amenazas de la solución mediante Azure DDoS Protection y Azure Firewall. Para obtener más información, consulte los artículos siguientes:

Si usa el controlador de entrada NGINX o cualquier otro controlador de entrada hospedado de AKS en lugar de Azure Application Gateway, puede usar Azure Firewall para inspeccionar el tráfico hacia y desde el clúster de AKS y proteger el clúster contra la filtración de datos y otro tráfico de red no deseado. Para obtener más información, consulte los artículos siguientes:

Colaboradores

Microsoft mantiene este artículo. Los siguientes colaboradores lo escribieron originalmente:

Autor principal:

Otros colaboradores: