|
| 1 | +--- |
| 2 | +title: Path, header, and query string routing with Application Gateway for Containers - Gateway API (preview) |
| 3 | +description: Learn how to configure Application Gateway for Containers with support with path, header, and query string routing. |
| 4 | +services: application-gateway |
| 5 | +author: greglin |
| 6 | +ms.service: application-gateway |
| 7 | +ms.subservice: appgw-for-containers |
| 8 | +ms.topic: how-to |
| 9 | +ms.date: 07/29/2023 |
| 10 | +ms.author: greglin |
| 11 | +--- |
| 12 | + |
| 13 | +# Path, header, and query string routing with Application Gateway for Containers - Gateway API (preview) |
| 14 | + |
| 15 | +This document helps set up an example application that uses resources from Gateway API to demonstrate traffic routing based on URL path, query string, and header: |
| 16 | +- [Gateway](https://gateway-api.sigs.k8s.io/concepts/api-overview/#gateway) - creating a gateway with one https listener |
| 17 | +- [HTTPRoute](https://gateway-api.sigs.k8s.io/v1alpha2/api-types/httproute/) - creating an HTTP route that references a backend service |
| 18 | +- [HTTPRouteMatch](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteMatch) - Using `matches` to route based on path, header, and query string. |
| 19 | + |
| 20 | +## Prerequisites |
| 21 | + |
| 22 | +> [!IMPORTANT] |
| 23 | +> Application Gateway for Containers is currently in PREVIEW.<br> |
| 24 | +> See the [Supplemental Terms of Use for Microsoft Azure Previews](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) for legal terms that apply to Azure features that are in beta, preview, or otherwise not yet released into general availability. |
| 25 | +
|
| 26 | +1. If following the BYO deployment strategy, ensure you have set up your Application Gateway for Containers resources and [ALB Controller](quickstart-deploy-application-gateway-for-containers-alb-controller.md) |
| 27 | +2. If following the ALB managed deployment strategy, ensure you have provisioned your [ALB Controller](quickstart-deploy-application-gateway-for-containers-alb-controller.md) and provisioned the Application Gateway for Containers resources via the [ApplicationLoadBalancer custom resource](quickstart-create-application-gateway-for-containers-managed-by-alb-controller.md). |
| 28 | +3. Deploy sample HTTP application |
| 29 | + Apply the following deployment.yaml file on your cluster to create a sample web application to demonstrate path, query, and header based routing. |
| 30 | + ```bash |
| 31 | + kubectl apply -f https://trafficcontrollerdocs.blob.core.windows.net/examples/traffic-split-scenario/deployment.yaml |
| 32 | + ``` |
| 33 | + |
| 34 | + This command creates the following on your cluster: |
| 35 | + - a namespace called `test-infra` |
| 36 | + - 2 services called `backend-v1` and `backend-v2` in the `test-infra` namespace |
| 37 | + - 2 deployments called `backend-v1` and `backend-v2` in the `test-infra` namespace |
| 38 | + |
| 39 | +## Deploy the required Gateway API resources |
| 40 | + |
| 41 | +# [ALB managed deployment](#tab/alb-managed) |
| 42 | + |
| 43 | +Create a gateway: |
| 44 | + |
| 45 | +```bash |
| 46 | +kubectl apply -f - <<EOF |
| 47 | +apiVersion: gateway.networking.k8s.io/v1beta1 |
| 48 | +kind: Gateway |
| 49 | +metadata: |
| 50 | + name: gateway-01 |
| 51 | + namespace: test-infra |
| 52 | + annotations: |
| 53 | + alb.networking.azure.io/alb-namespace: alb-test-infra |
| 54 | + alb.networking.azure.io/alb-name: alb-test |
| 55 | +spec: |
| 56 | + gatewayClassName: azure-alb-external |
| 57 | + listeners: |
| 58 | + - name: http-listener |
| 59 | + port: 80 |
| 60 | + protocol: HTTP |
| 61 | + allowedRoutes: |
| 62 | + namespaces: |
| 63 | + from: Same |
| 64 | +EOF |
| 65 | +``` |
| 66 | + |
| 67 | + |
| 68 | +# [Bring your own (BYO) deployment](#tab/byo) |
| 69 | +1. Set the following environment variables |
| 70 | + |
| 71 | +```bash |
| 72 | +RESOURCE_GROUP='<resource group name of the Application Gateway For Containers resource>' |
| 73 | +RESOURCE_NAME='alb-test' |
| 74 | + |
| 75 | +RESOURCE_ID=$(az network alb show --resource-group $RESOURCE_GROUP --name $RESOURCE_NAME --query id -o tsv) |
| 76 | +FRONTEND_NAME='frontend' |
| 77 | +``` |
| 78 | + |
| 79 | +2. Create a Gateway |
| 80 | +```bash |
| 81 | +kubectl apply -f - <<EOF |
| 82 | +apiVersion: gateway.networking.k8s.io/v1beta1 |
| 83 | +kind: Gateway |
| 84 | +metadata: |
| 85 | + name: gateway-01 |
| 86 | + namespace: test-infra |
| 87 | + annotations: |
| 88 | + alb.networking.azure.io/alb-id: $RESOURCE_ID |
| 89 | +spec: |
| 90 | + gatewayClassName: azure-alb-external |
| 91 | + listeners: |
| 92 | + - name: http-listener |
| 93 | + port: 80 |
| 94 | + protocol: HTTP |
| 95 | + allowedRoutes: |
| 96 | + namespaces: |
| 97 | + from: Same |
| 98 | + addresses: |
| 99 | + - type: alb.networking.azure.io/alb-frontend |
| 100 | + value: $FRONTEND_NAME |
| 101 | +EOF |
| 102 | +``` |
| 103 | + |
| 104 | +--- |
| 105 | + |
| 106 | +Once the gateway resource has been created, ensure the status is valid, the listener is _Programmed_, and an address is assigned to the gateway. |
| 107 | +```bash |
| 108 | +kubectl get gateway gateway-01 -n test-infra -o yaml |
| 109 | +``` |
| 110 | + |
| 111 | +Example output of successful gateway creation. |
| 112 | +```yaml |
| 113 | +status: |
| 114 | + addresses: |
| 115 | + - type: IPAddress |
| 116 | + value: xxxx.yyyy.alb.azure.com |
| 117 | + conditions: |
| 118 | + - lastTransitionTime: "2023-06-19T21:04:55Z" |
| 119 | + message: Valid Gateway |
| 120 | + observedGeneration: 1 |
| 121 | + reason: Accepted |
| 122 | + status: "True" |
| 123 | + type: Accepted |
| 124 | + - lastTransitionTime: "2023-06-19T21:04:55Z" |
| 125 | + message: Application Gateway For Containers resource has been successfully updated. |
| 126 | + observedGeneration: 1 |
| 127 | + reason: Programmed |
| 128 | + status: "True" |
| 129 | + type: Programmed |
| 130 | + listeners: |
| 131 | + - attachedRoutes: 0 |
| 132 | + conditions: |
| 133 | + - lastTransitionTime: "2023-06-19T21:04:55Z" |
| 134 | + message: "" |
| 135 | + observedGeneration: 1 |
| 136 | + reason: ResolvedRefs |
| 137 | + status: "True" |
| 138 | + type: ResolvedRefs |
| 139 | + - lastTransitionTime: "2023-06-19T21:04:55Z" |
| 140 | + message: Listener is accepted |
| 141 | + observedGeneration: 1 |
| 142 | + reason: Accepted |
| 143 | + status: "True" |
| 144 | + type: Accepted |
| 145 | + - lastTransitionTime: "2023-06-19T21:04:55Z" |
| 146 | + message: Application Gateway For Containers resource has been successfully updated. |
| 147 | + observedGeneration: 1 |
| 148 | + reason: Programmed |
| 149 | + status: "True" |
| 150 | + type: Programmed |
| 151 | + name: https-listener |
| 152 | + supportedKinds: |
| 153 | + - group: gateway.networking.k8s.io |
| 154 | + kind: HTTPRoute |
| 155 | +``` |
| 156 | +
|
| 157 | +Once the gateway has been created, create an HTTPRoute to define two different matches and a default service to route traffic to. |
| 158 | +
|
| 159 | +The way the following rules read are as follows: |
| 160 | +1) If the path is /bar, traffic is routed to backend-v2 service on port 8080 OR |
| 161 | +2) If the request contains an HTTP header with the name magic and the value foo, the URL contains a query string defining the name great with a value of example, AND the path is /some/thing, the request will be sent to backend-v2 on port 8080. |
| 162 | +3) Else all other requests will be routed to backend-v1 service on port 8080. |
| 163 | +
|
| 164 | +```bash |
| 165 | +kubectl apply -f - <<EOF |
| 166 | +apiVersion: gateway.networking.k8s.io/v1beta1 |
| 167 | +kind: HTTPRoute |
| 168 | +metadata: |
| 169 | + name: http-route |
| 170 | + namespace: test-infra |
| 171 | +spec: |
| 172 | + parentRefs: |
| 173 | + - name: gateway-01 |
| 174 | + namespace: test-infra |
| 175 | + rules: |
| 176 | + - matches: |
| 177 | + - path: |
| 178 | + type: PathPrefix |
| 179 | + value: /bar |
| 180 | + backendRefs: |
| 181 | + - name: backend-v2 |
| 182 | + port: 8080 |
| 183 | + - matches: |
| 184 | + - headers: |
| 185 | + - type: Exact |
| 186 | + name: magic |
| 187 | + value: foo |
| 188 | + queryParams: |
| 189 | + - type: Exact |
| 190 | + name: great |
| 191 | + value: example |
| 192 | + path: |
| 193 | + type: PathPrefix |
| 194 | + value: /some/thing |
| 195 | + method: GET |
| 196 | + backendRefs: |
| 197 | + - name: backend-v2 |
| 198 | + port: 8080 |
| 199 | + - backendRefs: |
| 200 | + - name: backend-v1 |
| 201 | + port: 8080 |
| 202 | +EOF |
| 203 | +``` |
| 204 | + |
| 205 | +Once the HTTPRoute resource has been created, ensure the route has been _Accepted_ and the Application Gateway for Containers resource has been _Programmed_. |
| 206 | +```bash |
| 207 | +kubectl get httproute http-route -n test-infra -o yaml |
| 208 | +``` |
| 209 | + |
| 210 | +Verify the status of the Application Gateway for Containers resource has been successfully updated. |
| 211 | + |
| 212 | +```yaml |
| 213 | +status: |
| 214 | + parents: |
| 215 | + - conditions: |
| 216 | + - lastTransitionTime: "2023-06-19T22:18:23Z" |
| 217 | + message: "" |
| 218 | + observedGeneration: 1 |
| 219 | + reason: ResolvedRefs |
| 220 | + status: "True" |
| 221 | + type: ResolvedRefs |
| 222 | + - lastTransitionTime: "2023-06-19T22:18:23Z" |
| 223 | + message: Route is Accepted |
| 224 | + observedGeneration: 1 |
| 225 | + reason: Accepted |
| 226 | + status: "True" |
| 227 | + type: Accepted |
| 228 | + - lastTransitionTime: "2023-06-19T22:18:23Z" |
| 229 | + message: Application Gateway For Containers resource has been successfully updated. |
| 230 | + observedGeneration: 1 |
| 231 | + reason: Programmed |
| 232 | + status: "True" |
| 233 | + type: Programmed |
| 234 | + controllerName: alb.networking.azure.io/alb-controller |
| 235 | + parentRef: |
| 236 | + group: gateway.networking.k8s.io |
| 237 | + kind: Gateway |
| 238 | + name: gateway-01 |
| 239 | + namespace: test-infra |
| 240 | + ``` |
| 241 | +
|
| 242 | +## Test access to the application |
| 243 | +
|
| 244 | +Now we're ready to send some traffic to our sample application, via the FQDN assigned to the frontend. Use the following command to get the FQDN. |
| 245 | +
|
| 246 | +```bash |
| 247 | +fqdn=$(kubectl get gateway gateway-01 -n test-infra -o jsonpath='{.status.addresses[0].value}') |
| 248 | +``` |
| 249 | + |
| 250 | +By using the curl command, we can validate three different scenarios: |
| 251 | + |
| 252 | +### Path based routing |
| 253 | +In this scenario, the client request sent to http://frontend-fqdn/bar will be routed to backend-v2 service. |
| 254 | + |
| 255 | +Run the following command: |
| 256 | +```bash |
| 257 | +curl http://$fqdn/bar |
| 258 | +``` |
| 259 | + |
| 260 | +Notice the container serving the request is backend-v2. |
| 261 | + |
| 262 | +### Query string + header + path routing |
| 263 | +In this scenario, the client request sent to http://frontend-fqdn/some/thing?great=example with a header key/value part of "magic: foo" will be routed to backend-v2 service. |
| 264 | + |
| 265 | +Run the following command: |
| 266 | +```bash |
| 267 | +curl http://$fqdn/some/thing?great=example -H "magic: foo" |
| 268 | +``` |
| 269 | + |
| 270 | +Notice the container serving the request is backend-v2. |
| 271 | + |
| 272 | +### Default route |
| 273 | +If neither of the first two scenarios are satisfied, Application Gateway for Containers will route all other requests to the backend-v1 service. |
| 274 | + |
| 275 | +Run the following command: |
| 276 | +```bash |
| 277 | +curl http://$fqdn/ |
| 278 | +``` |
| 279 | + |
| 280 | +Notice the container serving the request is backend-v1. |
| 281 | + |
| 282 | +Congratulations, you have installed ALB Controller, deployed a backend application and routed traffic to the application via Gateway API on Application Gateway for Containers. |
0 commit comments