共用方式為


適用於容器的 Azure 應用程式閘道 URL 重寫 - 輸入 API

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

使用方式詳細資料

URL 重寫會利用適用於容器的應用程式閘道的 IngressExtension 自訂資源。

背景

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

下圖說明了適用於容器的應用程式閘道向後端目標發起要求時,送往 contoso.com/shop 的要求是如何重寫為送往 contoso.com/ecommerce

圖表顯示適用於容器的應用程式閘道正在將 URL 重寫至後端。

必要條件

  1. 如果遵循 BYO 部署策略,請確定您已設定適用於容器的應用程式閘道資源和 ALB 控制器
  2. 如果遵循 ALB 受管理的部署策略,請確定您已透過 ApplicationLoadBalancer 自訂資源佈建 ALB 控制器 以及適用於容器的應用程式閘道資源。
  3. 部署範例 HTTP 應用程式:
    在您的叢集上套用下列 deployment.yaml 檔案,以建立範例 Web 應用程式來示範路徑、查詢和標頭型路由。
kubectl apply -f https://raw.githubusercontent.com/MicrosoftDocs/azure-docs/refs/heads/main/articles/application-gateway/for-containers/examples/traffic-split-scenario/deployment.yaml

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

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

部署必要的輸入 API 資源

  1. 建立攔截所有流量,並路由至 backend-v2 的輸入
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-01
  namespace: test-infra
  annotations:
    alb.networking.azure.io/alb-name: alb-test
    alb.networking.azure.io/alb-namespace: alb-test-infra
spec:
  ingressClassName: azure-alb-external
  rules:
    - host: contoso.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: backend-v2
                port:
                  number: 8080
EOF
  1. 建立與 /shop 前置詞相符,且路由至 backend-v1 的輸入
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-02
  namespace: test-infra
  annotations:
    alb.networking.azure.io/alb-name: alb-test
    alb.networking.azure.io/alb-namespace: alb-test-infra
    alb.networking.azure.io/alb-ingress-extension: url-rewrite
spec:
  ingressClassName: azure-alb-external
  rules:
    - host: contoso.com
      http:
        paths:
          - path: /shop
            pathType: Prefix
            backend:
              service:
                name: backend-v1
                port:
                  number: 8080
EOF

注意

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

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

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

kubectl get ingress ingress-01 -n test-infra -o yaml
kubectl get ingress ingress-02 -n test-infra -o yaml

其中一個輸入資源的輸出範例。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    alb.networking.azure.io/alb-frontend: FRONTEND_NAME
    alb.networking.azure.io/alb-id: /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/yyyyyyyy/providers/Microsoft.ServiceNetworking/trafficControllers/zzzzzz
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"annotations":{"alb.networking.azure.io/alb-frontend":"FRONTEND_NAME","alb.networking.azure.io/alb-id":"/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/yyyyyyyy/providers/Microsoft.ServiceNetworking/trafficControllers/zzzzzz"},"name"
:"ingress-01","namespace":"test-infra"},"spec":{"ingressClassName":"azure-alb-external","rules":[{"host":"contoso.com","http":{"paths":[{"backend":{"service":{"name":"backend-v2","port":{"number":8080}}},"path":"/","pathType":"Prefix"}]}}]}}
  creationTimestamp: "2023-07-22T18:02:13Z"
  generation: 2
  name: ingress-01
  namespace: test-infra
  resourceVersion: "278238"
  uid: 17c34774-1d92-413e-85ec-c5a8da45989d
spec:
  ingressClassName: azure-alb-external
  rules:
  - host: contoso.com
    http:
      paths:
      - backend:
          service:
            name: backend-v2
            port:
              number: 8080
        path: /
        pathType: Prefix
status:
  loadBalancer:
    ingress:
    - hostname: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.fzyy.alb.azure.com
      ports:
      - port: 80
        protocol: TCP

建立輸入之後,為 contoso.com 建立 IngressExtension 資源。 此範例可確保傳送至 contoso.com/shop 的流量會以 contoso.com/ecommerce 的形式在後端目標發起。

kubectl apply -f - <<EOF
apiVersion: alb.networking.azure.io/v1
kind: IngressExtension
metadata:
  name: url-rewrite
  namespace: test-infra
spec:
  rules:
    - host: contoso.com
      rewrites:
      - type: URLRewrite
        urlRewrite:
          path:
            type: ReplacePrefixMatch
            replacePrefixMatch: /ecommerce
EOF

建立 IngressExtension 資源後,請確定 IngressExtension 資源顯示 [已接受],且適用於容器的應用程式閘道資源的狀態為 [已程式化]

kubectl get IngressExtension url-rewrite -n test-infra -o yaml

確認適用於容器的應用程式閘道資源已針對 IngressExtension 成功更新。

測試應用程式的存取權

現在我們已準備好將一些流量透過指派給前端的 FQDN 傳送至範例應用程式。 請使用下列命令來取得 FQDN。

fqdn=$(kubectl get ingress ingress-01 -n test-infra -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')

若使用 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 控制器、部署了後端應用程式,並使用 IngressExtension 重寫了用戶端要求的 URL,之後便可以將流量設定為適用於容器的應用程式閘道上的目標。