Instalar um AGIC (Controlador de Entrada do Gateway de Aplicativo) usando um Gateway de Aplicativo existente

O Controlador de Entrada do Gateway de Aplicativo (AGIC) é um pod no cluster do Serviço de Kubernetes do Azure (AKS). O AGIC monitora os recursos de Entrada do Kubernetes e cria e aplica a configuração do Gateway de Aplicativo com base no status do cluster Kubernetes.

Estrutura de Tópicos

Pré-requisitos

Este documento pressupõe que você já tenha as seguintes ferramentas e infraestrutura instaladas:

Fazer o backup da configuração do Gateway de Aplicativo antes de instalar o AGIC:

  1. No portal do Azure, navegue até a instância do Gateway de Aplicativo.
  2. Na seção Automação, selecione Exportar modelo e selecione Baixar.

O arquivo zip que você baixou contém modelos JSON, bash e scripts do PowerShell que você pode usar para restaurar o App Gateway caso seja necessário

Instalar o Helm

O Helm é um gerenciador de pacotes do Kubernetes usado para instalar o pacote application-gateway-kubernetes-ingress.

Observação

Se você usar Cloud Shell, não precisará instalar o Helm. O Azure Cloud Shell vem com o Helm versão 3. Ignore a primeira etapa e adicione apenas o repositório do Helm do AGIC.

  1. Instale o Helm e execute o seguinte para adicionar o pacote Helm application-gateway-kubernetes-ingress:

    • Cluster AKS habilitado para RBAC do Kubernetes
    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. Adicione o repositório AGIC do Helm:

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

Autenticação do Azure Resource Manager

O AGIC se comunica com o servidor de API do Kubernetes e o Azure Resource Manager. Ele exige uma identidade para acessar essas APIs.

Configurar a Carga de Trabalho do Microsoft Entra ID

A Carga de trabalho do Microsoft Entra ID é uma identidade que você atribui a uma carga de trabalho de software para autenticar e acessar outros serviços e recursos. Essa identidade permite que o pod do AKS use essa identidade e autentique-se com outros recursos do Azure. Para essa configuração, precisamos de autorização para que o pod AGIC faça solicitações HTTP para o ARM.

  1. Use o comando az account set da CLI do Azure para definir uma assinatura específica como a assinatura ativa atual. Em seguida, use o comando az identity create para criar uma identidade gerenciada. A identidade precisa ser criada no grupo de recursos do nó. O grupo de recursos do nó recebe um nome por padrão, como MC_myResourceGroup_myAKSCluster_eastus.

    az account set --subscription "subscriptionID"
    
    az identity create --name "userAssignedIdentityName" --resource-group "resourceGroupName" --location "location" --subscription "subscriptionID"
    
  2. Quanto à atribuição de função, execute o seguinte comando para identificar o principalId para a identidade recém-criada:

    $resourceGroup="resource-group-name"
    $identityName="identity-name"
    az identity list -g $resourceGroup --query "[?name == '$identityName'].principalId | [0]" -o tsv
    
  3. Conceda o acesso de Colaborador de identidade ao seu Gateway de Aplicativo. Você precisa da ID do Gateway de Aplicativo, que se parece com: /subscriptions/A/resourceGroups/B/providers/Microsoft.Network/applicationGateways/C. Primeiro, obtenha a lista de IDs do Gateway de Aplicativo na sua assinatura executando o seguinte comando:

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

    Para atribuir o acesso de Colaborador de identidade, execute o seguinte comando:

    $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. Conceda ao Leitor de identidade acesso ao grupo de recursos do Gateway de Aplicativo. A ID do grupo de recursos é semelhante a: /subscriptions/A/resourceGroups/B. Você pode obter todos os grupos de recursos com: 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
    

Observação

Verifique se a identidade usada pelo AGIC tem a permissão Microsoft.Network/virtualNetworks/subnets/join/action delegada para a sub-rede onde o Gateway de Aplicativo está implantado. Se uma função personalizada não for definida com essa permissão, você poderá usar a função interna de Colaborador de Rede, que contém a permissão Microsoft.Network/virtualNetworks/subnets/join/action.

Usando uma entidade de serviço

Também é possível fornecer acesso AGIC ao ARM usando um segredo do Kubernetes.

  1. Crie uma Entidade de Serviço do Active Directory e codifique com base64. A codificação base64 é necessária para que o blob JSON seja salvo no Kubernetes.

    az ad sp create-for-rbac --role Contributor --sdk-auth | base64 -w0
    
  2. Adicione o blob JSON codificado em base64 ao arquivo helm-config.yaml. Veja mais informações sobre helm-config.yaml na próxima seção.

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

Implantar o complemento do controlador de entrada do Gateway de Aplicativo do Azure

Criar um manifesto de implantação do controlador de entrada

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

Implantar o controlador de entrada

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

Instalar o Controlador de Entrada com um Gráfico do Helm

Nas primeiras etapas, instalamos o Tiller do Helm no cluster do Kubernetes. Use o Cloud Shell para instalar o pacote AGIC Helm:

  1. Adicionar o repositório application-gateway-kubernetes-ingress do Helm e executar uma atualização do Helm

    helm repo add application-gateway-kubernetes-ingress https://appgwingress.blob.core.windows.net/ingress-azure-helm-package/
    helm repo update
    
  2. Baixe o arquivo helm-config.yaml, que vai configurar o AGIC:

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

    Ou copie o seguinte arquivo 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. Edite o helm-config.yaml e preencha os valores de appgw e armAuth.

    Observação

    O <identity-client-id> é uma propriedade da Carga de Trabalho do Microsoft Entra ID que você configurou na seção anterior. Você pode recuperar essas informações executando o seguinte comando: az identity show -g <resourcegroup> -n <identity-name>, em que <resourcegroup> é o grupo de recursos que hospeda os recursos de infraestrutura relacionados ao cluster do AKS, ao Gateway de Aplicativo e à identidade gerenciada.

  4. Instalar o gráfico do Helm application-gateway-kubernetes-ingress com a configuração helm-config.yaml da etapa anterior

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

    Como alternativa, você pode combinar o helm-config.yaml e o comando do Helm em uma única etapa:

    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. Verifique o log do pod recém-criado para verificar se ele foi iniciado corretamente

