Share via


適用於容器的 Azure 應用程式閘道 URL 重寫 - 閘道 API (預覽)

適用於容器的應用程式閘道可用於重寫用戶端要求的 URL,包括要求的主機名和/或路徑。 適用於容器的應用程式閘道向後端目標發起要求時,要求將包含重寫的新 URL 以發起要求。

使用方式詳細資料

URL 重寫會利用 Kubernetes 閘道 API 所定義的篩選條件。

背景

藉助 URL 重寫,您可以在向後端目標發起要求時,將傳入要求轉譯為不同的 URL。

下圖中的範例說明了 contoso.com/shop 的目標要求如何重寫為 contoso.com/ecommerce。 由適用於容器的應用程式閘道向後端目標發起要求:

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

必要條件

重要

適用於容器的應用程式閘道目前為預覽版。
請參閱 Microsoft Azure 預覽版增補使用規定,以了解適用於 Azure 功能 (搶鮮版 (Beta)、預覽版,或尚未正式發行的版本) 的法律條款。

  1. 如果遵循 BYO 部署策略,請確定您已設定了適用於容器的應用程式閘道和 ALB 控制器
  2. 如果遵循 ALB 受控部署策略,請確定您已透過 ApplicationLoadBalancer 自訂資源佈建了 ALB 控制器,以及適用於容器的應用程式閘道。
  3. 部署範例 HTTP 應用程式在您的叢集上套用下列 deployment.yaml 檔案來建立範例 Web 應用程式,從而示範路徑、查詢和標頭型路由。
kubectl apply -f https://trafficcontrollerdocs.blob.core.windows.net/examples/traffic-split-scenario/deployment.yaml

此指令會在您的叢集上建立下列物件:

  • 名為 test-infra 的命名空間
  • test-infra 命名空間中的兩個服務,分別名為 backend-v1backend-v2
  • test-infra 命名空間中的兩個部署,分別名為 backend-v1backend-v2

部署必要的閘道 API 資源

  1. 建立閘道
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
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

注意

當 ALB 控制器在 ARM 中建立適用於容器的應用程式閘道資源時,ALB 控制器會針對前端資源使用下列命名慣例:fe-<8 個隨機產生的字元>

如果您要變更在 Azure 中建立的前端名稱,請考慮遵循自備部署策略

建立閘道資源之後,請確定狀態有效,接聽程式的狀態為 [已程式化],並且已經將位址指派給閘道。

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

成功建立閘道後輸出內容的範例。

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

建立閘道之後,請為 contoso.com 建立 HTTPRoute 資源。 此範例可確保傳送至 contoso.com/shop 的流量會作為 contoso.com/ecommerce 引入到後端目標中。

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
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

建立 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 命令指定伺服器名稱指標時,contoso.com/shop 應該從 backend-v1 服務傳回回應,且後端目標的要求路徑會顯示 contoso.com/ecommerce

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

透過回應,應能看到下列內容:

{
 "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"
}

當您使用 curl 命令指定伺服器名稱指標時,contoso.com 應該從 backend-v2 服務傳回回應。

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

透過回應,應能看到下列內容:

{
 "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"
}

恭喜您,您已安裝了 ALB 控制器、部署了後端應用程式,並使用篩選重寫了用戶端要求的 URL,之後便可以將流量設定為適用於容器的應用程式閘道上的目標。