部署Bookinfo示例程序詳細過程和步驟(基於Kubernetes集群+Istio v1.0)
部署Bookinfo示例程序
在下載的Istio安裝包的samples目錄中包含了示例應用程序。
Bookinfo應用
部署一個樣例應用,它由四個單獨的微服務構成,用來演示多種 Istio 特性。這個應用模仿在線書店的一個分類,顯示一本書的信息。頁面上會顯示一本書的描述,書籍的細節(ISBN、頁數等),以及關於這本書的一些評論。
Bookinfo 應用分為四個單獨的微服務:
-
productpage :productpage 微服務會調用 details 和 reviews 兩個微服務,用來生成頁面。
-
details :這個微服務包含了書籍的信息。
-
reviews :這個微服務包含了書籍相關的評論。它還會調用 ratings 微服務。
-
ratings :ratings 微服務中包含了由書籍評價組成的評級信息。
reviews 微服務有 3 個版本:
-
v1 版本不會調用 ratings 服務。
-
v2 版本會調用 ratings 服務,並使用 1 到 5 個黑色星形圖標來顯示評分信息。
-
v3 版本會調用 ratings 服務,並使用 1 到 5 個紅色星形圖標來顯示評分信息。
下圖展示了這個應用的端到端架構。

Bookinfo 是一個異構應用,幾個微服務是由不同的語言編寫的。這些服務對 Istio 並無依賴,但是構成了一個有代表性的服務網格的例子:它由多個服務、多個語言構成,並且 reviews 服務具有多個版本。
要在 Istio 中運行這一應用,無需對應用自身做出任何改變。我們只要簡單的在 Istio 環境中對服務進行配置和運行,具體一點說就是把 Envoy sidecar 注入到每個服務之中。這個過程所需的具體命令和配置方法由運行時環境決定,而部署結果較為一致,如下圖所示:

所有的微服務都和 Envoy sidecar 集成在一起,被集成服務所有的出入流量都被 sidecar 所劫持,這樣就為外部控制准備了所需的 Hook,然后就可以利用 Istio 控制平面為應用提供服務路由、遙測數據收集以及策略實施等功能。
接下來可以根據 Istio 的運行環境,按照下面的講解完成應用的部署。
先驗證kubernetes 集群是否啟用了 自動Sidecar 注入。
Sidecar 的自動注入
使用 Kubernetes 的 mutating webhook admission controller,可以進行 Sidecar 的自動注入。Kubernetes 1.9 以后的版本才具備這一能力。使用這一功能之前首先要檢查 kube-apiserver 的進程,是否具備 admission-control 參數,並且這個參數的值中需要包含 MutatingAdmissionWebhook 以及 ValidatingAdmissionWebhook 兩項,並且按照正確的順序加載,這樣才能啟用 admissionregistration API:
[root@centos-110 ~]# kubectl api-versions | grep admissionregistration
admissionregistration.k8s.io/v1beta1
ps -ef | grep apiserver

確認kubernetes 集群已啟用了自動Sidecar 注入。
部署bookinfo 服務
創建 book 命名空間(可選),也可以直接使用默認的 default 命名空間。
kubectl create ns book
給 book 命名空間設置標簽:istio-injection=enabled:
$ kubectl label namespace book istio-injection=enabled
$ kubectl get namespace -L istio-injection
[root@centos-110 ~]# kubectl get ns -L istio-injection
NAME STATUS AGE ISTIO-INJECTION
book Active 1d enabled
default Active 27d
istio-system Active 8d disabled
kube-public Active 27d
kube-system Active 27d
weave Active 21d
如果集群使用的是自動 Sidecar 注入,只需簡單的 kubectl 就能完成服務的部署。
[root@centos-110 istio-1.0.0]# kubectl apply -n book -f samples/bookinfo/platform/kube/bookinfo.yaml
service "details" created
deployment.extensions "details-v1" created
service "ratings" created
deployment.extensions "ratings-v1" created
service "reviews" created
deployment.extensions "reviews-v1" created
deployment.extensions "reviews-v2" created
deployment.extensions "reviews-v3" created
service "productpage" created
deployment.extensions "productpage-v1" created
上面的命令會啟動全部的四個服務,其中也包括了 reviews 服務的三個版本(v1、v2 以及 v3)。
如果服務部署有問題,可以使用如下命令刪除已經部署的服務。
kubectl delete -f samples/bookinfo/platform/kube/bookinfo.yaml -n book
確認所有的服務和Pods 都正常運行:
[root@centos-110 istio-1.0.0]# kubectl get svc -n book
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.103.243.183 <none> 9080/TCP 9s
productpage ClusterIP 10.111.96.136 <none> 9080/TCP 7s
ratings ClusterIP 10.111.136.187 <none> 9080/TCP 9s
reviews ClusterIP 10.97.99.117 <none> 9080/TCP 8s
[root@centos-110 istio-1.0.0]# kubectl get pods -n book -o wide
NAME READY STATUS RESTARTS AGE IP NODE
details-v1-6865b9b99d-4rpfs 2/2 Running 0 12m 10.244.2.140 centos-112
productpage-v1-f8c8fb8-9zlmb 2/2 Running 0 12m 10.244.2.150 centos-112
ratings-v1-77f657f55d-mvx9g 2/2 Running 0 12m 10.244.2.135 centos-112
reviews-v1-6b7f6db5c5-8jfq7 2/2 Running 0 12m 10.244.2.142 centos-112
reviews-v2-7ff5966b99-pfhz8 2/2 Running 0 12m 10.244.2.146 centos-112
reviews-v3-5df889bcff-vhk49 2/2 Running 0 12m 10.244.1.147 centos-111
驗證Pod是否會自動注入Sidecar
kubectl describe pod productpage-v1-f8c8fb8-8dnjm -n book
被注入Sidecar的Pod 會有2個容器,多出了一個 istio-proxy 容器及其對應的存儲卷。

