Share via


Reescritura de encabezados para Puerta de enlace de aplicaciones para contenedores de Azure: API de puerta de enlace

Puerta de enlace de aplicaciones para contenedores permite reescribir los encabezados HTTP de las solicitudes de cliente y las respuestas de los destinos de backend.

Detalles de uso

Las reescrituras de encabezados aprovechan las ventajas de los filtros, tal como se define en la API de puerta de enlace de Kubernetes.

Fondo

Las reescrituras de encabezados permiten modificar los encabezados de solicitud y respuesta hacia y desde los destinos de backend.

En la ilustración siguiente, se muestra una solicitud con un agente de usuario específico que se reescribe en un valor simplificado llamado SearchEngine-BingBot cuando la solicitud se inicia en el destino de backend mediante Puerta de enlace de aplicaciones para contenedores:

Diagrama que muestra cómo Puerta de enlace de aplicaciones para contenedores reescribe un encabezado de solicitud al back-end.

Requisitos previos

  1. Si sigue la estrategia Traiga su propia (BYO) implementación, asegúrese de configurar los recursos de Puerta de enlace de aplicaciones para contenedores y del controlador de ALB.

  2. Si sigue la estrategia de implementación administrada de ALB, asegúrese de aprovisionar el controlador de ALB de los recursos de Puerta de enlace de aplicaciones para contenedores mediante el recurso personalizado ApplicationLoadBalancer.

  3. Implementar aplicación HTTP de ejemplo: aplique el siguiente archivo deployment.yaml en el clúster para crear una aplicación web de ejemplo para mostrar la reescritura de encabezado.

    kubectl apply -f https://trafficcontrollerdocs.blob.core.windows.net/examples/traffic-split-scenario/deployment.yaml
    

    Este comando crea lo siguiente en el clúster:

    • un espacio de nombres denominado test-infra
    • dos servicios llamados backend-v1 y backend-v2 en el espacio de nombres test-infra
    • dos implementaciones llamadas backend-v1 y backend-v2 en el espacio de nombres test-infra

Implementación de los recursos necesarios de la API de puerta de enlace

Cree una puerta de enlace:

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: gateway-01
  namespace: test-infra
  annotations:
    alb.networking.azure.io/alb-namespace: alb-test-infra
    alb.networking.azure.io/alb-name: alb-test
spec:
  gatewayClassName: azure-alb-external
  listeners:
  - name: http-listener
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: Same
EOF

Nota:

Cuando el controlador de ALB cree los recursos de Puerta de enlace de aplicaciones para contenedores en ARM, usará las siguientes convenciones de nomenclatura para un recurso de frontend: fe-<8 caracteres generados aleatoriamente>

Si desea cambiar el nombre del frontend creado en Azure, considere la posibilidad de seguir la estrategia Traiga su propia implementación.

Una vez creado el recurso de puerta de enlace, asegúrese de que el estado sea válido, de que el cliente de escucha se haya programado y de que se haya asignado una dirección a la puerta de enlace.

kubectl get gateway gateway-01 -n test-infra -o yaml

Salida de ejemplo de la creación correcta de la puerta de enlace.

status:
  addresses:
  - type: IPAddress
    value: xxxx.yyyy.alb.azure.com
  conditions:
  - lastTransitionTime: "2023-06-19T21:04:55Z"
    message: Valid Gateway
    observedGeneration: 1
    reason: Accepted
    status: "True"
    type: Accepted
  - lastTransitionTime: "2023-06-19T21:04:55Z"
    message: Application Gateway For Containers resource has been successfully updated.
    observedGeneration: 1
    reason: Programmed
    status: "True"
    type: Programmed
  listeners:
  - attachedRoutes: 0
    conditions:
    - lastTransitionTime: "2023-06-19T21:04:55Z"
      message: ""
      observedGeneration: 1
      reason: ResolvedRefs
      status: "True"
      type: ResolvedRefs
    - lastTransitionTime: "2023-06-19T21:04:55Z"
      message: Listener is accepted
      observedGeneration: 1
      reason: Accepted
      status: "True"
      type: Accepted
    - lastTransitionTime: "2023-06-19T21:04:55Z"
      message: Application Gateway For Containers resource has been successfully updated.
      observedGeneration: 1
      reason: Programmed
      status: "True"
      type: Programmed
    name: https-listener
    supportedKinds:
    - group: gateway.networking.k8s.io
      kind: HTTPRoute

Una vez creada la puerta de enlace, cree un elemento HTTPRoute que escuche el nombre de host contoso.com e invalide el valor del agente de usuario en SearchEngine-BingBot.

En este ejemplo, buscamos el agente de usuario utilizado por el motor de búsqueda de Bing y simplificamos el encabezado a SearchEngine-BingBot para facilitar el análisis de backend.

En este ejemplo, también se muestra la adición de un nuevo encabezado llamado AGC-Header-Add con un valor de AGC-value y se quita un encabezado de solicitud llamado client-custom-header.

Sugerencia

En este ejemplo, aunque podemos usar el valor "Exact" de HTTPHeaderMatch para una coincidencia de cadena, se usa una demostración en la expresión regular para ilustrar funcionalidades adicionales.

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: header-rewrite-route
  namespace: test-infra
