Установка контроллера входящего трафика Шлюза приложений (AGIC) с помощью имеющегося Шлюза приложений

Контроллер Шлюз приложений входящего трафика (AGIC) — это модуль pod в кластере Служба Azure Kubernetes (AKS). Контроллер AGIC отслеживает ресурсы входящего трафика (ingress) Kubernetes, а также создает и применяет конфигурацию Шлюза приложений в соответствии с состоянием кластера Kubernetes.

Границы

Необходимые компоненты

В этом документе предполагается, что у вас уже установлены следующие средства и инфраструктура:

Создайте резервную копию конфигурации Шлюз приложений перед установкой AGIC:

  1. В портал Azure перейдите к экземпляру Шлюз приложений.
  2. В разделе "Автоматизация" выберите "Экспорт шаблона" и нажмите кнопку "Скачать".

Скачанный ZIP-файл содержит шаблоны JSON, bash и скрипты PowerShell, которые можно использовать для восстановления шлюза приложений, которые должны стать необходимыми.

Установка Helm

Helm — это менеджер пакетов для Kubernetes, используемый для установки application-gateway-kubernetes-ingress пакета.

Примечание.

Если вы используете Cloud Shell, вам не нужно устанавливать Helm. Azure Cloud Shell поставляется с Helm версии 3. Пропустите первый шаг и просто добавьте репозиторий AGIC Helm.

  1. Установите Helm и выполните следующую команду, чтобы добавить пакет Helm application-gateway-kubernetes-ingress:

    • Кластер AKS со включенным Kubernetes RBAC
    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. Добавьте репозиторий Helm 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 обменивается данными с сервером API Kubernetes и с Azure Resource Manager. Для доступа к этим API-интерфейсам ему необходимо удостоверение.

Настройка Идентификация рабочей нагрузки Microsoft Entra

Идентификация рабочей нагрузки Microsoft Entra — это удостоверение, назначаемое рабочей нагрузке программного обеспечения, для проверки подлинности и доступа к другим службам и ресурсам. Это удостоверение позволяет модулем pod AKS использовать это удостоверение и проходить проверку подлинности с другими ресурсами Azure. Для этой конфигурации требуется авторизация модуля AGIC для выполнения HTTP-запросов к ARM.

  1. Используйте команду Azure CLI az account set , чтобы задать определенную подписку для текущей активной подписки. Затем используйте команду az identity create для создания управляемого удостоверения. Удостоверение необходимо создать в группе ресурсов узла. Группа ресурсов узла по умолчанию назначается имя, например MC_myResourceGroup_myAKSCluster_eastus.

    az account set --subscription "subscriptionID"
    
    az identity create --name "userAssignedIdentityName" --resource-group "resourceGroupName" --location "location" --subscription "subscriptionID"
    
  2. Чтобы определить principalId только что созданное удостоверение, выполните следующую команду:

    $resourceGroup="resource-group-name"
    $identityName="identity-name"
    az identity list -g $resourceGroup --query "[?name == '$identityName'].principalId | [0]" -o tsv
    
  3. Предоставьте участнику удостоверений доступ к Шлюз приложений. Вам нужен идентификатор Шлюз приложений, который выглядит следующим образом: /subscriptions/A/resourceGroups/B/providers/Microsoft.Network/applicationGateways/C Сначала получите список идентификаторов Шлюз приложений в подписке, выполнив следующую команду:

    az network application-gateway list --query '[].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. Предоставьте читателю удостоверений доступ к группе ресурсов Шлюз приложений. Идентификатор группы ресурсов выглядит следующим образом: /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, имеет разрешение Microsoft.Network/virtualNetworks/subnets/join/action, делегированное в подсеть, в которой развернуты Шлюз приложений. Если пользовательская роль не определена с этим разрешением, можно использовать встроенную роль участника сети , которая содержит разрешение Microsoft.Network/virtualNetworks/subnets/join/action .

Использование субъекта-службы

Кроме того, можно предоставить доступ AGIC к ARM с помощью секрета Kubernetes.

  1. Создайте субъект-службу Active Directory и закодируйте его с использованием кодировки Base64. Кодировка Base64 необходима для сохранения большого двоичного объекта JSON в Kubernetes.

    az ad sp create-for-rbac --role Contributor --sdk-auth | base64 -w0
    
  2. Добавьте в файл helm-config.yaml большой двоичный объект JSON в кодировке Base64. Дополнительные сведения о файле helm-config.yaml см. в следующем разделе.

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

Развертывание надстройки контроллера входящего трафика Шлюз приложений Azure

Создание манифеста развертывания контроллера входящего трафика

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

