기존 Application Gateway를 사용하여 AGIC(Application Gateway 수신 컨트롤러) 설치

AGIC(Application Gateway 수신 컨트롤러)는 AKS(Azure Kubernetes Service) 클러스터 내의 Pod입니다. AGIC는 Kubernetes 수신 리소스를 모니터링하고 Kubernetes 클러스터의 상태에 따라 Application Gateway 구성을 만들고 적용합니다.

컨테이너용 Application Gateway란?도 참조 하세요.

개요

필수 조건

이 문서에서는 다음과 같은 도구 및 인프라가 이미 설치되어 있다고 가정합니다.

AGIC를 설치하기 전에 Application Gateway 구성을 백업하세요.

  1. Azure Portal에서 Application Gateway 인스턴스로 이동합니다.
  2. 자동화 섹션에서 템플릿 내보내기를 선택한 다음 다운로드를 선택합니다.

다운로드한 zip 파일에는 필요한 경우 App Gateway를 복원하는 데 사용할 수 있는 JSON 템플릿, bash 및 PowerShell 스크립트가 포함되어 있습니다.

Helm 설치

Helm은 Kubernetes의 패키지 관리자로 application-gateway-kubernetes-ingress 패키지를 설치하는 데 사용됩니다.

참고 항목

Cloud Shell을 사용하는 경우에는 Helm을 설치할 필요가 없습니다. Azure Cloud Shell은 Helm 버전 3과 함께 제공됩니다. 첫 번째 단계를 건너뛰고 AGIC Helm 리포지토리만 추가합니다.

  1. Helm을 설치하고 다음을 실행하여 application-gateway-kubernetes-ingress Helm 패키지를 추가합니다.

    • Kubernetes RBAC를 사용하는 AKS 클러스터
    kubectl create serviceaccount --namespace kube-system tiller-sa
    kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller-sa
    helm init --tiller-namespace kube-system --service-account tiller-sa
    
  2. AGIC 리포지토리를 추가합니다.

    helm repo add application-gateway-kubernetes-ingress https://appgwingress.blob.core.windows.net/ingress-azure-helm-package/
    helm repo update
    

Azure Resource Manager 인증

AGIC는 Kubernetes API 서버 및 Azure Resource Manager와 통신합니다. 이러한 API에 액세스하려면 ID가 필요합니다.

Microsoft Entra 워크로드 ID 설치

Microsoft Entra 워크로드 ID는 다른 서비스 및 리소스를 인증하고 액세스하기 위해 소프트웨어 워크로드에 할당하는 ID입니다. 이 ID를 사용하면 AKS Pod에서 이 ID를 사용하고 다른 Azure 리소스로 인증할 수 있습니다. 이 구성에서 ARM에 대한 HTTP 요청을 수행하려면 AGIC Pod에 대한 권한 부여가 필요합니다.

  1. Azure CLI az account set 명령을 사용하여 특정 구독을 현재 활성 구독으로 설정합니다. 그런 다음, 관리 ID를 만들려면 az identity create 명령을 사용합니다. 노드 리소스 그룹에서 ID를 만들어야 합니다. 노드 리소스 그룹에는 기본적으로 MC_myResourceGroup_myAKSCluster_eastus와 같은 이름이 할당됩니다.

    az account set --subscription "subscriptionID"
    
    az identity create --name "userAssignedIdentityName" --resource-group "resourceGroupName" --location "location" --subscription "subscriptionID"
    
  2. 역할 할당의 경우 다음 명령을 실행하여 새로 만든 ID에 대해 principalId를 식별합니다.

    $resourceGroup="resource-group-name"
    $identityName="identity-name"
    az identity list -g $resourceGroup --query "[?name == '$identityName'].principalId | [0]" -o tsv
    
  3. ID 기여자에 Application Gateway에 대한 액세스 권한을 부여합니다. 다음과 같은 Application Gateway의 ID가 필요합니다. /subscriptions/A/resourceGroups/B/providers/Microsoft.Network/applicationGateways/C 먼저 다음 명령을 실행하여 구독의 Application Gateway ID 목록을 가져옵니다.

    az network application-gateway list --query '[].id'
    

    ID 기여자에 액세스 권한을 할당하려면 다음 명령을 실행합니다.

    $resourceGroup="resource-group-name"
    $identityName="identity-Name"
    # Get the Application Gateway ID
    $AppGatewayID=$(az network application-gateway list --query '[].id' -o tsv)
    $role="contributor"
    # Get the principal ID for the User assigned identity
    $principalId=$(az identity list -g $resourceGroup --query "[?name == '$identityName'].principalId | [0]" -o tsv)
    az role assignment create --assignee $principalId --role $role --scope $AppGatewayID
    
  4. ID 판독기에 Application Gateway 리소스 그룹에 대한 액세스 권한을 부여합니다. 리소스 그룹 ID 형식은 다음과 같습니다. /subscriptions/A/resourceGroups/B az group list --query '[].id'를 사용하여 모든 리소스 그룹을 가져올 수 있습니다.

    $resourceGroup="resource-group-name"
    $identityName="identity-Name"
    # Get the Application Gateway resource group
    $AppGatewayResourceGroup=$(az network application-gateway list --query '[].resourceGroup' -o tsv)
    # Get the Application Gateway resource group ID
    $AppGatewayResourceGroupID=$(az group show --name $AppGatewayResourceGroup --query id -o tsv)
    $role="Reader"
    # Get the principal ID for the User assigned identity
    $principalId=$(az identity list -g $resourceGroup --query "[?name == '$identityName'].principalId | [0]" -o tsv)
    # Assign the Reader role to the User assigned identity at the resource group scope
    az role assignment create --role $role --assignee $principalId  --scope $AppGatewayResourceGroupID
    

