Instalar un controlador de entrada de Application Gateway (AGIC) mediante una instancia de Application Gateway existente

El controlador de entrada de Application Gateway (AGIC) es un pod dentro del clúster de Azure Kubernetes Service (AKS). AGIC supervisa los recursos de entrada de Kubernetes. Además, crea y aplica la configuración de Application Gateway en función del estado del clúster de Kubernetes.

Contorno

Requisitos previos

Este documento asume que ya tiene instaladas las siguientes herramientas e infraestructura:

Realice una copia de seguridad de su configuración de Application Gateway antes de instalar AGIC:

  1. Desde Azure Portal, vaya a la instancia de Application Gateway.
  2. En la sección Automatización, seleccione Exportar plantilla y, a continuación, seleccione Descargar.

El archivo ZIP que descargó contiene plantillas JSON, bash y scripts de PowerShell que puede usar para restaurar la instancia de App Gateway en caso de que sea necesario

Instalación de Helm

Helm es un administrador de paquetes para Kubernetes que se usa para instalar el paquete application-gateway-kubernetes-ingress.

Nota:

Si usa Cloud Shell, no es necesario instalar Helm. Azure Cloud Shell viene con Helm versión 3. Omita el primer paso y agregue el repositorio de Helm de AGIC.

  1. Instale Helm y ejecute lo siguiente para agregar el paquete de Helm application-gateway-kubernetes-ingress:

    • Clúster de AKS habilitado para RBAC de 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. Agregue el repositorio de Helm de AGIC:

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

Autenticación de Azure Resource Manager

AGIC se comunica con el servidor de la API de Kubernetes y Azure Resource Manager. Una identidad es necesaria para acceder a estas API.

Configurar un id. de carga de trabajo de Microsoft Entra

El id. de carga de trabajo de Microsoft Entra es una identidad que se asigna a una carga de trabajo de software para autenticar y acceder a otros servicios y recursos. Esta identidad permite al pod de AKS usar esta identidad y autenticarse con otros recursos de Azure. Para esta configuración, necesitamos autorización para que el pod de AGIC realice solicitudes HTTP a ARM.

  1. Use el comando az account set de la CLI de Azure para que una suscripción específica se establezca como la suscripción activa actual. Después, use el comando az identity create para crear una identidad administrada. La identidad debe crearse en el grupo de recursos del nodo. De forma predeterminada, al grupo de recursos de nodos se le asigna un nombre, como MC_myResourceGroup_myAKSCluster_eastus.

    az account set --subscription "subscriptionID"
    
    az identity create --name "userAssignedIdentityName" --resource-group "resourceGroupName" --location "location" --subscription "subscriptionID"
    
  2. Para la asignación de roles, ejecute el siguiente comando para identificar el principalId para la identidad recién creada:

    $resourceGroup="resource-group-name"
    $identityName="identity-name"
    az identity list -g $resourceGroup --query "[?name == '$identityName'].principalId | [0]" -o tsv
    
  3. Conceda acceso al Colaborador de identidad a Application Gateway. Necesita el id. de Application Gateway, que tiene el siguiente aspecto: /subscriptions/A/resourceGroups/B/providers/Microsoft.Network/applicationGateways/C. En primer lugar, ejecute el comando siguiente para obtener la lista de id. de Application Gateway de la suscripción:

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

    Para asignar acceso al Colaborador de identidad, ejecute el siguiente 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 acceso a la identidad de Lector al grupo de recursos de Application Gateway. El id. del grupo de recursos tiene el siguiente aspecto: /subscriptions/A/resourceGroups/B. Puede obtener todos los grupos de recursos con: 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
    

Nota:

Asegúrese de que la identidad usada por AGIC tiene el permiso Microsoft.Network/virtualNetworks/subnets/join/action delegado en la subred en la que se implementa Application Gateway. Si no se define un rol personalizado con este permiso, puede usar el rol integrado Colaborador de red, que contiene el permiso Microsoft.Network/virtualNetworks/subnets/join/action.

Uso de una entidad de servicio

También es posible proporcionar a AGIC acceso a ARM a través de un secreto de Kubernetes.

  1. Cree una entidad de servicio de Active Directory y codifíquela con base64. La codificación base64 es necesaria para que el blob JSON se guarde en Kubernetes.

    az ad sp create-for-rbac --role Contributor --sdk-auth | base64 -w0
    
  2. Agregue el blob JSON codificado con base64 al archivo helm-config.yaml. Para obtener más información sobre helm-config.yaml, consulte la siguiente sección.

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

Implementación del complemento del controlador de entrada de Azure Application Gateway

Creación de un manifiesto de implementación del 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

Implementación del controlador de entrada

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

Instalación del controlador de entrada como un gráfico de Helm

En los primeros pasos instalamos Tiller de Helm en el clúster de Kubernetes. Use Cloud Shell para instalar el paquete de Helm de AGIC:

  1. Agregue el repositorio de Helm application-gateway-kubernetes-ingress y realice una actualización de Helm

    helm repo add application-gateway-kubernetes-ingress https://appgwingress.blob.core.windows.net/ingress-azure-helm-package/
    helm repo update
    
  2. Descargue helm-config.yaml, que configura AGIC:

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

    O copie el siguiente archivo 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 helm-config.yaml y rellene los valores de appgw y armAuth.

    Nota:

    El <identity-client-id> es una propiedad del id. de carga de trabajo de Microsoft Entra que configuró en la sección anterior. Para recuperar esta información, ejecute el siguiente comando: az identity show -g <resourcegroup> -n <identity-name>, donde <resourcegroup> es el grupo de recursos que hospeda los recursos de infraestructura relacionados con el clúster de AKS, Application Gateway y la identidad administrada.

  4. Instale el gráfico de Helm application-gateway-kubernetes-ingress con la configuración de helm-config.yaml del paso anterior

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

    También puede combinar el helm-config.yaml y el comando de Helm en un solo paso:

    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. Compruebe el registro del pod recién creado para comprobar si se inició correctamente

