共用方式為


容器 Azure 應用程式閘道 URL 重新導向 - 閘道 API

適用於容器的應用程式閘道可讓您根據 URL 的三個層面,將重新導向回應傳回給用戶端:通訊協定、主機名稱和路徑。 針對每個重新導向,定義的 HTTP 狀態碼可能會傳回給用戶端,以定義重新導向的性質。

使用方式詳細資料

URL 重新導向會利用 Kubernetes 閘道 API 所定義的 RequestRedirect 規則篩選

重新導向

重新導向會設定傳回給用戶端的回應狀態碼,以了解重新導向的用途。 支援下列重新導向類型:

  • 301 (永久移動):表示已指派新的永久 URI 給目標資源。 此資源的未來參考會使用其中一個封閉的 URI。 針對 HTTP 至 HTTPS 重新導向使用 301 狀態碼。
  • 302 (已找到):表示目標資源暫時位於不同的 URI。 由於重新導向有時會變更,對於未來的要求,用戶端應該繼續使用有效要求 URI。

重新導向功能

  • 通訊協定重新導向通常用來告訴用戶端從未加密流量配置移動到流量,例如 HTTP 到 HTTPS 重新導向。

  • 主機名稱重新導向符合要求的完整網域名稱 (fqdn)。 這通常會在將舊網域名稱重新導向到新網域名稱時觀察到;例如將 contoso.com 重新導向到 fabrikam.com

  • 路徑重新導向有兩個不同的變體:prefixfull

    • 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 發起的第二個要求會傳回一個重新導向,以發起針對其 HTTPs 變體的新連線。

圖表顯示適用於容器的應用程式閘道將重新導向 URL 傳回給用戶端。

必要條件

  1. 如果遵循 BYO 部署策略,請確定您已設定適用於容器的應用程式閘道資源和 ALB 控制器

  2. 如果遵循 ALB 受管理的部署策略,請確定您已透過 ApplicationLoadBalancer 自訂資源佈建 ALB 控制器 以及適用於容器的應用程式閘道資源。

  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 的命名空間
    • test-infra 命名空間中名為 echo 的一個服務
    • test-infra 命名空間中名為 echo 的一個部署
    • test-infra 命名空間中名為 listener-tls-secret 的一個密碼

部署必要的閘道 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 中建立適用於容器的應用程式閘道資源時,ALB 控制器會針對前端資源使用下列命名慣例: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

建立閘道之後,請使用 RequestRedirect 篩選器建立 的 contoso.com HTTPRoute 資源,以將 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

建立 的 contoso.com HTTPRoute 資源,以處理路徑 /summer-promotion 至特定 URL 的重新導向。 藉由排除 HTTP to 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 資源顯示 [已接受],且適用於容器的應用程式閘道資源的狀態為 [已程式化]

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 傳送至範例應用程式。 使用下列命令來取得 FQDN。

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

當您使用 curl 命令指定伺服器名稱指標時,http://contoso.com 應該會使用定義對 https://contoso.com 進行 301 重新導向的 location 標頭,從適用於容器的應用程式閘道傳回回應。

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 適用於容器的應用程式閘道應該會傳回對 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 控制器、部署後端應用程式,並使用閘道 API 來設定 HTTP 至 HTTPS 重新導向和路徑型重新導向至特定用戶端要求。