참고 항목

AGIC에서 사용하는 ID에 Application Gateway이 배포된 서브넷에 위임된 Microsoft.Network/virtualNetworks/subnets/join/action 권한이 있는지 확인하세요. 사용자 지정 역할이 이 권한으로 정의되지 않은 경우 Microsoft.Network/virtualNetworks/subnets/join/action 권한이 포함된 기본 제공 네트워크 기여자 역할을 사용할 수 있습니다.

서비스 주체 사용

Kubernetes 암호를 사용하여 ARM에 대한 액세스 권한을 AGIC에 제공할 수도 있습니다.

  1. Active Directory 서비스 주체를 만들고 base64로 인코딩합니다. base64 인코딩은 JSON blob을 Kubernetes에 저장하는 데 필요합니다.

    az ad sp create-for-rbac --role Contributor --sdk-auth | base64 -w0
    
  2. base64 인코딩 JSON blob을 helm-config.yaml 파일에 추가합니다. helm-config.yaml에 대한 자세한 내용은 다음 섹션에 나와 있습니다.

    armAuth:
        type: servicePrincipal
        secretJSON: <Base64-Encoded-Credentials>
    

Azure Application Gateway 수신 컨트롤러 추가 항목 배포

수신 컨트롤러 배포 매니페스트 만들기

---
# file: pet-supplies-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: pet-supplies-ingress
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway

spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: store-front
            port:
              number: 80
      - path: /order-service
        pathType: Prefix
        backend:
          service:
            name: order-service
            port:
              number: 3000
      - path: /product-service
        pathType: Prefix
        backend:
          service:
            name: product-service
            port:
              number: 3002

수신 컨트롤러 배포

$namespace="namespace"
$file="pet-supplies-ingress.yaml"
kubectl apply -f $file -n $namespace

수신 컨트롤러를 Helm Chart로 설치

