Route HTTP requests to specific service versions based on URL query parameters. For example, route requests containing ?test-params=v1 to helloworld-v1 and requests containing ?test-params=v2 to helloworld-v2.
Query parameter matching uses the queryParams field in an Istio VirtualService to inspect URL query strings and route traffic to different destination subsets.
Supported match types
The queryParams field supports three match types through the Istio StringMatch type:
| Match type | Syntax | Example URL | Configuration |
|---|---|---|---|
| Exact | exact: "<value>" | ?key=true | exact: "true" |
| Prefix | prefix: "<value>" | ?key=abc or ?key=abx | prefix: "ab" |
| Regex | regex: "<pattern>" | ?key=123 | regex: "\\d+$" |
Regex patterns use RE2 syntax. For example,regex: "(?i)^aaa$"performs a case-insensitive match against the stringaaa.
Prerequisites
Before you begin, make sure that you have:
Completed the preparations described in Preparations
Deployed the
helloworldandsleepservices
Procedure
Step 1: Verify baseline behavior
Before applying routing rules, confirm that the helloworld service responds from both v1 and v2 at random.
Use kubectl to connect to the Container Service for Kubernetes (ACK) cluster with the kubeconfig file, then open a shell in the
sleeppod:kubectl exec -it deploy/sleep -- shSend a request to the
helloworldservice:curl helloworld:5000/helloThe response comes from either v1 or v2 at random. Example output:
Hello version: v1, instance: helloworld-v1-6d77f4c4cf-p****Hello version: v2, instance: helloworld-v2-6b96c5684-4****
Step 2: Create a destination rule
Define subsets for v1 and v2 of the helloworld service. For more information, see Manage destination rules.
Apply the following destination rule:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: helloworld
namespace: default
spec:
host: helloworld
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2This configuration groups helloworld service endpoints into two subsets based on the version label: v1 and v2.
Step 3: Create a virtual service with query parameter matching
Create a virtual service that routes requests based on the test-params query parameter. For more information, see Manage virtual services.
Apply the following virtual service:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: helloworld-vs
namespace: default
spec:
hosts:
- helloworld
http:
- match:
- queryParams:
test-params:
exact: v1
route:
- destination:
host: helloworld
subset: v1
- match:
- queryParams:
test-params:
exact: v2
route:
- destination:
host: helloworld
subset: v2This configuration applies two routing rules:
Requests with
?test-params=v1are routed to thev1subset.Requests with
?test-params=v2are routed to thev2subset.
Routing rules are evaluated top to bottom. The first matching rule takes effect. To handle unmatched requests, add a catch-all rule at the end without a match condition. For example: - route:
- destination:
host: helloworld
subset: v1Step 4: Verify query parameter routing
Open a shell in the
sleeppod:kubectl exec -it deploy/sleep -- shSend a request with
test-params=v1:curl helloworld:5000/hello?test-params=v1Expected output:
Hello version: v1, instance: helloworld-v1-6d77f4c4cf-p****Send a request with
test-params=v2:curl helloworld:5000/hello?test-params=v2Expected output:
Hello version: v2, instance: helloworld-v2-6b96c5684-4****
Combine query parameters with other match criteria
A single match entry can combine query parameters with other HTTP match fields such as headers, URI paths, or methods. When multiple fields appear in the same match entry, all conditions must be satisfied (AND logic).
The following example routes requests only when both the query parameter and a header match:
http:
- match:
- queryParams:
test-params:
exact: v1
headers:
x-custom-header:
exact: debug
route:
- destination:
host: helloworld
subset: v1To match on either condition (OR logic), define each condition in a separate match entry:
http:
- match:
- queryParams:
test-params:
exact: v1
- headers:
x-custom-header:
exact: debug
route:
- destination:
host: helloworld
subset: v1