# `Istio` Example: Request Routing
`Bookinfo` Application
## Tasks > Traffic Management > Request Routing
###### tags: `ITRI`, `istio`, `example`
***
## Reference
- Official Website: ISTIO > DOCS > TASKS > TRAFFIC MANAGEMENT > REQUEST ROUTING: [Request Routing](https://istio.io/docs/tasks/traffic-management/request-routing/)
- Blog of 青蛙小白: [Istio 1.0学习笔记(三):使用Istio对服务进行流量管理 - 配置请求路由](https://blog.frognew.com/2018/08/learning-istio-1.0-3.html)
***
## Target
This task shows you how to ++route requests dynamically++ to multiple versions of a microservice.
***
## Review *Bookinfo*

其中 `Bookinfo` 對 review 部屬了 v1~v3 共三種 version。
```bash
# kubectl get pod -l app=reviews -n istio-example
NAME READY STATUS RESTARTS AGE
reviews-v1-5787f7b87-5g6k4 2/2 Running 0 5h9m
reviews-v2-6d8b975647-t9t2m 2/2 Running 0 5h9m
reviews-v3-7d5549f9-sphc8 2/2 Running 0 5h9m
```
If you refresh the page several times (重新整理頁面多次時), you should see different versions of reviews shown in productpage.
- This is because without an explicit default service version to route to, Istio routes requests to all available versions in a round robin fashion.
- Since we haven’t yet used *Istio* to ++control the version routing++.
- Then it is presented in a *round robin* style (no stars, red stars, black stars).
***
## Apply default destination rules
Before using *Istio* to ++control the Bookinfo version routing++, we need to define the available versions, called *subsets*, in destination rules.
Create default destination rules for the *Bookinfo* services.
Since we did not enable mutual TLS,
```bash
# kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml -n istio-example
```
Display the destination rules.
```bash
# kubectl get destinationrules -n istio-example
NAME HOST AGE
details details 1d
productpage productpage 1d
ratings ratings 1d
reviews reviews 1d
```
***
# Request Routing
This task shows how to ++route requests dynamically++ to multiple versions of a microservice.
In this task, we apply rules that route all traffic to v1 (version 1) of the microservices.
## Apply a virtual service
To route to one version only, we apply *virtual services* that set the default version for the microservices. In this case, the virtual services will route all traffic to `v1` of each microservice.
*Virtual services* were applied in `samples/bookinfo/networking/virtual-service-all-v1.yaml`.
```yaml=
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: productpage
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- route:
- destination:
host: ratings
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: details
spec:
hosts:
- details
http:
- route:
- destination:
host: details
subset: v1
---
```
Apply the virtual services.
```bash
# kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
```
Check the virtual services.
```bash
# kubectl get virtualservice
NAME GATEWAYS HOSTS AGE
details [details] 1h
productpage [productpage] 1h
ratings [ratings] 1h
reviews [reviews] 1h
```
## Result
Go to the url: `http://100.86.1.141/productpage`, we would see no stars are on the page again.
***
# Route based on user identity
## Target
Change the route configuration so that all traffic from a specific user is routed to a specific service version. In this case, all traffic from a user named *Jason* will be routed to the service `reviews:v2`.
## How to identify the specific user?
*Istio* doesn’t have any special, built-in understanding of user identity. This example is enabled by the fact that the `productpage` service ++adds a custom `end-user` header++ to all outbound HTTP requests to the reviews service.
- 因此 *Istio* 實際上並不知道倒底是哪個 user 發出 request。
- 再將上方說明文字解釋一次:這個例子是 `productpage service` → `review service` 的 request 加上 `end-user` header field 並通過判斷 header 實現的。
- Reminder that `reviews:v2` is the version that includes the star ratings feature.
|Version|GUI|
|-|-|
|v2|<li>Version v2 calls the `ratings` service, and displays each rating as 1 to 5 ++black++ stars.</li> |
## Apply a virtual service
*Virtual services* were applied in `samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml`.
```yaml=
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
```
- When matching `end-user=jason`, this request would be routed to `reviews:v2`.
- Other requests would be routed to `reviews:v1`.
Apply the virtual services.
```bash
# kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml -n istio-example
```
## Result
Open browser to `http://$GATEWAY_URL/productpage` to view the Bookinfo web page. And sign in *jason* without any password.

Refresh the browser. We would see the black start as `review:v2` there always.

Log in as another user (pick any name you wish). Refresh the browser. Now the stars are gone. This is because traffic is routed to `reviews:v1` for all users except *Jason*.
***
## Clean Up
Remove the application virtual services.
```bash
# kubectl delete -f samples/bookinfo/networking/virtual-service-all-v1.yaml -n istio-example
```
If we want to clear all the `Bookinfo` example, use the script.
```bash
# samples/bookinfo/platform/kube/cleanup.sh
```
Confirm shutdown.
```bash
# kubectl get virtualservices -n istio-example #-- there should be no virtual services
# kubectl get destinationrules -n istio-example #-- there should be no destination rules
# kubectl get gateway -n istio-example #-- there should be no gateway
# kubectl get pods -n istio-example #-- the Bookinfo pods should be deleted
```
***
<center>** End **</center>
***
***