처음 몇 단계에서 Kubernetes 클러스터에 Helm의 Tiller을 설치합니다. Cloud Shell를 사용하여 AGIC Helm 패키지를 설치합니다.

  1. application-gateway-kubernetes-ingress Helm 리포지토리를 추가하고 Helm 업데이트를 수행합니다.

    helm repo add application-gateway-kubernetes-ingress https://appgwingress.blob.core.windows.net/ingress-azure-helm-package/
    helm repo update
    
  2. AGIC를 구성하는 helm-config.xml을 다운로드합니다.

    wget https://raw.githubusercontent.com/Azure/application-gateway-kubernetes-ingress/master/docs/examples/sample-helm-config.yaml -O helm-config.yaml
    

    또는 다음 YAML 파일을 복사합니다.

    # This file contains the essential configs for the ingress controller helm chart
    
    # Verbosity level of the App Gateway Ingress Controller
    verbosityLevel: 3
    
    ################################################################################
    # Specify which application gateway the ingress controller must manage
    #
    appgw:
        subscriptionId: <subscriptionId>
        resourceGroup: <resourceGroupName>
        name: <applicationGatewayName>
    
        # Setting appgw.shared to "true" creates an AzureIngressProhibitedTarget CRD.
        # This prohibits AGIC from applying config for any host/path.
        # Use "kubectl get AzureIngressProhibitedTargets" to view and change this.
        shared: false
    
    ################################################################################
    # Specify which kubernetes namespace the ingress controller must watch
    # Default value is "default"
    # Leaving this variable out or setting it to blank or empty string would
    # result in Ingress Controller observing all accessible namespaces.
    #
    # kubernetes:
    #   watchNamespace: <namespace>
    
    ################################################################################
    # Specify the authentication with Azure Resource Manager
    #
    # Two authentication methods are available:
    # - Option 1: Azure-AD-workload-identity
    armAuth:
        type: workloadIdentity
        identityClientID:  <identityClientId>
    
    ## Alternatively you can use Service Principal credentials
    # armAuth:
    #    type: servicePrincipal
    #    secretJSON: <<Generate this value with: "az ad sp create-for-rbac --role Contributor --sdk-auth | base64 -w0" >>
    
    ################################################################################
    # Specify if the cluster is Kubernetes RBAC enabled or not
    rbac:
        enabled: false # true/false
    
    # Specify aks cluster related information. THIS IS BEING DEPRECATED.
    aksClusterConfiguration:
        apiServerAddress: <aks-api-server-address>
    
  3. helm-config.yaml을 편집하고 appgwarmAuth 값을 채웁니다.

    참고 항목

    이전 섹션에서 설치한 Microsoft Entra 워크로드 ID의 <identity-client-id> 속성입니다. az identity show -g <resourcegroup> -n <identity-name> 명령을 실행하여 이 정보를 검색할 수 있습니다. 여기서 <resourcegroup>은 AKS 클러스터, Application Gateway 및 관리 ID와 관련된 인프라 리소스를 호스팅하는 리소스 그룹입니다.

  4. 이전 단계의 helm-config.yaml 구성을 사용하여 Helm Chart application-gateway-kubernetes-ingress를 설치합니다.

    helm install -f <helm-config.yaml> application-gateway-kubernetes-ingress/ingress-azure
    

    또는 helm-config.yaml 및 Helm 명령을 하나의 단계로 결합할 수 있습니다.

    helm install ./helm/ingress-azure \
         --name ingress-azure \
         --namespace default \
         --debug \
         --set appgw.name=applicationgatewayABCD \
         --set appgw.resourceGroup=your-resource-group \
         --set appgw.subscriptionId=subscription-uuid \
         --set appgw.shared=false \
         --set armAuth.type=servicePrincipal \
         --set armAuth.secretJSON=$(az ad sp create-for-rbac --role Contributor --sdk-auth | base64 -w0) \
         --set rbac.enabled=true \
         --set verbosityLevel=3 \
         --set kubernetes.watchNamespace=default \
         --set aksClusterConfiguration.apiServerAddress=aks-abcdefg.hcp.westus2.azmk8s.io
    
  5. 새로 만든 pod의 로그를 확인하여 제대로 시작되었는지 확인합니다.

Azure Application Gateway를 사용하여 HTTP 또는 HTTPS를 통해 AKS 서비스를 인터넷에 노출하는 방법을 이해하려면 이 방법 가이드를 참조하세요.

공유 Application Gateway

기본적으로 AGIC는 연결된 Application Gateway에 대한 모든 소유권이 있다고 가정합니다. AGIC 버전 0.8.0 이상에서는 다른 Azure 구성 요소와 단일 Application Gateway를 공유할 수 있습니다. 예를 들어, Virtual Machine Scale Set에서 호스트된 앱 및 AKS 클러스터에 동일한 Application Gateway를 사용할 수 있습니다.

이 설정을 사용하도록 지정하기 전에 Application Gateway의 구성을 백업하세요.

  1. Azure Portal에서 Application Gateway 인스턴스로 이동합니다.
  2. 자동화 섹션에서 템플릿 내보내기를 선택한 다음 다운로드를 선택합니다.

다운로드한 zip 파일에는 Application Gateway를 복원하는 데 사용할 수 있는 JSON 템플릿, bash 및 PowerShell 스크립트가 포함되어 있습니다.

예제 시나리오

두 웹 사이트에 대한 트래픽을 관리하는 가상의 Application Gateway를 살펴보겠습니다.

  • dev.contoso.com - 새 AKS 클러스터에서 호스트되며 Application Gateway 및 AGIC를 사용합니다.
  • prod.contoso.com - Azure Virtual Machine Scale Set에서 호스트됩니다.

기본 설정을 사용할 경우 AGIC는 가리키는 Application Gateway에 대해 100% 소유권이 있다고 가정합니다. AGIC는 App Gateway의 모든 구성을 덮어씁니다. (Application Gateway에서) prod.contoso.com에 대한 수신기를 수동으로 만들어야 경우 Kubernetes 수신에서 정의하지 않고 AGIC는 몇 초 안에 prod.contoso.com 구성을 삭제합니다.

AGIC를 설치하고 Virtual Machine Scale Set 머신에서도 prod.contoso.com을 제공하려면 dev.contoso.com만 구성하도록 AGIC를 제한해야 합니다. 이 방법은 다음 CRD를 인스턴스화하여 용이하게 진행할 수 있습니다.

cat <<EOF | kubectl apply -f -
apiVersion: "appgw.ingress.k8s.io/v1"
kind: AzureIngressProhibitedTarget
metadata:
  name: prod-contoso-com
spec:
  hostname: prod.contoso.com
