Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
In questo articolo si distribuisce l'applicazione Yelb nel cluster Servizio Azure Kubernetes (AKS) creato nell'articolo previous article.
Controllare l'ambiente
Prima di distribuire l'applicazione, assicurarsi che il cluster del servizio Azure Kubernetes sia configurato correttamente usando i comandi seguenti:
Elencare gli spazi dei nomi nel proprio cluster usando il comando
kubectl get namespace.kubectl get namespaceSe è stato installato il controller di ingresso NGINX usando il componente aggiuntivo di routing dell'applicazione, lo spazio dei nomi è visualizzabile
app-routing-systemnell'output: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 4h29mSe è stato installato il controller di ingresso NGINX tramite Helm, verrà visualizzato
ingress-basicnello spazio dei nomi dell'output.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 8m9sOttenere i dettagli del servizio dello spazio dei nomi
app-routing-systemo ilingress-basicusando ilkubectl get service command.kubectl get service --namespace <namespace-name> -o wideSe hai usato il componente aggiuntivo di routing dell'applicazione, dovresti vedere che
EXTERNAL-IPdel servizionginxè un indirizzo IP privato. Questo indirizzo corrisponde all'IP privato di una configurazione IP front-end nel Load balancer privatokubernetes-internaldel cluster 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=nginxSe è stato usato Helm, si noterà che il
EXTERNAL-IPdelnginx-ingress-ingress-nginx-controllerservizio è un indirizzo IP privato. Questo indirizzo è l'indirizzo IP privato di una configurazione IP front-end nel servizio di bilanciamento del carico privato del cluster 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
Preparare la distribuzione dell'applicazione Yelb
Se si vuole distribuire l'esempio usando la terminazione TLS nel gateway applicativo e l'invocazione di Yelb tramite HTTP, è possibile trovare gli script Bash e i modelli YAML per distribuire l'applicazione Yelb nella cartella http.
Se si vuole distribuire l'esempio usando l'architettura Implementazione di TLS end-to-end tramite gateway applicazione di Azure, è possibile trovare gli script Bash e i modelli YAML per distribuire l'applicazione web nella cartella https.
Nelle sezioni rimanenti di questo articolo viene illustrato il processo di distribuzione dell'applicazione di esempio usando l'approccio TLS end-to-end.
Personalizzare le variabili
Prima di eseguire qualsiasi script, è necessario personalizzare i valori delle variabili nel
00-variables.shfile. Questo file è incluso in tutti gli script e contiene le variabili seguenti:# 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"È possibile eseguire il comando seguente az aks show per recuperare il
clientIddell'identità gestita assegnata dall'utente usata dal provider di Azure Key Vault per il driver CSI dell'archivio segreti. IlkeyVault.bicepmodulo Amministratore Key Vault viene assegnato all'identità gestita dall'utente del componente aggiuntivo affinché possa recuperare il certificato utilizzato da Kubernetes Ingress per esporre ilyelb-uiservizio tramite il controller di ingresso NGINX.az aks show \ --name <aks-name> \ --resource-group <aks-resource-group-name> \ --query addonProfiles.azureKeyvaultSecretsProvider.identity.clientId \ --output tsv \ --only-show-errorsSe l'infrastruttura di Azure è stata distribuita usando i moduli Bicep forniti con questo esempio, è possibile procedere a distribuire l'applicazione Yelb. Se si vuole distribuire l'applicazione nel cluster del servizio Azure Kubernetes, è possibile usare gli script seguenti per configurare l'ambiente. È possibile usare
02-create-nginx-ingress-controller.shper installare il controller di ingresso NGINX con ModSecurity open source web application firewall (WAF) abilitato.#!/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
Distribuire l'applicazione
Eseguire lo script seguente
03-deploy-yelb.shper distribuire l'applicazione Yelb e un oggetto Ingress Kubernetes per rendere ilyelb-uiservizio accessibile alla rete Internet pubblica.#!/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 yelbAggiornare il manifesto YAML
yelb-uiper includere la definizionecsi volumee utilizzarevolume mountper leggere il certificato come segreto da 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
È ora possibile distribuire l'applicazione. Lo script utilizza il
yelb.ymlmanifesto YAML per distribuire l'applicazione e per creare l'oggetto Ingress con ilingress.yml. Se si usa una zona DNS pubblicaAzure per la risoluzione dei nomi di dominio, è possibile usare lo script04-configure-dns.sh. Questo script associa l'indirizzo IP pubblico del controller di ingresso NGINX al dominio usato dall'oggetto in ingresso, che espone ilyelb-uiservizio. Lo script esegue le operazioni seguenti:- Recupera l'indirizzo IP pubblico di Azure utilizzato dalla configurazione IP del front-end dell'Application Gateway.
- Controlla se esiste un
Arecord per il sottodominio usato dalyelb-uiservizio. - Se il
Arecord non esiste, lo 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
Annotazioni
Prima di distribuire l'applicazione Yelb e creare l'oggetto ingress, lo script genera un SecretProviderClass per recuperare il certificato TLS da Azure Key Vault e generare il segreto Kubernetes per l'oggetto ingress. È importante notare che il Secrets Store CSI Driver for Key Vault crea il segreto Kubernetes contenente il certificato TLS solo quando la definizione di SecretProviderClass e del volume è inclusa nel deployment. Per assicurarsi che il certificato TLS venga recuperato correttamente da Azure Key Vault e archiviato nel segreto Kubernetes usato dall'oggetto ingress, è necessario apportare le modifiche seguenti al manifesto YAML della distribuzione di yelb-ui:
- Aggiungere la definizione di
csi volumeutilizzando il driversecrets-store.csi.k8s.io, che fa riferimento all'oggettoSecretProviderClassresponsabile del recupero del certificato TLS da Azure Key Vault. - Includere
volume mountper leggere il certificato come segreto da Azure Key Vault.
Per ulteriori informazioni, vedere Impostare il Secrets Store CSI Driver per abilitare l'ingress controller NGINX con TLS.
Testare l'applicazione
Usare lo 05-call-yelb-ui.sh script per richiamare il yelb-ui servizio, simulare attacchi SQL injection, XSS e osservare il modo in cui il set di regole gestito di ModSecurity blocca le richieste dannose.
#!/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
Lo script Bash deve produrre l'output seguente, in cui la prima chiamata ha esito positivo, mentre le regole ModSecurity bloccano le due chiamate seguenti:
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
Monitorare l'applicazione
Nella soluzione proposta, il processo di distribuzione configura automaticamente la risorsa gateway applicazione di Azure per raccogliere i log di diagnostica e le metriche in un'area di lavoro Log Analytics di Azure. Abilitando i log, è possibile ottenere informazioni dettagliate importanti sulle valutazioni, le corrispondenze e i blocchi eseguiti dal Web application firewall di Azure (WAF) all'interno dell'Application Gateway. Per ulteriori informazioni, vedere Registri diagnostici per Application Gateway. È anche possibile usare Log Analytics per esaminare i dati all'interno dei log del firewall. Quando si dispone dei log del firewall nell'area di lavoro Log Analytics, è possibile visualizzare i dati, scrivere query, creare visualizzazioni e aggiungerli al dashboard del portale. Per informazioni dettagliate sulle query di log, vedere Panoramica delle query di log in Monitoraggio di Azure.
Esplorare i dati con le query di Kusto
Nella soluzione proposta, il processo di distribuzione configura automaticamente la risorsa gateway applicazione di Azure per raccogliere i log di diagnostica e le metriche in un'area di lavoro Log Analytics di Azure. Abilitando i log, è possibile ottenere informazioni dettagliate sulle valutazioni, le corrispondenze e i blocchi eseguiti dal Web application firewall di Azure (WAF) all'interno del gateway applicazione. Per ulteriori informazioni, vedere Registri diagnostici per Application Gateway.
È anche possibile usare Log Analytics per esaminare i dati all'interno dei log del firewall. Quando si dispone dei log del firewall nell'area di lavoro Log Analytics, è possibile visualizzare i dati, scrivere query, creare visualizzazioni e aggiungerli al dashboard del portale. Per altre informazioni sulle query di log, vedere Panoramica delle query di log in Monitoraggio di Azure.
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog"
| limit 10
In alternativa, quando si usa la tabella specifica della risorsa , è possibile accedere ai dati di log del firewall non elaborati usando la query seguente. Per altre informazioni sulle tabelle specifiche delle risorse, vedere la documentazione di riferimento sui dati di monitoraggio .
AGWFirewallLogs
| limit 10
Dopo aver ottenuto i dati, è possibile approfondire e creare grafici o visualizzazioni. Ecco alcuni esempi aggiuntivi di query KQL che possono essere usate:
Richieste abbinate e bloccate per indirizzo IP
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog"
| summarize count() by clientIp_s, bin(TimeGenerated, 1m)
| render timechart
Richieste corrispondenti/bloccate per URI
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog"
| summarize count() by requestUri_s, bin(TimeGenerated, 1m)
| render timechart
Regole corrispondenti principali
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog"
| summarize count() by ruleId_s, bin(TimeGenerated, 1m)
| where count_ > 10
| render timechart
Primi cinque gruppi di regole corrispondenti
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayFirewallLog"
| summarize Count=count() by details_file_s, action_s
| top 5 by Count desc
| render piechart
Esaminare le risorse distribuite
È possibile usare interfaccia della riga di comando di Azure o Azure PowerShell per elencare le risorse distribuite nel gruppo di risorse.
Elencare le risorse distribuite nel gruppo di risorse usando il comando [az resource list][az-resource-list].
az resource list --resource-group <resource-group-name>
È possibile usare interfaccia della riga di comando di Azure o Azure PowerShell per eliminare il gruppo di risorse quando non sono più necessarie le risorse create in questa esercitazione.
Eliminare il gruppo di risorse e le risorse associate usando il az group delete comando .
az group delete --name <resource-group-name>
Passaggi successivi
È possibile aumentare la sicurezza e la protezione dalle minacce della soluzione usando Azure Protezione DDoS e Firewall di Azure. Per altre informazioni, consultare gli articoli seguenti:
- Tutorial: proteggere il gateway delle applicazioni con la protezione di rete DDoS di Azure
- Firewall e gateway applicativo per le reti virtuali
- Rete Zero Trust per applicazioni Web con Firewall di Azure e Application Gateway
Se si usa il controller di ingresso NGINX o qualsiasi altro controller di ingresso ospitato nel servizio Azure Kubernetes al posto del gateway applicazione di Azure, è possibile usare il Firewall di Azure per controllare il traffico da e verso il cluster del servizio Azure Kubernetes e proteggere il cluster dall'esfiltrazione di dati e da altri traffico di rete indesiderato. Per altre informazioni, consultare gli articoli seguenti:
- Usare Firewall di Azure per proteggere i cluster del servizio Azure Kubernetes (AKS)
- Usare Firewall di Azure per proteggere un cluster Servizio Azure Kubernetes (AKS)
Contributori
Microsoft gestisce questo articolo. I collaboratori seguenti l'hanno originariamente scritto:
Autore principale:
- Paolo Salvatori | Ingegnere Principale per i Clienti
Altri contributori:
- Ken Kilty | Manager Tecnico Principale
- Russell de Pina | TPM principale
- Erin Schaffer | Content Developer 2