Additional route settings
Configure additional route table settings, such as setting a default destination or weighted routing to version subsets.
When you forward requests to a Kubernetes service, virtual destination, or external service, you can configure additional settings in your route table. Review the following sections to set a default destination, route to an application subset, or assign weights to app instances.
Set a default destination
Set a default destination in a route table so that multiple routes can be easily assigned to that destination.
For example, you might want to designate multiple routes for one destination, for the purpose of assigning certain policies to certain routes. Instead of typing out the same destination definition in each of the routes, you can instead define the destination as the default, and leave the forwardTo
directive in each route empty. Note that any routes in the route table that do not specify a destination will forward traffic to the default destination.
In this example route table, the information for the ratings
destination is defined in the spec.defaultDestination
field, rather than repeated in each http
route. This way, the two routes can automatically reference the ratings definition.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
annotations:
cluster.solo.io/cluster: ""
name: www-example-com
namespace: bookinfo
spec:
defaultDestination:
port:
number: 9080
ref:
name: ratings
namespace: bookinfo
hosts:
- www.example.com
http:
- forwardTo: {}
labels:
"no": auth
matchers:
- headers:
- name: noauth
value: "true"
name: ratings-ingress-no-auth
- forwardTo: {}
labels:
route: ratings
name: ratings-ingress
virtualGateways:
- name: istio-ingressgateway
Weighted routing to an application subset
If you are testing multiple versions of your app within your cluster environment, you can route to each version by using the version numbers. Additionally, you can optionally assign weights to each version of the app to determine the load or requests that each version receives.
For example, say that your app deployment for each version contains the app: global-app
label, and labels such as version: v1
and version: v2
. In the route table, you add references to the both versions of the app, and specify the version labels in the subset
field of each reference section.
Additionally, this example route table specifies an optional weight
for each version of the app. 75% of traffic requests to the /global-app
are directed to v1
, and 25% of traffic requests are directed to v2
. Weighted routing can be useful in scenarios such as controlled rollouts to slowly move traffic from an older to a newer version of your app.
The following example route tables are provided for quick reference. For an extended example on weighted subset routing, check out the Online Boutique app example in the Solo Communities of Practice repo.
Kubernetes service routing
In the reference for each Kubernetes service, add subsets and weights.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: global-app-routes
namespace: global
spec:
hosts:
- '*'
# Selects the virtual gateway you previously created
virtualGateways:
- name: istio-ingressgateway
namespace: bookinfo
cluster: ${CLUSTER_NAME}
http:
# Route for the global-app service
- name: global-app
# Prefix matching
matchers:
- uri:
prefix: /global-app
# Forwarding directive
forwardTo:
destinations:
# Reference to Kubernetes service for version 1 of the app in this cluster
- ref:
name: global-app
namespace: global
cluster: ${CLUSTER_NAME}
port:
number: 9080
# Label for v1
subset:
version: v1
# 75% of request traffic to /global-app
weight: 75
# Reference to Kubernetes service for version 2 of the app in this cluster
- ref:
name: global-app
namespace: global
cluster: ${CLUSTER_NAME}
port:
number: 9080
# Label for v2
subset:
version: v2
# 25% of request traffic to /global-app
weight: 25
Virtual destination routing
For each service that your virtual destination exposes, add a reference to the virtual destination. Then, add a version subset and weight to each of the references.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: global-app-routes
namespace: global
spec:
hosts:
- '*'
# Selects the virtual gateway you previously created
virtualGateways:
- name: istio-ingressgateway
namespace: bookinfo
cluster: ${CLUSTER_NAME}
http:
# Route for the global-app service
- name: global-app
# Prefix matching
matchers:
- uri:
prefix: /global-app
# Forwarding directive
forwardTo:
destinations:
# Reference to the virtual destination that selects v1 of the global-app service
- ref:
name: global-app
kind: VIRTUAL_DESTINATION
subset:
version: v1
# 75% of request traffic to /global-app
weight: 75
# Reference to the virtual destination that selects v2 of the global-app service
- ref:
name: global-app
kind: VIRTUAL_DESTINATION
subset:
version: v2
# 25% of request traffic to /global-app
weight: 25
Route table annotations for Istio virtual services
You can add annotations to the route table that are populated to the Istio virtual service that the route table is translated to. A common example is to add annotations to exclude the virtual service from being managed by ExternalDNS, such as in cases where you want to manually manage the DNS record or integrate it with a different DNS provider.
Keep in mind the following rules when adding annotations to a virtual service via route tables:
- Annotations that are automatically set by Gloo Mesh Gateway, such as
cluster.solo.io/cluster
cannot be overwritten. If you specify an annotation that is set by Gloo Mesh Gateway, the annotation is ignored. - Annotation keys must be unique. You cannot add multiple annotations with the same key, but different values, such as
external-dns.alpha.kubernetes.io/exclude: "true"
andexternal-dns.alpha.kubernetes.io/exclude: "false"
. If you add multiple annotations with the same key to the route table, the Kubernetes API server randomly selects one of the keys and creates the route table with that key-value pair. All other duplicate keys are ignored. Because of that, the corresponding virtual service is created with the same key-value pair that was added to the route table. - If you have a delegated route table setup, annotations can be added only to parent route tables. When you add the annotation to a child or grandchild route table, the annotation is ignored and a warning is added to the status of the child or grandchild route table.
To add annotations via a route table:
Create a route table with the
cluster.solo.io/cluster: mycluster
annotation to verify that you cannot create a conflicting annotation. This annotation is automatically added by Gloo Mesh Gateway when the route table is translated into an Istio virtual service. Although you can create the route table, the annotation is not added to the translated virtual service.kubectl apply -f- <<EOF apiVersion: networking.gloo.solo.io/v2 kind: RouteTable metadata: name: annotations namespace: bookinfo spec: hosts: - annotations.com # Selects the virtual gateway you previously created virtualGateways: - name: istio-ingressgateway namespace: bookinfo virtualServiceAnnotations: cluster.solo.io/cluster: mycluster http: # Route for the main productpage app - name: productpage matchers: - uri: prefix: /productpage forwardTo: destinations: - ref: name: productpage namespace: bookinfo port: number: 9080 EOF
Get the details of the route table and verify that you see a warning about the existing cluster annotation.
kubectl get routetable annotations -n bookinfo -o yaml
Example output:
status: common: State: approval: WARNING message: '[1 WARNINGS]: skipping virtualServiceAnnotations with key cluster.solo.io/cluster since an annotation with this key is already present in the VirtualService metadata ' observedGeneration: 1 workspaceConditions: WARNING: 1
Verify that the annotation is not added to the Istio virtual service.
Get the name of the virtual service.
kubectl get virtualservices -n gloo-mesh-gateways | grep routetable-annotations
Get the details of the virtual service.
kubectl get virtualservice <name> -n gloo-mesh-gateways -o yaml
Modify the route table and add other annotations. For example, you can add an annotation to exclude a service from being managed by ExternalDNS as shown in the following example. This setup can be useful if you want to manually manage the DNS record for the ingress gateway, or integrate and manage it via a different DNS provider.
kubectl apply -f- <<EOF apiVersion: networking.gloo.solo.io/v2 kind: RouteTable metadata: name: annotations namespace: bookinfo spec: hosts: - annotations.com # Selects the virtual gateway you previously created virtualGateways: - name: istio-ingressgateway namespace: bookinfo virtualServiceAnnotations: external-dns.alpha.kubernetes.io/exclude: "true" external-dns.alpha.kubernetes.io/ttl: "60" http: # Route for the main productpage app - name: productpage matchers: - uri: prefix: /productpage forwardTo: destinations: - ref: name: productpage namespace: bookinfo port: number: 9080 EOF
Get the details of the route table and verify that it shows a status of
ACCEPTED
.kubectl get routetable annotations -n bookinfo -o yaml
Verify that the annotations are added to the virtual service.
kubectl get virtualservice <name> -n gloo-mesh-gateways -o yaml
Example output:
apiVersion: networking.istio.io/v1 kind: VirtualService metadata: annotations: cluster.solo.io/cluster: gloo-gateway-docs-mgt external-dns.alpha.kubernetes.io/exclude: "true" external-dns.alpha.kubernetes.io/ttl: "60" ...
Optional: Clean up the resources that you created in this guide.
kubectl delete routetable annotations -n bookinfo