AWS(Amazon Web Services) 웹 애플리케이션을 Azure로 배포하기

이 문서에서는 당신이 이전 문서에서 만든 AKS(Azure Kubernetes Service) 클러스터에 Yelb 애플리케이션을 배포합니다.

환경 확인

애플리케이션을 배포하기 전에 다음 명령을 사용하여 AKS 클러스터가 제대로 구성되었는지 확인합니다.

  1. 명령을 사용하여 클러스터의 네임스페이스를 나열합니다 kubectl get namespace .

    kubectl get namespace
    

    애플리케이션 라우팅 추가 기능을 사용하여 NGINX 인그레스 컨트롤러를 설치한 경우 출력에 네임스페이스 app-routing-system가 표시됩니다.

    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
    

    Helm을 통해 NGINX 수신 컨트롤러를 설치한 경우 출력에 ingress-basic 네임스페이스가 표시됩니다.

    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. kubectl get service command을(를) 사용하여 app-routing-system 또는 ingress-basic 네임스페이스의 서비스 세부 정보를 가져옵니다.

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

    애플리케이션 라우팅 추가 기능을 사용한 경우 서비스의 개인 IP 주소가 표시됩니다 EXTERNAL-IPnginx . 이 주소는 AKS 클러스터의 프라이빗 부하 분산 장치에 있는 kubernetes-internal 프런트 엔드 IP 구성의 개인 IP입니다.

    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
    

    Helm을 사용한 경우, nginx-ingress-ingress-nginx-controller 서비스의 EXTERNAL-IP가 개인 IP 주소로 표시됩니다. 이 주소는 AKS 클러스터의 프라이빗 부하 분산 장치에 있는 kubernetes-internal 프런트 엔드 IP 구성의 개인 IP입니다.

    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
    

Yelb 애플리케이션 배포 준비

HTTP 접근 방식이 아닌 Application Gateway에서 TLS 종료 및 Yelb 호출 방식을 사용하여 샘플을 배포하려는 경우, http 폴더에서 Yelb 애플리케이션을 배포하기 위한 Bash 스크립트 및 YAML 템플릿을 찾을 수 있습니다.

Azure Application Gateway 아키텍처를 사용하여 엔드투엔드 TLS를 사용하여 샘플을 배포하려는 경우 Bash 스크립트 및 YAML 템플릿을 찾아 https 폴더에 웹 애플리케이션을 배포할 수 있습니다.

이 문서의 나머지 섹션에서는 엔드투엔드 TLS 접근 방식을 사용하여 샘플 애플리케이션의 배포 프로세스를 안내합니다.

변수 사용자 지정

  1. 스크립트를 실행하기 전에 파일의 변수 값을 사용자 지정해야 합니다 00-variables.sh . 이 파일은 모든 스크립트에 포함되며 다음 변수를 포함합니다.

    # 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. 다음 az aks show 명령을 실행하여 Azure Key Vault 비밀 저장소 CSI 드라이버 공급자에서 사용하는 clientId 검색할 수 있습니다. keyVault.bicep 모듈은 애드온의 사용자 할당 관리형 ID에 Key Vault Administrator 역할을 부여하여, Kubernetes Ingress에서 사용하는 인증서를 가져올 수 있도록 하고, 이 인증서는 NGINX ingress controller를 통해 yelb-ui 서비스를 외부에 노출하는 데 사용됩니다.

    az aks show \
      --name <aks-name> \
      --resource-group <aks-resource-group-name> \
      --query addonProfiles.azureKeyvaultSecretsProvider.identity.clientId \
      --output tsv \
      --only-show-errors
    
  3. 이 샘플과 함께 제공되는 Bicep 모듈을 사용하여 Azure 인프라를 배포한 경우 Yelb 애플리케이션을 배포할 수 있습니다. AKS 클러스터에 애플리케이션을 배포하려는 경우 다음 스크립트를 사용하여 환경을 구성할 수 있습니다. 02-create-nginx-ingress-controller.sh NGINX 수신 컨트롤러ModSecurity 오픈 소스 웹 애플리케이션 방화벽(WAF)이 사용 가능하도록 설정하여 설치할 수 있습니다.

    #!/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
    

애플리케이션 배포

  1. 다음 03-deploy-yelb.sh 스크립트를 실행하여 Yelb 애플리케이션과 쿠버네티스 인그레스 개체를 배포하고, 이를 통해 공용 인터넷에서 yelb-ui 서비스에 액세스할 수 있도록 합니다.

    #!/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. yelb-ui YAML 매니페스트에 csi volume 정의와 volume mount를 포함하도록 업데이트하여 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. 이제 애플리케이션을 배포할 수 있습니다. 스크립트는 yelb.yml YAML 매니페스트를 사용하여 애플리케이션을 배포하고 ingress.yml 인그레스 오브젝트를 만듭니다. 도메인 이름 확인에 Azure 공용 DNS 영역 사용하는 경우 04-configure-dns.sh 스크립트를 사용할 수 있습니다. 이 스크립트는 NGINX 수신 컨트롤러의 공용 IP 주소를 수신 개체에서 사용하는 도메인과 연결하여 서비스를 노출합니다 yelb-ui . 스크립트에서 수행하는 단계는 다음과 같습니다.

    1. Application Gateway의 프런트 엔드 IP 구성에서 사용하는 Azure 공용 IP의 공용 주소를 검색합니다.
    2. yelb-ui 서비스에서 사용하는 하위 도메인에 A 레코드가 있는지 확인합니다.
    3. 레코드가 A 존재하지 않으면, 스크립트가 레코드를 생성합니다.
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

메모

