# Istio - Bookinfo Application

The Bookinfo application is broken into four separate microservices:

  • productpage - the productpage microservice calls the details and reviews microservices to populate the page.
  • details - the details microservice contains book information.
  • reviews - the reviews microservice contains book reviews. It also calls the ratings microservice.
  • ratings - the ratings microservice contains book ranking information that accompanies a book review.

There are 3 versions of the reviews microservice:

  • Version v1 - doesn’t call the ratings service.

    Bookinfo v1

  • Version v2 - calls the ratings service, and displays each rating as 1 to 5 black stars.

    Bookinfo v2

  • Version v3 - calls the ratings service, and displays each rating as 1 to 5 red stars.

    Bookinfo v3

Bookinfo (opens new window) application architecture:

Application Architecture with Istio

Deploy the demo of Bookinfo (opens new window) application:

kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
sleep 400

Confirm all services and pods are correctly defined and running:

kubectl get svc,deployment,pods -o wide


NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE     SELECTOR
service/details       ClusterIP   <none>        9080/TCP   4m21s   app=details
service/kubernetes    ClusterIP        <none>        443/TCP    75m     <none>
service/productpage   ClusterIP     <none>        9080/TCP   4m17s   app=productpage
service/ratings       ClusterIP    <none>        9080/TCP   4m20s   app=ratings
service/reviews       ClusterIP     <none>        9080/TCP   4m19s   app=reviews

NAME                                   READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS    IMAGES                                         SELECTOR
deployment.extensions/details-v1       1/1     1            1           4m21s   details       istio/examples-bookinfo-details-v1:1.8.0       app=details,version=v1
deployment.extensions/productpage-v1   1/1     1            1           4m16s   productpage   istio/examples-bookinfo-productpage-v1:1.8.0   app=productpage,version=v1
deployment.extensions/ratings-v1       1/1     1            1           4m20s   ratings       istio/examples-bookinfo-ratings-v1:1.8.0       app=ratings,version=v1
deployment.extensions/reviews-v1       1/1     1            1           4m19s   reviews       istio/examples-bookinfo-reviews-v1:1.8.0       app=reviews,version=v1
deployment.extensions/reviews-v2       1/1     1            1           4m18s   reviews       istio/examples-bookinfo-reviews-v2:1.8.0       app=reviews,version=v2
deployment.extensions/reviews-v3       1/1     1            1           4m18s   reviews       istio/examples-bookinfo-reviews-v3:1.8.0       app=reviews,version=v3

NAME                                      READY   STATUS    RESTARTS   AGE     IP            NODE                             NOMINATED NODE   READINESS GATES
pod/details-v1-68c7c8666d-pvrx6           2/2     Running   0          4m21s   pruzicka-k8s-istio-workshop-node03   <none>           <none>
pod/elasticsearch-operator-sysctl-297j8   1/1     Running   0          45m    pruzicka-k8s-istio-workshop-node02   <none>           <none>
pod/elasticsearch-operator-sysctl-bg8rn   1/1     Running   0          45m   pruzicka-k8s-istio-workshop-node03   <none>           <none>
pod/elasticsearch-operator-sysctl-vwvbl   1/1     Running   0          45m    pruzicka-k8s-istio-workshop-node01   <none>           <none>
pod/productpage-v1-54d799c966-2b4ss       2/2     Running   0          4m16s   pruzicka-k8s-istio-workshop-node03   <none>           <none>
pod/ratings-v1-8558d4458d-ln99n           2/2     Running   0          4m20s   pruzicka-k8s-istio-workshop-node03   <none>           <none>
pod/reviews-v1-cb8655c75-hpqfg            2/2     Running   0          4m19s   pruzicka-k8s-istio-workshop-node03   <none>           <none>
pod/reviews-v2-7fc9bb6dcf-snshx           2/2     Running   0          4m18s   pruzicka-k8s-istio-workshop-node02   <none>           <none>
pod/reviews-v3-c995979bc-wcql9            2/2     Running   0          4m18s   pruzicka-k8s-istio-workshop-node01   <none>           <none>

Check the container details - you should see also container istio-proxy next to productpage.