或者通過如下命令查看pod 中是否有istio-proxy 容器:
[root@centos-110 ~]# kubectl get pod productpage-v1-f8c8fb8-8dnjm -o jsonpath='{.spec.containers[*].name}' -n book
productpage istio-proxy
輸出結果顯示pod 中有2個容器,分別為 productpage 和 istio-proxy。
可以禁用 book 命名空間的自動注入功能,然后檢查新建 Pod 是不是就不帶有 Sidecar 容器了。
確定入口IP和端口
執行以下命令以確定您的 Kubernetes 集群是否在支持外部負載均衡器的環境中運行。
[root@centos-110 ~]# kubectl get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway NodePort 10.106.84.2 <none> 80:31380/TCP,443:31390/TCP,31400:31400/TCP,15011:32329/TCP,8060:32167/TCP,15030:31095/TCP,15031:30203/TCP 8d
如果 EXTERNAL-IP 設置了該值,則要求您的環境具有可用於 Ingress 網關的外部負載均衡器。如果 EXTERNAL-IP 值是 <none>(或一直是 <pending> ),則說明可能您的環境不支持為 ingress 網關提供外部負載均衡器的功能。在這種情況下,您可以使用 Service 的 node port 方式訪問網關。
使用 kubectl patch 更新 istio-ingressgateway 服務網關類型
由於在我的kubernetes 集群環境中,不支持外部負載均衡器。因此,使用 node port 方式訪問網關。
[root@centos-110 istio-1.0.0]# kubectl patch service istio-ingressgateway -n istio-system -p '{"spec":{"type":"NodePort"}}'
service "istio-ingressgateway" patched
給 Bookinfo 應用定義 ingress gateway
現在 Bookinfo 服務都已正常運行中,我們需要讓kubernetes集群外部可以訪問應用,如通過瀏覽器訪問。Istio gateway 可以實現這一目的。
kubectl apply -n book -f samples/bookinfo/networking/bookinfo-gateway.yaml
輸出結果:
gateway.networking.istio.io "bookinfo-gateway" created
virtualservice.networking.istio.io "bookinfo" created
確認gateway創建成功:
kubectl get gateway -n book
NAME AGE
bookinfo-gateway 15h
也可以通過 istioctl 命令,驗證 gateway和virtualservice 創建成功,具體命令如下所示:

前面,我們通過NodePort 方式來暴露istio-ingressgateway 服務,現在根據如下命令來獲取 ingress ports:
$ 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}')
獲取 ingress IP 地址:
$ export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o 'jsonpath={.items[0].status.hostIP}')
通過瀏覽器訪問 ingress 服務
接下來就可以在瀏覽器的 URL 中使用 $INGRESS_HOST:$INGRESS_PORT(也就是 192.168.56.110:31380)進行訪問,輸入 http://192.168.56.110:31380/productpage 網址之后,顯示信息如下:

如果刷新幾次應用的頁面,就會看到頁面中會隨機展示 reviews 服務的不同版本的效果(紅色、黑色的星形或者沒有顯示)。reviews 服務出現這種情況是因為我們還沒有使用 Istio 來控制版本的路由。
理解原理
Gateway 配置資源允許外部流量進入 Istio 服務網格,並使 Istio 的流量管理和策略功能可用於邊緣服務。
在前面的步驟中,我們在 Istio 服務網格中創建了一個服務,並展示了如何將服務的 HTTP 端點暴露給外部流量。
=================================================
清理 Bookinfo 示例應用
結束對 Bookinfo 示例應用的體驗之后,就可以使用下面的命令來完成應用的刪除和清理了。
在 Kubernetes 環境中完成刪除
1. 刪除路由規則,並終結應用的 Pod
$ samples/bookinfo/platform/kube/cleanup.sh
* 確認應用已經關停 - 如果前面創建了namespace - book,則下面的命令也需要添加 -n book 參數。
$ istioctl get gateway #-- 此處應該已經沒有 Gateway
$ istioctl get virtualservices #-- 此處應該已經沒有 VirtualService
$ kubectl get pods #-- Bookinfo 的所有 Pod 應該都已經被刪除
卸載 istio
使用kubectl 卸載 istio
kubectl delete -f install/kubernetes/istio-demo.yaml
手動清除額外的job 資源
kubectl -n istio-system delete job --all
刪除CRD
kubectl delete -f install/kubernetes/helm/istio/templates/crds.yaml -n istio-system
參考鏈接:
注入 Istio sidecar
Install with helm
控制 Ingress 流量
Bookinfo 應用
Istio及Bookinfo示例程序安裝試用筆記