Consulte este guia de instruções para entender como expor um serviço do AKS por HTTP ou HTTPS, na Internet, usando um Gateway de Aplicativo do Azure.

Gateway de Aplicativo Compartilhado

Por padrão, o AGIC pressupõe a propriedade total do Gateway de Aplicativo ao qual está vinculado. O AGIC versão 0.8.0 e posterior pode compartilhar um único Gateway de Aplicativo com outros componentes do Azure. Por exemplo, poderíamos usar o mesmo Gateway de Aplicativo em um aplicativo hospedado no Conjunto de Dimensionamento de Máquinas Virtuais e em um cluster do AKS.

Faça o backup da sua configuração do Gateway de Aplicativo antes de habilitar essa configuração:

  1. No portal do Azure, navegue até sua instância de Application Gateway
  2. Na seção Automação, selecione Exportar modelo e selecione Baixar.

O arquivo zip que você baixou contém modelos JSON, bash e scripts do PowerShell que você pode usar para restaurar o Gateway de Aplicativo

Cenário de Exemplo

Vamos examinar um Gateway de Aplicativo imaginário, que gerencia o tráfego para dois sites da Web:

Com as configurações padrão, o AGIC pressupõe 100% de propriedade do Gateway de Aplicativo ao qual ele é apontado. O AGIC substitui toda a configuração do Gateway de Aplicativo. Se você criar manualmente um ouvinte para prod.contoso.com (no Gateway de Aplicativo) sem defini-lo na entrada do Kubernetes, o AGIC excluirá a configuração prod.contoso.com em segundos.

Para instalar o AGIC e também para atender prod.contoso.com em nossos computadores do conjunto de dimensionamento de máquinas virtuais, é necessário restringir AGIC somente à configuração dev.contoso.com. Isso é facilitado com a criação da seguinte instância de 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

O comando acima cria um objeto AzureIngressProhibitedTarget. Isso torna o AGIC (versão 0.8.0 e posterior) ciente da existência da configuração do Gateway de Aplicativo para o prod.contoso.com e o instrui explicitamente para evitar a alteração de qualquer configuração relacionada a esse nome de host.

Habilitar com a nova instalação do AGIC

Para limitar o AGIC (versão 0.8.0 e posterior) a um subconjunto da configuração do Gateway de Aplicativo, modifique o modelo helm-config.yaml. Na seção appgw:, adicione a chave shared e defina-a como true.

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

Aplicar as alterações do Helm:

  1. Verifique se o CRD AzureIngressProhibitedTarget está instalado com:

    kubectl apply -f https://raw.githubusercontent.com/Azure/application-gateway-kubernetes-ingress/7b55ad194e7582c47589eb9e78615042e00babf3/crds/AzureIngressProhibitedTarget-v1-CRD-v1.yaml
    
  2. Atualizar Helm:

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

Como resultado, seu cluster do AKS terá uma nova instância do AzureIngressProhibitedTarget chamada prohibit-all-targets:

kubectl get AzureIngressProhibitedTargets prohibit-all-targets -o yaml

O objeto prohibit-all-targets, como o nome sugere, proíbe o AGIC de alterar a configuração de qualquer host e caminho. A instalação do Helm com o appgw.shared=true implantará o AGIC, mas não fará alterações no Gateway de Aplicativo.

Ampliar permissões

Como o Helm com appgw.shared=true e o padrão prohibit-all-targets impede que o AGIC aplique uma configuração, amplie as permissões do AGIC:

  1. Crie um novo arquivo YAML chamado AzureIngressProhibitedTarget com o seguinte snippet que contém sua configuração específica:

    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. Somente depois de criar sua própria proibição personalizada, você poderá excluir o padrão, o que é muito amplo:

    kubectl delete AzureIngressProhibitedTarget prohibit-all-targets
    

Habilitar para uma instalação existente do AGIC

Vamos supor que já temos um cluster do AKS em funcionamento, o Gateway de Aplicativo e o AGIC configurado no nosso cluster. Temos uma entrada para prod.contoso.com e estamos atendendo com êxito o tráfego do cluster. Queremos adicionar staging.contoso.com ao nosso Gateway de Aplicativo existente, mas é necessário hospedá-lo em uma VM. Vamos reutilizar o Gateway de Aplicativo existente e configurar manualmente um ouvinte e pools de back-end para o staging.contoso.com. Mas ajustar manualmente a configuração do Gateway de Aplicativo (pelo portal, APIs ARM ou Terraform) estaria em conflito com as suposições do AGIC da propriedade total. Logo após aplicarmos as alterações, o AGIC as substituirá ou as excluirá.

Podemos proibir o AGIC de fazer alterações em um subconjunto da configuração.

  1. Crie um novo arquivo YAML chamado AzureIngressProhibitedTarget com o seguinte snippet:

    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. Veja o objeto recém-criado:

    kubectl get AzureIngressProhibitedTargets
    
  3. Modificar a configuração do Gateway de Aplicativo do portal do Azure – adicionar ouvintes, regras de roteamento, back-ends, etc. O novo objeto que criamos (manually-configured-staging-environment) proíbe que o AGIC substitua a configuração do Gateway de Aplicativo relacionada a staging.contoso.com.