kubectl describe pod -l app=productpage


    Container ID:   docker://09597863ee7cdde548ddc1fe1990eed0fea4c28ca7d7a0aedc58af6918edafd6
    Image:          istio/examples-bookinfo-productpage-v1:1.8.0
    Container ID:  docker://7c411ca50317c307ac326e3dd27a598ff4fd00e53206f15acd8debf5e7b319d8
    Image:         docker.io/istio/proxyv2:1.0.5

The kubectl logs command will show you the output of the envoy proxy:

kubectl logs $(kubectl get pod -l app=productpage -o jsonpath="{.items[0].metadata.name}") istio-proxy


2019-02-21T08:23:21.009428Z     info    Version root@6f6ea1061f2b-docker.io/istio-1.0.5-c1707e45e71c75d74bf3a5dec8c7086f32f32fad-Clean
2019-02-21T08:23:21.009468Z     info    Proxy role: model.Proxy{ClusterID:"", Type:"sidecar", IPAddress:"", ID:"productpage-v1-54d799c966-vbm6k.default", Domain:"default.svc.cluster.local", Metadata:map[string]string(nil)}
2019-02-21T08:23:21.009751Z     info    Effective config: binaryPath: /usr/local/bin/envoy
configPath: /etc/istio/proxy
connectTimeout: 10s
discoveryAddress: istio-pilot.istio-system:15007
discoveryRefreshDelay: 1s
drainDuration: 45s
parentShutdownDuration: 60s
proxyAdminPort: 15000
serviceCluster: productpage
zipkinAddress: zipkin.istio-system:9411

Define the Istio gateway (opens new window) for the application:

cat samples/bookinfo/networking/bookinfo-gateway.yaml
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
sleep 5


apiVersion: networking.istio.io/v1alpha3
kind: Gateway
  name: bookinfo-gateway
    istio: ingressgateway # use istio default controller
  - port:
      number: 80
      name: http
      protocol: HTTP
    - "*"
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
  name: bookinfo
  - "*"
  - bookinfo-gateway
  - match:
    - uri:
        exact: /productpage
    - uri:
        exact: /login
    - uri:
        exact: /logout
    - uri:
        prefix: /api/v1/products
    - destination:
        host: productpage
          number: 9080

Confirm the gateway and virtualsevice has been created:

kubectl get gateway,virtualservice


NAME                                           AGE
gateway.networking.istio.io/bookinfo-gateway   11s

NAME                                          AGE
virtualservice.networking.istio.io/bookinfo   12s

Determining the ingress IP and ports when using a node port:

export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath="{.spec.ports[?(@.name==\"http2\")].nodePort}")
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath="{.spec.ports[?(@.name==\"https\")].nodePort}")
export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o "jsonpath={.items[0].status.hostIP}")
if test -f ../../terraform.tfstate && grep -q vms_public_ip ../../terraform.tfstate; then
  export INGRESS_HOST=$(terraform output -json -state=../../terraform.tfstate | jq -r ".vms_public_ip.value[0]")


31380 | 31390 | | |

Point your browser to http://$GATEWAY_URL/productpage (take the full URL from the output of the commands above).

Confirm the app is running:

curl -o /dev/null -s -w "%{http_code}\n" -A "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5" http://${GATEWAY_URL}/productpage



Create default destination rules (opens new window) (subsets) for the Bookinfo services:

kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

Display the destination rules:

kubectl get destinationrules -o yaml


- apiVersion: networking.istio.io/v1alpha3
  kind: DestinationRule
    name: reviews
    namespace: default
    host: reviews
    - labels:
        version: v1
      name: v1
    - labels:
        version: v2
      name: v2
    - labels:
        version: v3
      name: v3

Generate some traffic for next 5 minutes to gather some data:

siege --log=/tmp/siege --concurrent=1 -q --internet --time=5M $GATEWAY_URL/productpage &

Open the browser with these pages:

Open the Bookinfo site in your browser http://$GATEWAY_URL/productpage and refresh the page several times - you should see different versions of reviews shown in productpage, presented in a round robin style (red stars, black stars, no stars), since we haven’t yet used Istio to control the version routing.

Bookinfo v1, v3, v2

Check the flows in Kiali (opens new window) graph:

Istio Graph