# `Istio` Example: `Bookinfo` Application Installation ###### tags: `ITRI`, `istio`, `example` *** ## Reference - Official Website: ISTIO/DOCS/EXAMPLES/BOOKINFO APPLICATION: [Bookinfo Application](https://istio.io/docs/examples/bookinfo/) - Chinese Version: [Bookinfo 应用](https://istio.io/zh/docs/examples/bookinfo/) - Blog of 青蛙小白: [Istio 1.0学习笔记(二):部署官方示例Bookinfo](https://blog.frognew.com/2018/08/learning-istio-1.0-2.html) *** ## *Bookinfo* Architecture ![Bookinfo Application without Istio](https://istio.io/docs/examples/bookinfo/noistio.svg) Four separate microservices in `Bookinfo`: - `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. (提供圖書評論功能,可以調用 `rating` 給圖書星星) - After following the steps below, 我們可以看到: ```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 ``` - `ratings` The `ratings` microservice contains book ranking information that accompanies a book review. (提供圖書給星星功能) - There are 3 versions of the reviews microservice: |Version|GUI| |-|-| |v1|<li>Version v1 doesn’t call the `ratings` service.</li> ![](https://i.imgur.com/PNhiDXp.png)| |v2|<li>Version v2 calls the `ratings` service, and displays each rating as 1 to 5 ++black++ stars.</li> ![](https://i.imgur.com/APSJl4R.png)| |v3|<li>Version v3 calls the `ratings` service, and displays each rating as 1 to 5 ++red++ stars.</li> ![](https://i.imgur.com/lOKghEK.png)| Notice that: - this application is polyglot (多語言的) - these services have no dependencies on *Istio* 仍不失它是一個有趣的 service mesh 示例。 *** ## Deploying the application 官方的 example 並不需要我們再去修改 application。 We only simply need to configure and run the services in an *Istio-enabled* environment, with *Envoy sidecars* injected along side each service. ![Bookinfo Application](https://istio.io/docs/examples/bookinfo/withistio.svg) 所有的微服务之间的调用都是通过 Envoy sidecar,即图中小黑色长方形,微服务的 sidecar 组成了服务网格 Service Mesh。 ### Running on Kubernetes #### Create namespace `istio-example` for *Bookinfo* Check if `istio-sidecar-injector` is running. ```bash # kubectl get pod -n istio-system | grep injector istio-sidecar-injector-fc58d99f-vck25 1/1 Running 0 4h7m ``` - `istio-sidecar-injector` 可以自动将 *Envoy* 容器作为 sidecar 注入到我们的业务应用 Pod 中,只要业务应用 Pod 所在的 namespace 包含 `istio-injection=enabled` 的 Label。 In this note, we create a namespace `istio-example` for *Bookinfo* application. ```bash # kubectl create namespace istio-example ``` Default *Istio* installation uses automatic sidecar injection. Label the namespace: ```bash # kubectl label namespace istio-example istio-injection=enabled ``` #### Run the *Bookinfo* application *Bookinfo* application was defined in `samples/bookinfo/platform/kube/bookinfo.yaml`. ```yaml= # Copyright 2017 Istio Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ################################################################################################## # Details service ################################################################################################## apiVersion: v1 kind: Service metadata: name: details labels: app: details service: details spec: ports: - port: 9080 name: http selector: app: details --- apiVersion: v1 kind: ServiceAccount metadata: name: bookinfo-details --- apiVersion: apps/v1 kind: Deployment metadata: name: details-v1 labels: app: details version: v1 spec: replicas: 1 selector: matchLabels: app: details version: v1 template: metadata: labels: app: details version: v1 spec: serviceAccountName: bookinfo-details containers: - name: details image: docker.io/istio/examples-bookinfo-details-v1:1.15.0 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 --- ################################################################################################## # Ratings service ################################################################################################## apiVersion: v1 kind: Service metadata: name: ratings labels: app: ratings service: ratings spec: ports: - port: 9080 name: http selector: app: ratings --- apiVersion: v1 kind: ServiceAccount metadata: name: bookinfo-ratings --- apiVersion: apps/v1 kind: Deployment metadata: name: ratings-v1 labels: app: ratings version: v1 spec: replicas: 1 selector: matchLabels: app: ratings version: v1 template: metadata: labels: app: ratings version: v1 spec: serviceAccountName: bookinfo-ratings containers: - name: ratings image: docker.io/istio/examples-bookinfo-ratings-v1:1.15.0 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 --- ################################################################################################## # Reviews service ################################################################################################## apiVersion: v1 kind: Service metadata: name: reviews labels: app: reviews service: reviews spec: ports: - port: 9080 name: http selector: app: reviews --- apiVersion: v1 kind: ServiceAccount metadata: name: bookinfo-reviews --- apiVersion: apps/v1 kind: Deployment metadata: name: reviews-v1 labels: app: reviews version: v1 spec: replicas: 1 selector: matchLabels: app: reviews version: v1 template: metadata: labels: app: reviews version: v1 spec: serviceAccountName: bookinfo-reviews containers: - name: reviews image: docker.io/istio/examples-bookinfo-reviews-v1:1.15.0 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 --- apiVersion: apps/v1 kind: Deployment metadata: name: reviews-v2 labels: app: reviews version: v2 spec: replicas: 1 selector: matchLabels: app: reviews version: v2 template: metadata: labels: app: reviews version: v2 spec: serviceAccountName: bookinfo-reviews containers: - name: reviews image: docker.io/istio/examples-bookinfo-reviews-v2:1.15.0 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 --- apiVersion: apps/v1 kind: Deployment metadata: name: reviews-v3 labels: app: reviews version: v3 spec: replicas: 1 selector: matchLabels: app: reviews version: v3 template: metadata: labels: app: reviews version: v3 spec: serviceAccountName: bookinfo-reviews containers: - name: reviews image: docker.io/istio/examples-bookinfo-reviews-v3:1.15.0 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 --- ################################################################################################## # Productpage services ################################################################################################## apiVersion: v1 kind: Service metadata: name: productpage labels: app: productpage service: productpage spec: ports: - port: 9080 name: http selector: app: productpage --- apiVersion: v1 kind: ServiceAccount metadata: name: bookinfo-productpage --- apiVersion: apps/v1 kind: Deployment metadata: name: productpage-v1 labels: app: productpage version: v1 spec: replicas: 1 selector: matchLabels: app: productpage version: v1 template: metadata: labels: app: productpage version: v1 spec: serviceAccountName: bookinfo-productpage containers: - name: productpage image: docker.io/istio/examples-bookinfo-productpage-v1:1.15.0 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 --- ``` Deploy the application: ```bash # cd istio-<version> # kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n istio-example ``` ### Confirm all services, pods & application If thay are correctly defined and running: ```bash # kubectl get services -n istio-example NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE details ClusterIP 10.233.55.254 <none> 9080/TCP 4h8m productpage ClusterIP 10.233.17.112 <none> 9080/TCP 4h8m ratings ClusterIP 10.233.28.165 <none> 9080/TCP 4h8m reviews ClusterIP 10.233.12.187 <none> 9080/TCP 4h8m # kubectl get pods -n istio-example NAME READY STATUS RESTARTS AGE details-v1-6978996b-blfrn 2/2 Running 0 4h9m productpage-v1-7658b8dcc6-9bbc5 2/2 Running 0 4h9m ratings-v1-84975bc778-zspbs 2/2 Running 0 4h9m reviews-v1-5787f7b87-5g6k4 2/2 Running 0 4h9m reviews-v2-6d8b975647-t9t2m 2/2 Running 0 4h9m reviews-v3-7d5549f9-sphc8 2/2 Running 0 4h9m ``` Send a request to it by a `curl` command from `ratings` for checking *BookInfo* is running: ```bash # kubectl exec -it -n istio-example $(kubectl get pod -n istio-example -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>" <title>Simple Bookstore App</title> ``` ## Istio Gateway: Determining the ingress IP and port Now that the `Bookinfo` services are up and running, you need to make the application accessible from outside of your Kubernetes cluster, e.g., from a browser. An ==Istio Gateway== is used for this purpose. 1. Define the ingress gateway for the application: ```bash # kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -n istio-example ``` 2. Confirm the gateway has been created: ```bash # kubectl get gateway -n istio-example NAME AGE bookinfo-gateway 4h ``` 3. Set the `INGRESS_HOST` and `INGRESS_PORT` variables for accessing the gateway. Check if our Kubernetes cluster is running in an environment that supports external load balancers: ```bash # kubectl get svc istio-ingressgateway -n istio-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingressgateway LoadBalancer 10.233.12.169 <pending> 15020:32165/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:31238/TCP,15030:31865/TCP,15031:30552/TCP,15032:31756/TCP,15443:30065/TCP 4h38m ``` - If the `EXTERNAL-IP` value is set, our environment has an external load balancer that you can use for the ingress gateway. - If the `EXTERNAL-IP` value is `<none>` (or perpetually `<pending>`), our environment does not provide an external load balancer for the ingress gateway. - In this case, you can access the gateway using the service’s node port. Set the ingress ports: ```bash 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}') ``` Setting the ingress IP depends on the cluster provider: ```bash export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}') ``` 4. Set `GATEWAY_URL`: ```bash # export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT ``` ### Confirm the app is accessible from outside the cluster Check from the CLI. ```bash # curl -s http://${GATEWAY_URL}/productpage | grep -o "<title>.*</title>" <title>Simple Bookstore App</title> ``` Open browser to `http://$GATEWAY_URL/productpage` to view the Bookinfo web page. ![](https://i.imgur.com/WPBUKlO.png) If you 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++. *** ## 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, apply `samples/bookinfo/networking/destination-rule-all.yaml`. ```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 ``` *** ## Clean Up Appication Remove the application virtual services. ```bash # kubectl delete -f samples/bookinfo/networking/virtual-service-all-v1.yaml -n istio-example ``` ## Uninstall from Kubernetes environment 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> *** ***