Поделиться через


Перенаправление URL-адресов для Шлюз приложений Azure для контейнеров — API шлюза

Шлюз приложений для контейнеров позволяет возвращать ответ перенаправления клиенту на основе трех аспектов URL-адреса: протокола, имени узла и пути. Для каждого перенаправления определенный код состояния HTTP может быть возвращен клиенту для определения характера перенаправления.

Сведения об использовании

Перенаправления URL-адресов используют фильтр правил RequestRedirect, определенный API шлюза Kubernetes.

Перенаправление

Перенаправление задает код состояния ответа, возвращенный клиентам, чтобы понять назначение перенаправления. Поддерживаются следующие типы перенаправления:

  • 301 (перемещено постоянно): указывает, что целевой ресурс назначает новый постоянный универсальный код ресурса (URI). Будущие ссылки на этот ресурс используют один из вложенных URI. Используйте код состояния 301 для перенаправления с HTTP на HTTPS.
  • 302 (найдено). Указывает, что целевой ресурс временно находится под другим URI. Так как перенаправление может измениться в некоторых случаях, клиент должен продолжать использовать действующий URI запроса для будущих запросов.

Возможности перенаправления

  • Перенаправление протокола обычно используется для того, чтобы сообщить клиенту перейти от незашифрованной схемы трафика к трафику, например HTTP к перенаправлению HTTPS.

  • Перенаправление имени узла соответствует полному доменному имени (fqdn) запроса. Обычно это наблюдается при перенаправлении старого доменного имени в новое доменное имя; contoso.com например, для fabrikam.com.

  • Перенаправление пути имеет два разных варианта: prefix и full.

    • Prefix Тип перенаправления перенаправляет все запросы, начиная с определенного значения. Например: префикс /shop будет соответствовать /shop и любой текст после. Например, /shop, /shop/checkout, и /shop/item-a будет все перенаправлены в /shop, а также.
    • Full Тип перенаправления соответствует точному значению. Например: /shop может перенаправляться в /store, но /shop/checkout не перенаправляется в /store.

На следующем рисунке показан пример запроса, предназначенного для перенаправления contoso.com/summer-promotion на contoso.com/shop/category/5. Кроме того, второй запрос, инициированный для contoso.com через протокол HTTP, возвращается перенаправление, чтобы инициировать новое подключение к его варианту https.

Схема, показывающая Шлюз приложений для контейнеров, возвращающих URL-адрес перенаправления клиенту.

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

  1. Если вы используете стратегию развертывания BYO, убедитесь, что вы настроили Шлюз приложений для ресурсов контейнеров и контроллера балансировки нагрузки.

  2. Если вы используете стратегию управляемого развертывания ALB, подготовьте контроллер ALB и подготовите Шлюз приложений для ресурсов контейнеров с помощью настраиваемого ресурса ApplicationLoadBalancer.

  3. Развертывание примера HTTP-приложения:

    Примените следующий файл deployment.yaml в кластере, чтобы развернуть пример сертификата TLS для демонстрации возможностей перенаправления.

    kubectl apply -f https://raw.githubusercontent.com/MicrosoftDocs/azure-docs/refs/heads/main/articles/application-gateway/for-containers/examples/https-scenario/ssl-termination/deployment.yaml
    

    Эта команда создает следующую команду в кластере:

    • пространство имен с именем test-infra
    • одна служба, вызываемая echo test-infra в пространстве имен
    • одно развертывание, вызываемое echo test-infra в пространстве имен
    • один секрет, вызываемый listener-tls-secret test-infra в пространстве имен

Развертывание необходимых ресурсов API шлюза

  1. Создание шлюза

    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
      - name: https-listener
        port: 443
        protocol: HTTPS
        allowedRoutes:
          namespaces:
            from: Same
        tls:
          mode: Terminate
          certificateRefs:
          - kind : Secret
            group: ""
            name: listener-tls-secret
    EOF
    

Примечание.

Когда контроллер ALB создает Шлюз приложений для ресурсов контейнеров в ARM, он будет использовать следующее соглашение об именовании для внешнего ресурса: fe-8< случайным образом созданные символы>

Если вы хотите изменить имя внешнего интерфейса, созданного в Azure, попробуйте выполнить собственную стратегию развертывания.

После создания ресурса шлюза убедитесь, что состояние является допустимым, прослушиватель запрограммирован, а адрес назначается шлюзу.

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