EOF

위의 명령은 AzureIngressProhibitedTarget 개체를 만듭니다. 이렇게 하면 AGIC(버전 0.8.0 이상)에서 prod.contoso.com에 대한 Application Gateway 구성이 있음을 인식하게 되며 해당 호스트 이름과 관련된 구성을 변경하지 말라는 명시적 지침을 받게 됩니다.

새 AGIC 설치로 사용

AGIC(버전 0.8.0 이상)를 Application Gateway 구성의 하위 집합으로 제한하려면 helm-config.yaml 템플릿을 수정합니다. appgw: 섹션 아래에서 shared 키를 추가하고 true로 설정합니다.

appgw:
    subscriptionId: <subscriptionId>    # existing field
    resourceGroup: <resourceGroupName>  # existing field
    name: <applicationGatewayName>      # existing field
    shared: true                        # <<<<< Add this field to enable shared Application Gateway >>>>>

Helm 변경 내용을 적용합니다.

  1. 다음을 사용하여 AzureIngressProhibitedTarget CRD가 설치되어 있는지 확인합니다.

    kubectl apply -f https://raw.githubusercontent.com/Azure/application-gateway-kubernetes-ingress/7b55ad194e7582c47589eb9e78615042e00babf3/crds/AzureIngressProhibitedTarget-v1-CRD-v1.yaml
    
  2. Helm을 업데이트합니다.

    helm upgrade \
        --recreate-pods \
        -f helm-config.yaml \
        ingress-azure application-gateway-kubernetes-ingress/ingress-azure
    

결과적으로 AKS 클러스터에는 prohibit-all-targets라는 AzureIngressProhibitedTarget의 새 인스턴스가 있습니다.

kubectl get AzureIngressProhibitedTargets prohibit-all-targets -o yaml

이름에서 알 수 있듯이 개체 prohibit-all-targets는 AGIC에서 모든 호스트 및 경로에 대한 구성을 변경하지 못하게 합니다. appgw.shared=true를 사용하여 Helm을 설치하면 AGIC가 배포되지만 Application Gateway는 변경되지 않습니다.

사용 권한 확장

appgw.shared=true 및 기본 prohibit-all-targets 있는 Helm은 AGIC가 구성을 적용하지 못하도록 차단하므로 AGIC 권한을 확대합니다.

  1. 특정 설정을 포함하는 다음 코드 조각을 사용하여 새 YAML 파일 AzureIngressProhibitedTarget을 만듭니다.

    cat <<EOF | kubectl apply -f -
    apiVersion: "appgw.ingress.k8s.io/v1"
    kind: AzureIngressProhibitedTarget
    metadata:
      name: your-custom-prohibitions
    spec:
      hostname: your.own-hostname.com
    EOF
    
  2. 고유한 사용자 지정 금지를 만든 후에만 매우 포괄적인 기본 금지를 삭제할 수 있습니다.

    kubectl delete AzureIngressProhibitedTarget prohibit-all-targets
    

기존 AGIC 설치에 사용

클러스터에 이미 작동 중인 AKS 클러스터, Application Gateway 및 구성된 AGIC가 있다고 가정해 보겠습니다. prod.contoso.com에 대한 수신이 있으며 클러스터에서 이에 대한 트래픽을 처리하고 있습니다. staging.contoso.com을 기존 Application Gateway에 추가하지만 VM에서 호스트해야 합니다. 기존 Application Gateway를 다시 사용하고 staging.contoso.com에 대한 수신기 및 백 엔드 풀을 수동으로 구성하겠습니다. 그러나 Application Gateway 구성을 수동으로 조정하면(Portal, ARM API 또는 Terraform 사용) AGIC의 전체 소유권 가정과 충돌합니다. 변경 내용을 적용하는 즉시, AGIC에서 덮어쓰거나 삭제합니다.

AGIC에서 구성의 하위 집합을 변경하지 못하도록 방지할 수 있습니다.

  1. 다음 코드 조각을 사용하여 새 YAML 파일 AzureIngressProhibitedTarget을 만듭니다.

    cat <<EOF | kubectl apply -f -
    apiVersion: "appgw.ingress.k8s.io/v1"
    kind: AzureIngressProhibitedTarget
    metadata:
      name: manually-configured-staging-environment
    spec:
      hostname: staging.contoso.com
    EOF
    
  2. 새로 만든 개체를 확인합니다.

    kubectl get AzureIngressProhibitedTargets
    
  3. 수신기, 라우팅 규칙, 백 엔드 등을 추가하여 Azure Portal에서 Application Gateway 구성을 수정합니다. 만든 새 개체(manually-configured-staging-environment)는 AGIC가 staging.contoso.com과 관련된 Application Gateway 구성을 덮어쓰지 못하도록 합니다.