Azure Application Gateway for Containers の URL のリダイレクト - Gateway API

Application Gateway for Containers を使用すると、URL の 3 つの側面 (プロトコル、ホスト名、パス) に基づいてリダイレクト応答をクライアントに返すことができます。 リダイレクトごとに定義済みの HTTP 状態コードをクライアントに返して、リダイレクトの性質を定義することがあります。

Usage details

URL のリダイレクトでは、Kubernetes Gateway API で定義される RequestRedirect ルール フィルターを利用します。

リダイレクト

リダイレクトにより、リダイレクトの目的を理解するためにクライアントに返される応答の状態コードが設定されます。 次の種類のリダイレクトがサポートされています。

  • 301 (永続的に移動): ターゲット リソースに新しい永続的な URI が割り当てられていることを示します。 このリソースへの今後の参照では、囲まれた URI のいずれかが使用されます。 状態コード 301 は HTTP から HTTPS へのリダイレクトに使用します。
  • 302 (検出) :ターゲット リソースが一時的に別の URI に存在することを示します。 リダイレクトは場合によっては変更される可能性があるため、クライアントは今後の要求のために有効な要求 URI を引き続き使用する必要があります。

リダイレクト機能

  • プロトコル リダイレクトは、暗号化されていないトラフィック スキームからトラフィックに移動する (HTTP から HTTPS へのリダイレクトなど) ようにクライアントに指示するためによく使用されます。

  • ホスト名のリダイレクトが要求の完全修飾ドメイン名 (FQDN) と一致します。 これは、古いドメイン名を新しいドメイン名に リダイレクトする (contoso.com から fabrikam.com など) 際によく見られます。

  • パスのリダイレクトには、prefixfull という 2 種類のバリアントがあります。

    • リダイレクトの種類の 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 にリダイレクトされる例を示しています。 さらに、http プロトコルを介して contoso.com 向けに開始された 2 つ目の要求は、その https バリアントへの新しい接続を開始するためにリダイレクトを返します。

A diagram showing the Application Gateway for Containers returning a redirect URL to a client.

前提条件

  1. BYO デプロイ戦略に従う場合は、Application Gateway for Containers リソースと ALB コントローラーを設定していることを確認します。

  2. ALB マネージド デプロイ戦略に従う場合は、ALB コントローラーのプロビジョニングと、ApplicationLoadBalancer カスタム リソースを介した Application Gateway for Containers リソースのプロビジョニングが完了していることを確認します。

  3. サンプル HTTP アプリケーションをデプロイする:

    クラスターに次の deployment.yaml ファイルを適用して、リダイレクト機能を示すサンプル TLS 証明書をデプロイします。

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

    このコマンドによって、クラスターに次のものが作成されます。

    • test-infra と呼ばれる名前空間
    • test-infra 名前空間内の echo という 1 つのサービス
    • test-infra 名前空間に echo と呼ばれる 1 つのデプロイ
    • test-infra 名前空間に listener-tls-secret と呼ばれる 1 つのシークレット

必要な Gateway 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
    

Note

ALB コントローラーは、ARM で Application Gateway for Containers リソースを作成するときに、フロントエンド リソースに対して次の名前付け規則を使用します。fe-<ランダムに生成された 8 文字>

Azure で作成されたフロントエンドの名前を変更したい場合は、BYO デプロイ戦略に従うことを検討してください。

ゲートウェイ リソースが作成されたら、状態が有効であること、リスナーが [プログラム済み] であること、ゲートウェイにアドレスが割り当てられていることを確認します。

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

https 経由で受信したトラフィックを処理する contoso.com 用の HTTPRoute リソースを作成します。

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 リソースに [承認済み] と表示され、Application Gateway for Containers リソースが [プログラム済み] になっていることを確認します。

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

各 HTTPRoute で Application Gateway for Containers リソースが正常に更新されたことを確認します。

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

ゲートウェイが作成されたら、http トラフィックを https にリダイレクトする RequestRedirect フィルターを使用して、contoso.com 用の HTTPRoute リソースを作成します。

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 リソースに [承認済み] と表示され、Application Gateway for Containers リソースが [プログラム済み] になっていることを確認します。

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

各 HTTPRoute で Application Gateway for Containers リソースが正常に更新されたことを確認します。

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

/summer-promotion のパスの特定の URL へのリダイレクトを処理する contoso.com 用の HTTPRoute リソースを作成します。 http から https への HTTPRoute リソースに示されている sectionName を削除することで、このリダイレクト規則は 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 リソースに [承認済み] と表示され、Application Gateway for Containers リソースが [プログラム済み] になっていることを確認します。

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

各 HTTPRoute で Application Gateway for Containers リソースが正常に更新されたことを確認します。

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 を使用して、サンプル アプリケーションにトラフィックを送信する準備ができました。 次のコマンドを実行して、FQDN を取得します。

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

curl コマンドを使用してサーバー名インジケーターを指定すると、http://contoso.comlocation ヘッダーが https://contoso.com への 301 リダイレクトを定義する Application Gateway for Containers からの応答を返す必要があります。

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

curl コマンドを使用してサーバー名インジケーターを指定すると、https://contoso.com/summer-promotion Application Gateway for Containers は https://contoso.com/shop/category/5 への 302 リダイレクトを返す必要があります。

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 コントローラーをインストールし、バックエンド アプリケーションをデプロイし、Gateway API を使用して、HTTP から HTTPS へのリダイレクトと特定のクライアント要求へのパス ベースのリダイレクトの両方を構成しました。