適用於容器的 Azure 應用程式閘道 URL 重寫 - 輸入 API
適用於容器的應用程式閘道可用於重寫用戶端要求的 URL,包括要求的主機名稱及/或路徑。 適用於容器的應用程式閘道向後端目標發起要求時,要求將包含重寫的新 URL 以發起要求。
使用方式詳細資料
URL 重寫會利用適用於容器的應用程式閘道的 IngressExtension 自訂資源。
背景
透過 URL 重寫,您可以在向後端目標發起要求時,將傳入要求轉譯為不同的 URL。
下圖說明了適用於容器的應用程式閘道向後端目標發起要求時,送往 contoso.com/shop 的要求是如何重寫為送往 contoso.com/ecommerce:
必要條件
- 如果遵循 BYO 部署策略,請確定您已設定適用於容器的應用程式閘道資源和 ALB 控制器。
- 如果遵循 ALB 受管理的部署策略,請確定您已透過 ApplicationLoadBalancer 自訂資源佈建 ALB 控制器 以及適用於容器的應用程式閘道資源。
- 部署範例 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-v1
和backend-v2
- 在
test-infra
命名空間中的兩個部署,分別名為backend-v1
和backend-v2
部署必要的輸入 API 資源
- 建立攔截所有流量,並路由至 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
- 建立與 /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,之後便可以將流量設定為適用於容器的應用程式閘道上的目標。