Пример выходных данных успешного создания шлюза.

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

Создайте ресурс HTTPRoute для contoso.com обработки трафика, полученного через https.

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: https-contoso
  namespace: test-infra
spec:
  parentRefs:
  - name: gateway-01
    sectionName: https-listener
  hostnames:
  - "contoso.com"
  rules:
  - backendRefs:
    - name: echo
      port: 80
EOF

При создании ресурса HTTPRoute убедитесь, что ресурс HTTPRoute отображается "Принято" и запрограммирован Шлюз приложений для ресурсов контейнеров.

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

Убедитесь, что ресурс Шлюз приложений для контейнеров успешно обновлен для каждого 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

После создания шлюза создайте ресурс HTTPRoute для contoso.com фильтра RequestRedirect, который перенаправляет http-трафик на https.

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: http-to-https-contoso-redirect
  namespace: test-infra
spec:
  parentRefs:
  - name: gateway-01
    sectionName: http-listener
  hostnames:
  - "contoso.com"
  rules:
    - matches:
      filters:
        - type: RequestRedirect
          requestRedirect:
            scheme: https
            statusCode: 301
EOF

При создании ресурса HTTPRoute убедитесь, что ресурс HTTPRoute отображается "Принято" и запрограммирован Шлюз приложений для ресурсов контейнеров.

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

Убедитесь, что ресурс Шлюз приложений для контейнеров успешно обновлен для каждого 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

Создайте ресурс HTTPRoute, который contoso.com обрабатывает перенаправление для пути /summer-promotion на определенный URL-адрес. Исключив разделName, показанный в ресурсах https https HTTPRoute, это правило перенаправления применяется как к HTTP-запросам, так и к HTTPS.

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: summer-promotion-redirect
  namespace: test-infra
spec:
  parentRefs:
  - name: gateway-01
    sectionName: https-listener
  hostnames:
  - "contoso.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /summer-promotion
    filters:
      - type: RequestRedirect
        requestRedirect:
          path:
            type: ReplaceFullPath
            replaceFullPath: /shop/category/5
          statusCode: 302
  - backendRefs:
    - name: echo
      port: 80
EOF

При создании ресурса HTTPRoute убедитесь, что ресурс HTTPRoute отображается "Принято" и запрограммирован Шлюз приложений для ресурсов контейнеров.

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

Убедитесь, что ресурс Шлюз приложений для контейнеров успешно обновлен для каждого 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

Проверка доступа к приложению.

Теперь мы готовы отправить некоторый трафик в пример приложения через полное доменное имя, назначенное интерфейсу. Чтобы получить полное доменное имя, используйте следующую команду.

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

При указании индикатора имени сервера с помощью команды http://contoso.com curl должен вернуть ответ из Шлюз приложений для контейнеров с заголовкомlocation, определяющим перенаправление 301.https://contoso.com

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

В ответе мы должны увидеть следующее:

* Added contoso.com:80:xxx.xxx.xxx.xxx to DNS cache
* Hostname contoso.com was found in DNS cache
*   Trying xxx.xxx.xxx.xxx:80...
* Connected to contoso.com (xxx.xxx.xxx.xxx) port 80 (#0)
> GET / HTTP/1.1
> Host: contoso.com
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< location: https://contoso.com/
< date: Mon, 26 Feb 2024 22:56:23 GMT
< server: Microsoft-Azure-Application-LB/AGC
< content-length: 0
<
* Connection #0 to host contoso.com left intact

При указании индикатора имени сервера с помощью команды https://contoso.com/summer-promotion curl Шлюз приложений для контейнеров должен вернуть перенаправление https://contoso.com/shop/category/5302.

fqdnIp=$(dig +short $fqdn)
curl -k --resolve contoso.com:443:$fqdnIp https://contoso.com/summer-promotion -v

В ответе мы должны увидеть следующее:

> GET /summer-promotion HTTP/2
> Host: contoso.com
> user-agent: curl/7.81.0
> accept: */*
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
< HTTP/2 302
< location: https://contoso.com/shop/category/5
< date: Mon, 26 Feb 2024 22:58:43 GMT
< server: Microsoft-Azure-Application-LB/AGC
<
* Connection #0 to host contoso.com left intact

Поздравляем, вы установили контроллер ALB, развернули серверное приложение и использовали API шлюза для настройки перенаправления HTTP в HTTPS и перенаправления на основе пути к определенным клиентским запросам.