做者 宋淨超 | 5400字 | 閱讀大約須要11分鐘 | 歸檔於istio | 發表於 2018-05-22html
標籤 #Istio #教程,來自 https://servicemesher.github.io/blog/istio-service-mesh-tutorial/java
本文是 Istio 管理 Java 微服務的案例教程,使用的全部工具和軟件所有基於開源方案,替換了 redhat-developer-demos/istio-tutorial 中的 minishift 環境,使用 kubernetes-vagrant-centos-cluster 替代,沿用了原有的微服務示例,使用 Zipkin 作分佈式追蹤而不是 Jaeger。git
本文中的代碼和 YAML 文件見 https://github.com/rootsongjc/istio-tutorial。github
原文地址:https://jimmysong.io/posts/istio-tutorial/spring
在進行本教程前須要先準備如下工具和環境。docker
請參考 kubernetes-vagrant-centos-cluster 在本地啓動擁有三個節點的 kubernetes 集羣。json
git clone https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster.git cd kubernetes-vagrant-centos-cluster vagrant up
在 kubernetes-vagrant-centos-cluster 中的包含 Istio 0.7.1 的安裝 YAML 文件,運行下面的命令安裝 Istio。centos
kubectl apply -f addon/istio/
運行示例api
kubectl apply -n default -f <(istioctl kube-inject -f yaml/istio-bookinfo/bookinfo.yaml)
在您本身的本地主機的/etc/hosts
文件中增長以下配置項。瀏覽器
172.17.8.102 grafana.istio.jimmysong.io 172.17.8.102 servicegraph.istio.jimmysong.io 172.17.8.102 zipkin.istio.jimmysong.io
咱們能夠經過下面的URL地址訪問以上的服務。
Service | URL |
---|---|
grafana | http://grafana.istio.jimmysong.io |
servicegraph | http://servicegraph.istio.jimmysong.io/dotviz,http://servicegraph.istio.jimmysong.io/graph |
zipkin | http://zipkin.istio.jimmysong.io |
詳細信息請參閱 https://istio.io/docs/guides/bookinfo.html
在打包成鏡像部署到 kubernetes 集羣上運行以前,咱們先在本地運行全部示例。
本教程中三個服務之間的依賴關係以下:
customer → preference → recommendation
customer
和 preference
微服務是基於 Spring Boot 構建的,recommendation
微服務是基於 vert.x 構建的。
customer
和 preference
微服務的 pom.xml
文件中都引入了 OpenTracing 和 Jeager 的依賴。
<dependency> <groupId>io.opentracing.contrib</groupId> <artifactId>opentracing-spring-cloud-starter</artifactId> <version>0.1.7</version> </dependency> <dependency> <groupId>com.uber.jaeger</groupId> <artifactId>jaeger-tracerresolver</artifactId> <version>0.25.0</version> </dependency>
咱們首先在本地肯定全部的微服務均可以正常運行,而後再打包鏡像在 kubernetes 集羣上運行。
啓動 Jaeger
使用 docker 來運行 jagger。
docker run -d \ --rm \ -p5775:5775/udp \ -p6831:6831/udp \ -p6832:6832/udp \ -p16686:16686 \ -p14268:14268 \ jaegertracing/all-in-one:1.3
Jaeger UI 地址 http://localhost:16686
Customer
cd customer/java/springboot JAEGER_SERVICE_NAME=customer mvn \ spring-boot:run \ -Drun.arguments="--spring.config.location=src/main/resources/application-local.properties"
服務訪問地址: http://localhost:8280
Preference
cd preference/java/springboot JAEGER_SERVICE_NAME=preference mvn \ spring-boot:run \ -Drun.arguments="--spring.config.location=src/main/resources/application-local.properties"
服務訪問地址:http://localhost:8180
Recommendation
cd recommendation/java/vertx mvn vertx:run
服務訪問地址:http://localhost:8080
全部服務都啓動以後,此時訪問 http://localhost:8280 將會看到以下輸出。
customer => preference => recommendation v1 from 'unknown': 1
每訪問一次最後的數字就會加 1。
Jaeger
此時訪問 http://localhost:16686 將看到 Jaeger query UI,全部應用將 metrics 發送到 Jeager 中。
能夠在 Jaeger UI 中搜索 customer
和 preference
service 的 trace 並查看每次請求的 tracing。
在本地運行測試無誤以後就能夠構建鏡像了。本教程中的容器鏡像都是在 fabric8/java-jboss-openjdk8-jdk 的基礎上構建的。只要將 Java 應用構建出 Jar 包而後放到 /deployments
目錄下基礎鏡像就能夠自動幫咱們運行,因此咱們看到着幾個應用的 Dockerfile
文件中都沒有執行入口,真正的執行入口是 run-java.sh。
Customer
構建 Customer 鏡像。
cd customer/java/springboot mvn clean package docker build -t jimmysong/istio-tutorial-customer:v1 . docker push jimmysong/istio-tutorial-customer:v1
第一次構建和上傳須要花費一點時間,下一次構建就會很快。
Preference
構建 Preference 鏡像。
cd preference/java/springboot mvn clean package docker build -t jimmysong/istio-tutorial-preference:v1 . docker push jimmysong/istio-tutorial-preference:v1
Recommendation
構建 Recommendation 鏡像。
cd recommendation/java/vertx mvn clean package docker build -t jimmysong/istio-tutorial-recommendation:v1 . docker push jimmysong/istio-tutorial-recommendation:v1
如今三個 docker 鏡像都構建完成了,咱們檢查一下。
$ docker images | grep istio-tutorial REPOSITORY TAG IMAGE ID CREATED SIZE jimmysong/istio-tutorial-recommendation v1 d31dd858c300 51 seconds ago 443MB jimmysong/istio-tutorial-preference v1 e5f0be361477 6 minutes ago 459MB jimmysong/istio-tutorial-customer v1 d9601692673e 13 minutes ago 459MB
使用下面的命令將以上服務部署到 kubernetes。
# create new namespace kubectl create ns istio-tutorial # deploy recommendation kubectl apply -f <(istioctl kube-inject -f recommendation/kubernetes/Deployment.yml) -n istio-tutorial kubectl apply -f recommendation/kubernetes/Service.yml # deploy preferrence kubectl apply -f <(istioctl kube-inject -f preference/kubernetes/Deployment.yml) -n istio-tutorial kubectl apply -f preference/kubernetes/Service.yml # deploy customer kubectl apply -f <(istioctl kube-inject -f customer/kubernetes/Deployment.yml) -n istio-tutorial kubectl apply -f customer/kubernetes/Service.yml
注意:preference
和 customer
應用啓動速度比較慢,咱們將 livenessProb 配置中的 initialDelaySeconds
設置爲 20 秒。
查看 Pod 啓動狀態:
kubectl get pod -w -n istio-tutorial
爲了在 kubernetes 集羣外部訪問 customer 服務,咱們須要增長 ingress 配置。
kubectl apply -f ingress/ingress.yaml
修改本地的 /etc/hosts
文件,增長一條配置。
172.17.8.102 customer.istio-tutorial.jimmysong.io
如今訪問 http://customer.istio-tutorial.jimmysong.io 將看到以下輸出:
customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 1
批量訪問該地址。
./bin/poll_customer.sh
訪問 http://servicegraph.istio.jimmysong.io/dotviz 查看服務的分佈式追蹤和依賴關係。
訪問 http://servicegraph.istio.jimmysong.io/dotviz 查看服務間的關係圖和 QPS。
訪問 http://grafana.istio.jimmysong.io 查看 Service Mesh 的監控信息。
爲了試用 Istio 中的各類功能,咱們須要爲應用構建多個版本,咱們爲 recommendation 構建 v2 版本的鏡像,看看如何使用 Istio 控制微服務的流量。
咱們將構建新版的 recommendation
服務的鏡像,並觀察 customer
對不一樣版本的 recommendataion
服務的訪問頻率。
修改 recommendation/java/vertx/src/main/java/com/redhat/developer/demos/recommendation/RecommendationVerticle.java
程序中代碼。
將 private static final String RESPONSE_STRING_FORMAT = "recommendation v1 from '%s': %d\n";
修改成 private static final String RESPONSE_STRING_FORMAT = "recommendation v2 from '%s': %d\n";
並構建 recommendation:v2
鏡像。
cd recommendation/java/vertx mvn clean package docker build -t jimmysong/istio-tutorial-recommendation:v2 . docker push jimmysong/istio-tutorial-recommendation:v2
將應用部署到 kubernetes。
# deploy recommendation kubectl apply -f <(istioctl kube-inject -f recommendation/kubernetes/Deployment-v2.yml) -n istio-tutorial
如今再訪問 customer
服務,將看到以下輸出:
$ bin/poll_customer.sh customer => preference => recommendation v2 from '77b9f6cc68-5xs27': 1 customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 3581 customer => preference => recommendation v2 from '77b9f6cc68-5xs27': 2 customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 3582 customer => preference => recommendation v2 from '77b9f6cc68-5xs27': 3 customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 3583 customer => preference => recommendation v2 from '77b9f6cc68-5xs27': 4
咱們能夠看到 v1 和 v2 版本的 recommendation
服務會被間隔訪問到。
咱們再將 v2 版本的 recommendation
實例數設置成 2 個。
kubectl scale --replicas=2 deployment/recommendation-v2 -n istio-tutorial kubectl get pod -w -n istio-tutorial
觀察 recommendation-v2
Pod 達到兩個以後再訪問 customer
服務。
$ bin/poll_customer.sh customer => preference => recommendation v2 from '77b9f6cc68-j9fgj': 1 customer => preference => recommendation v2 from '77b9f6cc68-5xs27': 71 customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 3651 customer => preference => recommendation v2 from '77b9f6cc68-j9fgj': 2 customer => preference => recommendation v2 from '77b9f6cc68-5xs27': 72 customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 3652 customer => preference => recommendation v2 from '77b9f6cc68-j9fgj': 3 customer => preference => recommendation v2 from '77b9f6cc68-5xs27': 73 customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 3653
觀察輸出中 v1 和 v2 版本 recommendation
的訪問頻率。
將 recommendataion
服務的實例數恢復爲 1。
kubectl scale --replicas=1 deployment/recommendation-v2
如下全部路有規則都是針對 recommendation
服務,並在 repo 的根目錄下執行。
將全部流量打給 v2
下面將演示如何動態的劃分不一樣版本服務間的流量,將全部的流量都打到 recommendation:v2
。
istioctl create -f istiofiles/route-rule-recommendation-v2.yml -n istio-tutorial
如今再訪問 customer
服務將看到全部的流量都會打到 recommendation:v2
。
刪除 RouteRules 後再訪問 customer
服務將看到又恢復了 v1 和 v2 版本的 recommendation
服務的間隔訪問。
istioctl delete routerule recommendation-default
切分流量
將 90% 的流量給 v1,10% 的流量給 v2。
istioctl create -f istiofiles/route-rule-recommendation-v1_and_v2.yml -n istio-tutorial
執行bin/poll_customer.sh
觀察訪問狀況。
要想動態切分流量只要修改 RouteRules 中的 weight
配置便可。
apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: name: recommendation-v1-v2 spec: destination: namespace: istio-tutorial name: recommendation precedence: 5 route: - labels: version: v1 weight: 90 - labels: version: v2 weight: 10
由於 RouteRule 有優先級,爲了繼續後面的實驗,在驗證完成後刪除該 RouteRule。
istioctl delete routerule recommendation-v1-v2 -n istio-tutorial
有時候咱們爲了加強系統的健壯性,須要對系統作混沌工程,故意注入故障,並保障服務能夠自動處理這些故障。
注入 HTTP 503 錯誤
istioctl create -f istiofiles/route-rule-recommendation-503.yml -n istio-tutorial
有 50% 的概率報 503 錯誤。
$ bin/poll_customer.sh customer => preference => recommendation v2 from '77b9f6cc68-5xs27': 135 customer => 503 preference => 503 fault filter abort customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 3860 customer => 503 preference => 503 fault filter abort customer => 503 preference => 503 fault filter abort customer => preference => recommendation v2 from '77b9f6cc68-5xs27': 136 customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 3861 customer => 503 preference => 503 fault filter abort customer => 503 preference => 503 fault filter abort customer => preference => recommendation v2 from '77b9f6cc68-5xs27': 137 customer => 503 preference => 503 fault filter abort
清理 RouteRule。
istioctl delete routerule recommendation-503 -n istio-tutorial
增長服務的訪問延遲。
istioctl create -f istiofiles/route-rule-recommendation-delay.yml -n istio-tutorial
會有 50% 的概率訪問 recommendation
服務有 7 秒的延遲。百分比和延遲時間能夠在 RouteRule 中配置。
清理 RouteRule。
istioctl delete routerule recommendation-delay -n istio-tutorial
讓服務不是直接失敗,而是增長重試機制。
咱們下面將同時應用兩條 RouteRule,讓訪問 recommendation
服務時有 50% 的概率出現 503 錯誤,並在出現錯誤的時候嘗試訪問 v2 版本,超時時間爲 2 秒。
istioctl create -f istiofiles/route-rule-recommendation-v2_503.yml -n istio-tutorial istioctl create -f istiofiles/route-rule-recommendation-v2_retry.yml -n istio-tutorial
執行 bin/poll_customer.sh
咱們看到一開始有些 503 錯誤,而後全部的流量都流向了 v2。
清理 RouteRules。
istioctl delete routerule recommendation-v2-retry -n istio-tutorial istioctl delete routerule recommendation-v2-503 -n istio-tutorial
設置超時時間,只有服務訪問超時才認定服務訪問失敗。
取消註釋 recommendation/java/vertx/src/main/java/com/redhat/developer/demos/recommendation/RecommendationVerticle.java
中的下面一行,增長超時時間爲 3 秒。
router.get("/").handler(this::timeout);
從新生成鏡像。
cd recommendation/java/vertx mvn clean package docker build -t jimmysong/istio-tutorial-recommendation:v2 . docker push jimmysong/istio-tutorial-recommendation:v2
從新部署到 kubernetes。
kubectl delete -f recommendation/kubernetes/Deployment-v2.yml
由於咱們從新構建的鏡像使用了一樣的名字和 tag,而以前在 Deployment-v2.yml
中配置的鏡像拉取策略是 IfNotPresent
,這樣的話即便咱們構建了新的鏡像也沒法應用到集羣上,所以將鏡像拉取策略改爲 Always
確保每次啓動 Pod 的時候都會拉取鏡像。
kubectl apply -f <(istioctl kube-inject -f recommendation/kubernetes/Deployment-v2.yml) -n istio-tutorial
啓用超時 RouteRules。
istioctl create -f istiofiles/route-rule-recommendation-timeout.yml -n istio-tutorial
訪問 customer
服務將看到以下輸出:
$ bin/poll_customer.sh customer => 503 preference => 504 upstream request timeout customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 4002 customer => 503 preference => 504 upstream request timeout customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 4003 customer => 503 preference => 504 upstream request timeout customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 4004
清理 RouteRules。
istioctl delete routerule recommendation-timeout -n istio-tutorial
User-agent 是一個字符串,其中包含了瀏覽器的信息,訪問 https://www.whoishostingthis.com/tools/user-agent 獲取你的 user-agent。
個人 user-agent 是:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
將全部的流量打到 v1。
istioctl create -f istiofiles/route-rule-recommendation-v1.yml -n istio-tutorial
將使用 Safari 瀏覽器訪問的流量打到 v2。
istioctl create -f istiofiles/route-rule-safari-recommendation-v2.yml -n istio-tutorial
誰用 Safari 或者 Chrome(Chrome 瀏覽器的 user-agent 中也包含 Safari 字段)訪問 http://customer.istio-tutorial.jimmysong.io/ 在通過 3 秒鐘(咱們在前面從新編譯 v2 鏡像,設置了 3 秒超時時間)後將看到訪問 v2 的輸出。
或者使用 curl 訪問。
curl -A Safari http://customer.istio-tutorial.jimmysong.io/ curl -A Firefox http://customer.istio-tutorial.jimmysong.io/
觀察返回的結果。
將移動端用戶的流量導到 v2。
istioctl create -f istiofiles/route-rule-mobile-recommendation-v2.yml -n istio-tutorial curl -A "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4(KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5" http://customer.istio-tutorial.jimmysong.io/
觀察輸出的結果。
清理 RouteRules。
istioctl delete routerule recommendation-mobile -n istio-tutorial istioctl delete routerule recommendation-safari -n istio-tutorial istioctl delete routerule recommendation-default -n istio-tutorial
確保當前至少運行了兩個版本的 recommendation
服務,而且沒有 RouteRule。
注:可使用 istioctl get routerule
獲取 RouteRule。
設置流量鏡像,將全部 v1 的流量都被鏡像到 v2。
istioctl create -f istiofiles/route-rule-recommendation-v1-mirror-v2.yml -n istio-tutorial bin/poll_customer.sh
查看 recommendation-v2 的日誌。
kubectl logs -f `oc get pods|grep recommendation-v2|awk '{ print $1 }'` -c recommendation
Istio 能夠設置服務訪問的黑白名單,若是沒有權限的話會返回 HTTP 404 Not Found。
istioctl create -f istiofiles/acl-whitelist.yml -n istio-tutorial
此時訪問 customer
服務。
$ bin/poll_customer.sh customer => 404 NOT_FOUND:preferencewhitelist.listchecker.istio-tutorial:customer is not whitelisted
重置環境。
istioctl delete -f istiofiles/acl-whitelist.yml -n istio-tutorial
設置黑名單,全部位於黑名單中的流量將得到 403 Forbidden 返回碼。
istioctl create -f istiofiles/acl-blacklist.yml -n istio-tutorial
此時訪問 customer
服務。
$ bin/poll_customer.sh customer => 403 PERMISSION_DENIED:denycustomerhandler.denier.istio-tutorial:Not allowed
重置環境。
istioctl delete -f istiofiles/acl-blacklist.yml -n istio-tutorial
Kubernetes 中默認的負載均衡策略是 round-robin,固然咱們可使用 Istio 把它修改爲 random。
增長 v1 的實例數。
kubectl scale deployment recommendation-v1 --replicas=2 -n istio-tutorial
持續訪問 customer
服務。
bin/poll_customer.sh
保持前臺輸出,觀察流量的行爲。
應用負載均衡策略。
istioctl create -f istiofiles/recommendation_lb_policy_app.yml -n istio-tutorial
觀察一段時間流量的行爲後,重置環境。
istioctl delete -f istiofiles/recommendation_lb_policy_app.yml -n istio-tutorial kubectl scale deployment recommendation-v1 --replicas=1 -n istio-tutorial
暫時不可用
當達到最大鏈接數和最大掛起請求數時快速失敗。
將流量在 v1 和 v2 之間均分。
istioctl create -f istiofiles/route-rule-recommendation-v1_and_v2_50_50.yml -n istio-tutorial
未開啓斷路器的時候啓動負載測試。
$ siege -r 2 -c 20 -v customer.istio-tutorial.jimmysong.io New configuration template added to /Users/jimmysong/.siege Run siege -C to view the current settings in that file ** SIEGE 4.0.4 ** Preparing 20 concurrent users for battle. The server is now under siege... HTTP/1.1 200 0.10 secs: 75 bytes ==> GET / HTTP/1.1 200 0.12 secs: 75 bytes ==> GET / HTTP/1.1 200 0.13 secs: 75 bytes ==> GET / HTTP/1.1 200 0.13 secs: 75 bytes ==> GET / HTTP/1.1 200 0.13 secs: 75 bytes ==> GET / HTTP/1.1 200 0.17 secs: 75 bytes ==> GET / HTTP/1.1 200 3.12 secs: 74 bytes ==> GET / HTTP/1.1 200 3.14 secs: 75 bytes ==> GET / HTTP/1.1 200 3.15 secs: 74 bytes ==> GET / HTTP/1.1 200 3.15 secs: 74 bytes ==> GET / HTTP/1.1 200 3.17 secs: 75 bytes ==> GET / HTTP/1.1 200 3.17 secs: 75 bytes ==> GET / HTTP/1.1 200 3.20 secs: 75 bytes ==> GET / HTTP/1.1 200 3.20 secs: 74 bytes ==> GET / HTTP/1.1 200 0.05 secs: 75 bytes ==> GET / HTTP/1.1 200 0.12 secs: 75 bytes ==> GET / HTTP/1.1 200 3.15 secs: 75 bytes ==> GET / HTTP/1.1 200 3.25 secs: 75 bytes ==> GET / HTTP/1.1 200 3.26 secs: 75 bytes ==> GET / HTTP/1.1 200 3.14 secs: 75 bytes ==> GET / HTTP/1.1 200 3.58 secs: 74 bytes ==> GET / HTTP/1.1 200 6.15 secs: 74 bytes ==> GET / HTTP/1.1 200 6.16 secs: 75 bytes ==> GET / HTTP/1.1 200 3.03 secs: 74 bytes ==> GET / HTTP/1.1 200 6.06 secs: 75 bytes ==> GET / HTTP/1.1 200 6.04 secs: 75 bytes ==> GET / HTTP/1.1 200 3.11 secs: 74 bytes ==> GET / HTTP/1.1 200 3.09 secs: 75 bytes ==> GET / HTTP/1.1 200 6.15 secs: 74 bytes ==> GET / HTTP/1.1 200 6.71 secs: 74 bytes ==> GET / HTTP/1.1 200 3.52 secs: 75 bytes ==> GET / ^C Lifting the server siege... Transactions: 31 hits Availability: 100.00 % Elapsed time: 7.99 secs Data transferred: 0.00 MB Response time: 2.99 secs Transaction rate: 3.88 trans/sec Throughput: 0.00 MB/sec Concurrency: 11.60 Successful transactions: 31 Failed transactions: 0 Longest transaction: 6.71 Shortest transaction: 0.05
全部的請求都成功了,可是性能不好,由於 v2 版本設置了 3 秒的超時時間。
咱們啓用下斷路器。
istioctl create -f istiofiles/recommendation_cb_policy_version_v2.yml -n istio-tutorial
從新測試一下。
$ siege -r 2 -c 20 -v customer.istio-tutorial.jimmysong.io ** SIEGE 4.0.4 ** Preparing 20 concurrent users for battle. The server is now under siege... HTTP/1.1 200 0.07 secs: 75 bytes ==> GET / HTTP/1.1 503 0.07 secs: 92 bytes ==> GET / HTTP/1.1 200 0.07 secs: 75 bytes ==> GET / HTTP/1.1 503 0.12 secs: 92 bytes ==> GET / HTTP/1.1 503 0.12 secs: 92 bytes ==> GET / HTTP/1.1 200 0.16 secs: 75 bytes ==> GET / HTTP/1.1 503 0.16 secs: 92 bytes ==> GET / HTTP/1.1 503 0.21 secs: 92 bytes ==> GET / HTTP/1.1 503 0.21 secs: 92 bytes ==> GET / HTTP/1.1 200 0.24 secs: 75 bytes ==> GET / HTTP/1.1 200 0.24 secs: 75 bytes ==> GET / HTTP/1.1 503 0.14 secs: 92 bytes ==> GET / HTTP/1.1 503 0.29 secs: 92 bytes ==> GET / HTTP/1.1 503 0.13 secs: 92 bytes ==> GET / HTTP/1.1 503 0.18 secs: 92 bytes ==> GET / HTTP/1.1 503 0.13 secs: 92 bytes ==> GET / HTTP/1.1 200 0.11 secs: 75 bytes ==> GET / HTTP/1.1 200 0.39 secs: 75 bytes ==> GET / HTTP/1.1 200 0.24 secs: 75 bytes ==> GET / HTTP/1.1 503 0.44 secs: 92 bytes ==> GET / HTTP/1.1 200 0.43 secs: 75 bytes ==> GET / HTTP/1.1 200 0.44 secs: 75 bytes ==> GET / HTTP/1.1 503 0.40 secs: 92 bytes ==> GET / HTTP/1.1 200 0.47 secs: 75 bytes ==> GET / HTTP/1.1 503 0.42 secs: 92 bytes ==> GET / HTTP/1.1 200 0.42 secs: 75 bytes ==> GET / HTTP/1.1 200 0.06 secs: 75 bytes ==> GET / HTTP/1.1 503 0.07 secs: 92 bytes ==> GET / HTTP/1.1 200 0.15 secs: 75 bytes ==> GET / HTTP/1.1 200 0.12 secs: 75 bytes ==> GET / HTTP/1.1 503 0.57 secs: 92 bytes ==> GET / HTTP/1.1 503 0.18 secs: 92 bytes ==> GET / HTTP/1.1 503 0.52 secs: 92 bytes ==> GET / HTTP/1.1 503 0.65 secs: 92 bytes ==> GET / HTTP/1.1 503 0.42 secs: 92 bytes ==> GET / HTTP/1.1 200 0.09 secs: 75 bytes ==> GET / HTTP/1.1 200 0.43 secs: 75 bytes ==> GET / HTTP/1.1 503 0.04 secs: 92 bytes ==> GET / HTTP/1.1 200 4.15 secs: 74 bytes ==> GET / HTTP/1.1 200 0.01 secs: 75 bytes ==> GET / Transactions: 19 hits Availability: 47.50 % Elapsed time: 4.16 secs Data transferred: 0.00 MB Response time: 0.72 secs Transaction rate: 4.57 trans/sec Throughput: 0.00 MB/sec Concurrency: 3.31 Successful transactions: 19 Failed transactions: 21 Longest transaction: 4.15 Shortest transaction: 0.01
咱們能夠看到在啓用了斷路器後各項性能都有提升。
清理配置。
istioctl delete routerule recommendation-v1-v2 -n istio-tutorial istioctl delete -f istiofiles/recommendation_cb_policy_version_v2.yml -n istio-tutorial
所謂的 Pool Ejection 就是當某些實例出現錯誤(如返回 5xx 錯誤碼)臨時將該實例彈出一段時間後(窗口期,可配置),而後再將其加入到負載均衡池中。咱們的例子中配置的窗口期是 15 秒。
將 v1 和 v2 的流量均分。
istioctl create -f istiofiles/route-rule-recommendation-v1_and_v2_50_50.yml -n istio-tutorial
增長 v2 的實例個數。
kubectl scale deployment recommendation-v2 --replicas=2 -n istio-tutorial kubectl get pods -w
等待全部的 Pod 的狀態都啓動完成。
如今到 v2 的容器中操做。
$ kubectl exec recommendation-v2-785465d9cd-225ms -c recommendation /bin/bash $ curl localhost:8080/misbehave Following requests to '/' will return a 503
增長 Pool Ejection 配置。
istioctl create -f istiofiles/recommendation_cb_policy_pool_ejection.yml -n istio-tutorial
此時再訪問 customer
服務。
$ bin/poll_customer.sh customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 10505 customer => preference => recommendation v2 from '785465d9cd-225ms': 2407 customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 10506 customer => preference => recommendation v2 from '785465d9cd-225ms': 2408 customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 10507 customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 10508 customer => preference => recommendation v1 from '6fc97476f8-m2ntp': 10509 customer => 503 preference => 503 recommendation misbehavior from '785465d9cd-ldc6j' customer => preference => recommendation v2 from '785465d9cd-225ms': 2409 customer => preference => recommendation v2 from '785465d9cd-225ms': 2410
咱們看到窗口期生效了,當出現 503 錯誤後至少 15 秒後纔會出現第二次。
即便有了負載均衡池彈出策略對於系統的彈性來講依然還不夠,若是你的服務有多個可用實例,能夠將斷路器、重試、Pool Ejection 等策略組合起來使用。
例如在以上的 Pool Ejection 的基礎上增長重試策略。
istioctl replace -f istiofiles/route-rule-recommendation-v1_and_v2_retry.yml -n istio-tutorial
如今再訪問 customer
服務就看不到 503 錯誤了。
清理配置。
kubectl scale deployment recommendation-v2 --replicas=1 -n istio-tutorial istioctl delete routerule recommendation-v1-v2 -n istio-tutorial istioctl delete -f istiofiles/recommendation_cb_policy_pool_ejection.yml -n istio-tutorial
Egress 是用來配置 Istio serivce mesh 中的服務對外部服務的訪問策略。
具體配置請參考 控制 Egress 流量。
如下示例還有問題,沒法正常工做。
構建示例鏡像 egresshttpbin。
cd egress/egresshttpbin/ mvn clean package docker build -t jimmysong/istio-tutorial-egresshttpbin:v1 . docker push jimmysong/istio-tutorial-egresshttpbin:v1
部署到 Kubernetes。
kubectl apply -f <(istioctl kube-inject -f egress/egresshttpbin/src/main/kubernetes/Deployment.yml) -n istio-toturial kubectl create -f egress/egresshttpbin/src/main/kubernetes/Service.yml
爲了在 kubernetes 集羣外部訪問到該服務,修改增長 ingress 配置並修改本地的/etc/hosts
文件,咱們在前面已經完成了,此處再也不贅述。
構建示例鏡像 egressgithub。
cd egress/egressgithub mvn clean package docker build -t jimmysong/istio-tutorial-egressgithub:v1 . docker push jimmysong/istio-tutorial-egressgithub:v1
部署到 Kubernetes。
kubectl apply -f <(istioctl kube-inject -f egress/egressgithub/src/main/kubernetes/Deployment.yml) -n istio-tutorial kubectl create -f egress/egressgithub/src/main/kubernetes/Service.yml
增長 Egress 配置。
istioctl create -f istiofiles/egress_httpbin.yml -n istio-tutorial
到 egresshttpbin 容器中測試。
kubectl exec -it $(oc get pods -o jsonpath="{.items[*].metadata.name}" -l app=egresshttpbin,version=v1) -c egresshttpbin /bin/bash curl localhost:8080 curl httpbin.org/user-agent curl httpbin.org/headers exit
增長對 jimmysong.io 的 egress 配置。
cat <<EOF | istioctl create -f - apiVersion: config.istio.io/v1alpha2 kind: EgressRule metadata: name: jimmysong-egress-rule namespace: istio-tutorial spec: destination: service: jimmysong.io ports: - port: 443 protocol: https EOF
增長 Egress 配置。
istioctl create -f istiofiles/egress_github.yml -n istio-tutorial
到 egressgithub 容器中測試。
kubectl exec -it $(oc get pods -o jsonpath="{.items[*].metadata.name}" -l app=egressgithub,version=v1) -c egressgithub /bin/bash curl http://jimmysong:443 exit
清理環境。
istioctl delete egressrule httpbin-egress-rule jimmysong-egress-rule github-egress-rule -n istio-tutorial