В ходе первых нескольких шагов в ваш кластер Kubernetes устанавливается Tiller для менеджера Helm. Используйте оболочку Cloud Shell, чтобы установить пакет AGIC Helm:

  1. Добавьте репозиторий Helm application-gateway-kubernetes-ingress, затем выполните обновление Helm

    helm repo add application-gateway-kubernetes-ingress https://appgwingress.blob.core.windows.net/ingress-azure-helm-package/
    helm repo update
    
  2. Скачайте helm-config.yaml, который настраивает AGIC:

    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 и задайте в нем значения appgw и armAuth.

    Примечание.

    Это <identity-client-id> свойство Идентификация рабочей нагрузки Microsoft Entra, которое вы настраиваете в предыдущем разделе. Эти сведения можно получить, выполнив следующую команду: az identity show -g <resourcegroup> -n <identity-name>где находится группа ресурсов, в которой <resourcegroup> размещаются ресурсы инфраструктуры, связанные с кластером AKS, Шлюз приложений и управляемым удостоверением.

  4. Установите диаграмму Helm application-gateway-kubernetes-ingress с конфигурацией helm-config.yaml из предыдущего шага

    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, чтобы убедиться, что он запустился надлежащим образом

Ознакомьтесь с этим практическим руководством, чтобы узнать, как можно предоставлять доступ к службе AKS через HTTP или HTTPS, для подключений из Интернета, с помощью Шлюза приложений Azure.

Общие Шлюз приложений

По умолчанию AGIC предполагает полное владение Шлюз приложений связанной с ней. Начиная с версии 0.8.0, AGIC может также разделять использование одного Шлюза приложений с другими компонентами Azure. Например, можно использовать те же Шлюз приложений для приложения, размещенного в масштабируемом наборе виртуальных машин и кластере AKS.

Создайте резервную копию конфигурации Шлюз приложений перед включением этого параметра:

  1. В портал Azure перейдите к экземпляру Application Gateway
  2. В разделе "Автоматизация" выберите "Экспорт шаблона" и нажмите кнопку "Скачать".

Скачанный ZIP-файл содержит шаблоны JSON, bash и скрипты PowerShell, которые можно использовать для восстановления Шлюз приложений

Пример сценария

Рассмотрим условный Шлюз приложений, который управляет трафиком для двух веб-сайтов:

При использовании параметров по умолчанию AGIC предполагает 100% владения Шлюз приложений на него указывает. AGIC перезаписывает всю конфигурацию Шлюза приложений. Если вы вручную создаете прослушиватель prod.contoso.com (на Шлюз приложений), не определяя его в входящего трафика Kubernetes, AGIC удаляет prod.contoso.com конфигурацию в течение нескольких секунд.

Чтобы установить AGIC и также обслуживать prod.contoso.com с машин из масштабируемого набора виртуальных машин, необходимо ограничить AGIC, чтобы он выполнил лишь настройку dev.contoso.com. Это обеспечивается посредством создания экземпляра следующего 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 и явным образом указывает ему не вносить в конфигурацию какие-либо изменения, связанные с этим именем узла.

Включение при новой установке AGIC

Чтобы ограничить группу доступности (версии 0.8.0 и более поздней) подмножеством конфигурации Шлюз приложений, измените 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. Убедитесь, что CRD AzureIngressProhibitedTarget установлен, выполнив команду:

    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 имеет новый экземпляр AzureIngressProhibitedTarget с именем prohibit-all-targets:

kubectl get AzureIngressProhibitedTargets prohibit-all-targets -o yaml

Объект prohibit-all-targets, как ясно по его имени, запрещает AGIC изменять конфигурации для любых узлов и путей. Установка Helm с appgw.shared=true развертыванием AGIC, но не вносит никаких изменений в Шлюз приложений.

Расширение разрешений

Так как Helm с appgw.shared=true и стандартными блоками AGIC не применяет конфигурацию prohibit-all-targets , расширяйте разрешения 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, Шлюз приложений и настроенный AGIC в нашем кластере. У нас есть входящий prod.contoso.com трафик и успешно обслуживаются трафик из кластера. Мы намерены добавить staging.contoso.com в имеющийся Шлюз приложений, но нам нужно разместить его на виртуальной машине. Мы повторно воспользуемся существующим Шлюзом приложений, вручную настроим прослушиватель и серверные пулы staging.contoso.com. Но настройка конфигурации Шлюз приложений вручную (с помощью портала, API ARM или 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— добавьте прослушиватели, правила маршрутизации, серверные части и т. д. Созданный объект (manually-configured-staging-environment) запрещает agIC перезаписывать Шлюз приложений конфигурации, связанной с staging.contoso.com.