spec:
  parentRefs:
    - name: gateway-01
      namespace: test-infra
  hostnames:
    - "contoso.com"
  rules:
    - matches:
        - headers:
          - name: user-agent
            value: Mozilla/5\.0 AppleWebKit/537\.36 \(KHTML, like Gecko; compatible; bingbot/2\.0; \+http://www\.bing\.com/bingbot\.htm\) Chrome/
            type: RegularExpression
      filters:
        - type: RequestHeaderModifier
          requestHeaderModifier:
            set:
              - name: user-agent
                value: SearchEngine-BingBot
            add:
              - name: AGC-Header-Add
                value: AGC-value
            remove: ["client-custom-header"]
      backendRefs:
        - name: backend-v2
          port: 8080
    - backendRefs:
        - name: backend-v1
          port: 8080
EOF

Una vez creado el recurso HTTPRoute, asegúrese de que la ruta sea Accepted y que el recurso de Puerta de enlace de aplicaciones para contenedores sea de tipo Programmed.

kubectl get httproute header-rewrite-route -n test-infra -o yaml

Compruebe que el estado del recurso de Puerta de enlace de aplicaciones para contenedores se haya actualizado correctamente.

status:
  parents:
  - conditions:
    - lastTransitionTime: "2023-06-19T22:18:23Z"
      message: ""
      observedGeneration: 1
      reason: ResolvedRefs
      status: "True"
      type: ResolvedRefs
    - lastTransitionTime: "2023-06-19T22:18:23Z"
      message: Route is Accepted
      observedGeneration: 1
      reason: Accepted
      status: "True"
      type: Accepted
    - lastTransitionTime: "2023-06-19T22:18:23Z"
      message: Application Gateway For Containers resource has been successfully updated.
      observedGeneration: 1
      reason: Programmed
      status: "True"
      type: Programmed
    controllerName: alb.networking.azure.io/alb-controller
    parentRef:
      group: gateway.networking.k8s.io
      kind: Gateway
      name: gateway-01
      namespace: test-infra

Prueba de acceso a la aplicación

Ahora, estamos listos para enviar tráfico a nuestra aplicación de ejemplo mediante el FQDN asignado al frontend. Utilice el siguiente comando para obtener el FQDN:

fqdn=$(kubectl get gateway gateway-01 -n test-infra -o jsonpath='{.status.addresses[0].value}')

Si especifica el indicador de nombre de servidor mediante el comando curl, contoso.com para el FQDN del frontend, la salida debe devolver una respuesta del servicio backend-v1.

fqdnIp=$(dig +short $fqdn)
curl -k --resolve contoso.com:80:$fqdnIp http://contoso.com

Mediante la respuesta deberíamos ver:

{
 "path": "/",
 "host": "contoso.com",
 "method": "GET",
 "proto": "HTTP/1.1",
 "headers": {
  "Accept": [
   "*/*"
  ],
  "User-Agent": [
   "curl/7.81.0"
  ],
  "X-Forwarded-For": [
   "xxx.xxx.xxx.xxx"
  ],
  "X-Forwarded-Proto": [
   "http"
  ],
  "X-Request-Id": [
   "dcd4bcad-ea43-4fb6-948e-a906380dcd6d"
  ]
 },
 "namespace": "test-infra",
 "ingress": "",
 "service": "",
 "pod": "backend-v1-5b8fd96959-f59mm"
}

Especificar un encabezado user-agent con el valor `` debe devolver una respuesta del servicio de backend de SearchEngine-BingBot:

fqdnIp=$(dig +short $fqdn)
curl -k --resolve contoso.com:80:$fqdnIp http://contoso.com -H "user-agent: Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm) Chrome/"

Mediante la respuesta deberíamos ver:

{
 "path": "/",
 "host": "fabrikam.com",
 "method": "GET",
 "proto": "HTTP/1.1",
 "headers": {
  "Accept": [
   "*/*"
  ],
  "User-Agent": [
   "curl/7.81.0"
  ],
  "X-Forwarded-For": [
   "xxx.xxx.xxx.xxx"
  ],
  "X-Forwarded-Proto": [
   "http"
  ],
  "X-Request-Id": [
   "adae8cc1-8030-4d95-9e05-237dd4e3941b"
  ]
 },
 "namespace": "test-infra",
 "ingress": "",
 "service": "",
 "pod": "backend-v2-5b8fd96959-f59mm"
}

La especificación de un encabezado client-custom-header con el valor moo, debe eliminarse de la solicitud cuando Puerta de enlace de aplicaciones para contenedores inicia la conexión con el servicio de back-end:

fqdnIp=$(dig +short $fqdn)
curl -k --resolve contoso.com:80:$fqdnIp http://contoso.com -H "client-custom-header: moo"

Mediante la respuesta deberíamos ver:

{
 "path": "/",
 "host": "fabrikam.com",
 "method": "GET",
 "proto": "HTTP/1.1",
 "headers": {
  "Accept": [
   "*/*"
  ],
  "User-Agent": [
   "curl/7.81.0"
  ],
  "X-Forwarded-For": [
   "xxx.xxx.xxx.xxx"
  ],
  "X-Forwarded-Proto": [
   "http"
  ],
  "X-Request-Id": [
   "kd83nc84-4325-5d22-3d23-237dd4e3941b"
  ]
 },
 "namespace": "test-infra",
 "ingress": "",
 "service": "",
 "pod": "backend-v2-5b8fd96959-f59mm"
}

Enhorabuena, ha instalado el controlador de ALB, ha implementado una aplicación de backend y ha modificado los valores del encabezado mediante la API de puerta de enlace en Puerta de enlace de aplicaciones para contenedores.