Yelb 애플리케이션을 배포하고 ingress 개체를 만들기 전에 스크립트는 SecretProviderClass 생성하여 Azure Key Vault TLS 인증서를 검색하고 ingress 개체에 대한 Kubernetes 비밀을 생성합니다. Secrets Store CSI Driver for Key VaultSecretProviderClass 및 볼륨 정의가 deployment에 포함된 경우에만 TLS 인증서가 담긴 Kubernetes 시크릿을 생성합니다. TLS 인증서가 Azure Key Vault 제대로 검색되고 ingress 개체에서 사용하는 Kubernetes 비밀에 저장되도록 하려면 yelb-ui 배포의 YAML 매니페스트를 다음과 같이 수정해야 합니다.

  • Azure Key Vault TLS 인증서를 검색하는 csi volume 개체를 참조하는 secrets-store.csi.k8s.io 드라이버를 사용하여 SecretProviderClass 정의를 추가합니다.
  • 인증서를 Azure Key Vault의 비밀로 읽으려면 volume mount을 포함하세요.

자세한 내용은 비밀 저장소 CSI 드라이버 설정을 참조하여 TLS에서 NGINX 수신 컨트롤러를 사용하도록 설정합니다.

애플리케이션 테스트

스크립트를 05-call-yelb-ui.sh 사용하여 서비스를 호출 yelb-ui 하고, SQL 삽입, XSS 공격을 시뮬레이션하고, ModSecurity의 관리되는 규칙 집합이 악의적인 요청을 차단하는 방법을 관찰합니다.

#!/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

Bash 스크립트는 첫 번째 호출이 성공하는 다음 출력을 생성해야 하며 ModSecurity 규칙은 다음 두 호출을 차단합니다.

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

응용 프로그램 모니터링

제안된 솔루션에서 배포 프로세스는 Azure Application Gateway 리소스를 자동으로 구성하여 진단 로그 및 메트릭을 Azure Log Analytics 작업 영역 작업 영역에 수집합니다. 로그를 사용하도록 설정하면 Application Gateway 내에서 WAF(Azure Web Application Firewall) 수행되는 평가, 일치 및 블록에 대한 중요한 인사이트를 얻을 수 있습니다. 자세한 내용은 Application Gateway에 대한 진단 로그를 참조하세요. Log Analytics 사용하여 방화벽 로그 내의 데이터를 검사할 수도 있습니다. Log Analytics 작업 영역에 방화벽 로그가 있는 경우 데이터를 보고, 쿼리를 작성하고, 시각화를 만들고, 포털 대시보드에 추가할 수 있습니다. 로그 쿼리에 대한 자세한 내용은 Azure Monitor 참조하세요.

Kusto 쿼리를 사용하여 데이터 탐색

제안된 솔루션에서 배포 프로세스는 Azure Application Gateway 리소스를 자동으로 구성하여 진단 로그 및 메트릭을 Azure Log Analytics 작업 영역 수집합니다. 로그를 사용하도록 설정하면 Application Gateway 내에서 Azure Web Application Firewall(WAF) 수행되는 평가, 일치 및 블록에 대한 인사이트를 얻을 수 있습니다. 자세한 내용은 Application Gateway에 대한 진단 로그를 참조하세요.

Log Analytics 사용하여 방화벽 로그 내의 데이터를 검사할 수도 있습니다. Log Analytics 작업 영역에 방화벽 로그가 있는 경우 데이터를 보고, 쿼리를 작성하고, 시각화를 만들고, 포털 대시보드에 추가할 수 있습니다. 로그 쿼리에 대한 자세한 내용은 Azure Monitor 참조하세요.

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

또는 리소스별 테이블로 작업할 때 다음 쿼리를 사용하여 원시 방화벽 로그 데이터에 액세스할 수 있습니다. 리소스별 테이블에 대한 자세한 내용은 모니터링 데이터 참조 설명서를 참조하세요.

AGWFirewallLogs
| limit 10

데이터가 있으면 더 자세히 살펴보고 그래프 또는 시각화를 만들 수 있습니다. 다음은 활용할 수 있는 KQL 쿼리의 몇 가지 추가 예입니다.

IP별 일치/차단된 요청

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

URI별 일치/차단된 요청

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

상위 일치 규칙

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

상위 5개 일치 규칙 그룹

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

배포된 리소스 검토

Azure CLI 또는 Azure PowerShell 사용하여 리소스 그룹에 배포된 리소스를 나열할 수 있습니다.

[az resource list][az-resource-list] 명령을 사용하여 리소스 그룹에 배포된 리소스를 나열합니다.

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

이 자습서에서 만든 리소스가 더 이상 필요하지 않은 경우 Azure CLI 또는 Azure PowerShell 사용하여 리소스 그룹을 삭제할 수 있습니다.

명령을 사용하여 리소스 그룹 및 관련 리소스를 az group delete 삭제합니다.

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

다음 단계

Azure DDoS ProtectionAzure Firewall 사용하여 솔루션의 보안 및 위협 방지를 강화할 수 있습니다. 자세한 내용은 다음 문서를 참조하세요.

NGINX 수신 컨트롤러 또는 Azure Application Gateway 대신 호스팅되는 다른 AKS 수신 컨트롤러를 사용하는 경우 Azure Firewall 사용하여 AKS 클러스터와 주고받은 트래픽을 검사하고 데이터 반출 및 기타 원치 않는 네트워크 트래픽으로부터 클러스터를 보호할 수 있습니다. 자세한 내용은 다음 문서를 참조하세요.

기여자

Microsoft 이 문서를 유지 관리합니다. 다음 기여자는 원래 그것을 썼다:

대표 저자:

기타 기여자: