Share via


Reescritura de direcciones URL para Puerta de enlace de aplicaciones para contenedores de Azure: API de puerta de enlace

La Puerta de enlace de aplicaciones para contenedores permite volver a escribir la dirección URL de una solicitud de cliente, incluidos el nombre de host o la ruta de acceso de las solicitudes. Cuando la Puerta de enlace de aplicaciones para contenedores inicia la solicitud al destino de backend, la solicitud contiene la dirección URL recién reescrita para iniciar la solicitud.

Detalles de uso

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

Fondo

La reescritura de direcciones URL permite traducir una solicitud entrante a una dirección URL diferente cuando se inicia en un destino de backend.

En la ilustración siguiente se muestra un ejemplo de una solicitud destinada a contoso.com/shop que se reescribe en contoso.com/ecommerce. Puerta de enlace de aplicaciones para contenedores inicia la solicitud en el destino de back-end:

A diagram showing the Application Gateway for Containers rewriting a URL to the backend.

Requisitos previos

  1. Si sigue la estrategia de implementación BYO, asegúrese de configurar los recursos de Puerta de enlace de aplicaciones para contenedores y el controlador de ALB.

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

  3. Implementación de una aplicación HTTP de ejemplo

    Aplique el siguiente archivo deployment.yaml en el clúster para implementar un certificado TLS de ejemplo para demostrar las funcionalidades de redireccionamiento.

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

    Este comando crea lo siguiente en el clúster:

    • Un espacio de nombres denominado test-infra
    • Un servicio llamado echo en el espacio de nombres test-infra
    • Una implementación llamada echo en el espacio de nombres test-infra
    • Un secreto llamado listener-tls-secret en el espacio de nombres test-infra

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

  1. Creación de 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: Hostname
    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 recurso HTTPRoute para contoso.com. En este ejemplo se garantiza que el tráfico enviado a contoso.com/shop se inicie como contoso.com/ecommerce al destino de backend.

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: rewrite-example
  namespace: test-infra
spec:
  parentRefs:
  - name: gateway-01
  hostnames:
  - "contoso.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /shop
      filters:
        - type: URLRewrite
          urlRewrite:
            path:
              type: ReplacePrefixMatch
              replacePrefixMatch: /ecommerce
      backendRefs:
        - name: backend-v1
          port: 8080
    - backendRefs:
        - name: backend-v2
          port: 8080
EOF

Cuandos se haya creado el recurso de HTTPRoute, asegúrese de que ambos recursos se muestren como Aceptado y que el recurso de la Puerta de enlace de aplicaciones para contenedores esté Programado.

kubectl get httproute rewrite-example -n test-infra -o yaml

Compruebe que el recurso de la Puerta de enlace de aplicaciones para contenedores se haya actualizado correctamente para cada instancia de HTTPRoute.

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}')

Al especificar el indicador de nombre de servidor mediante el comando curl, contoso.com/shop debe devolver una respuesta del servicio backend-v1 con la ruta de acceso solicitada al destino de backend que muestra contoso.com/ecommerce.

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

Mediante la respuesta deberíamos ver:

{
 "path": "/ecommerce",
 "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"
}

Al especificar el indicador de nombre de servidor mediante el comando curl, contoso.com debe devolver una respuesta del servicio backend-v2.

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": [
   "adae8cc1-8030-4d95-9e05-237dd4e3941b"
  ]
 },
 "namespace": "test-infra",
 "ingress": "",
 "service": "",
 "pod": "backend-v2-594bd59865-ppv9w"
}

Enhorabuena, instaló el controlador ALB, implementó una aplicación backend y utilizó el filtro para reescribir la URL solicitada por el cliente antes de establecer el tráfico en el destino en la Puerta de enlace de aplicaciones para contenedores.