Consulte esta guía paso a paso para comprender cómo puede exponer un servicio de AKS a través de HTTP o HTTPS a Internet mediante Azure Application Gateway.

Application Gateway compartido

De forma predeterminada, AGIC asume la propiedad total de la instancia de Application Gateway a la que está vinculado. AGIC versión 0.8.0 y versiones posteriores pueden compartir una única instancia de Application Gateway con otros componentes de Azure. Por ejemplo, podríamos usar la misma instancia de Application Gateway para una aplicación hospedada en un conjunto de escalado de máquinas virtuales, así como para un clúster de AKS.

Realice una copia de seguridad de su configuración de Application Gateway antes de habilitar esta opción:

  1. En Azure Portal, vaya a su instancia de Application Gateway.
  2. En la sección Automatización, seleccione Exportar plantilla y, a continuación, seleccione Descargar.

El archivo ZIP que descargó tendrá plantillas JSON, bash y scripts de PowerShell que puede usar para restaurar la instancia de Application Gateway

Escenario de ejemplo

Echemos un vistazo a una instancia de Application Gateway imaginaria, que administra el tráfico para dos sitios web:

Con la configuración predeterminada, AGIC asume la propiedad completa de la instancia de Application Gateway a la que se apunta. AGIC sobrescribe toda la configuración de la instancia de App Gateway. Si creamos manualmente un cliente de escucha para prod.contoso.com (en Application Gateway) sin definirlo en la entrada de Kubernetes, AGIC eliminará la configuración de prod.contoso.com en cuestión de segundos.

Para instalar AGIC y también servir prod.contoso.com desde las máquinas de un conjunto de escalado de máquinas virtuales, debemos restringir AGIC a configurar solo dev.contoso.com. Esto se facilita mediante la creación de instancias del siguiente 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

El comando anterior crea un objeto de AzureIngressProhibitedTarget. Esto hace que AGIC (versión 0.8.0 y posteriores) tenga en cuenta la existencia de la configuración de Application Gateway para prod.contoso.com y le indica explícitamente que evite cambiar cualquier configuración relacionada con ese nombre de host.

Habilitar con la nueva instalación de AGIC

Para limitar AGIC (versión 0.8.0 y posteriores) a un subconjunto de la configuración de Application Gateway, modifique la plantilla helm-config.yaml. En la sección appgw:, agregue la clave shared y establézcala 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 >>>>>

Aplique los cambios de Helm:

  1. Asegúrese de que el CRD de AzureIngressProhibitedTarget esté instalado con:

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

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

Como resultado, el clúster de AKS tiene una nueva instancia de AzureIngressProhibitedTarget denominada prohibit-all-targets:

kubectl get AzureIngressProhibitedTargets prohibit-all-targets -o yaml

El objeto prohibit-all-targets, como su nombre implica, prohíbe que AGIC cambie la configuración de cualquier host y ruta de acceso. Helm se instala con appgw.shared=true e implementa AGIC, pero no realiza ningún cambio en Application Gateway.

Ampliar permisos

Puesto que Helm con appgw.shared=true y el valor predeterminado prohibit-all-targets bloquea AGIC de aplicar una configuración, amplíe los permisos de AGIC:

  1. Cree un nuevo archivo YAML denominado AzureIngressProhibitedTarget con el siguiente fragmento de código que contenga la configuración 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. Solo después de haber creado su propia prohibición personalizada, podrá eliminar la predeterminada, que es demasiado amplia:

    kubectl delete AzureIngressProhibitedTarget prohibit-all-targets
    

Habilitar para una instalación de AGIC existente

Supongamos que ya tenemos un clúster de AKS y Application Gateway en funcionamiento, además de AGIC configurado en nuestro clúster. Tenemos una entrada para prod.contoso.com y estamos sirviendo correctamente el tráfico desde el clúster. Queremos agregar staging.contoso.com a nuestra instancia de Application Gateway existente, pero es necesario hospedarlo en una máquina virtual. Vamos a volver a usar la instancia de Application Gateway existente y a configurar manualmente un cliente de escucha y los grupos de back-end para staging.contoso.com. Sin embargo, el ajuste manual de la configuración de Application Gateway (a través del portal, las API de ARM o Terraform) puede entrar en conflicto con las suposiciones de AGIC sobre la propiedad total. Poco después de aplicar los cambios, AGIC los sobrescribe o elimina.

Podemos prohibir que AGIC realice cambios en un subconjunto de la configuración.

  1. Cree un nuevo archivo YAML denominado AzureIngressProhibitedTarget con el siguiente fragmento de código:

    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. Revise el objeto recién creado:

    kubectl get AzureIngressProhibitedTargets
    
  3. Modifique la configuración de Application Gateway a través de Azure Portal: agregue clientes de escucha, reglas de enrutamiento, back-ends, etc. El nuevo objeto que creamos (manually-configured-staging-environment) prohibirá que AGIC sobrescriba la configuración de Application Gateway relacionada con staging.contoso.com.