Istio Service Mesh 教程

Istio Service Mesh 教程

做者 宋淨超 | 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-tutorialgithub

原文地址:https://jimmysong.io/posts/istio-tutorial/spring

準備環境

在進行本教程前須要先準備如下工具和環境。docker

  • 8G 以上內存
  • Vagrant 2.0+
  • Virtualbox 5.0 +
  • 提早下載 kubernetes1.9.1 的 release 壓縮包
  • docker 1.12+
  • kubectl 1.9.1+
  • maven 3.5.2+
  • istioctl 0.7.1
  • git
  • curl、gzip、tar
  • kubetail
  • siege

安裝 Kubernetes

請參考 kubernetes-vagrant-centos-cluster 在本地啓動擁有三個節點的 kubernetes 集羣。json

git clone https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster.git
cd kubernetes-vagrant-centos-cluster
vagrant up

安裝 Istio

在 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/dotvizhttp://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。

Jaeger query UI

構建鏡像

在本地運行測試無誤以後就能夠構建鏡像了。本教程中的容器鏡像都是在 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

使用下面的命令將以上服務部署到 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

增長 Ingress 配置

爲了在 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。

服務關係圖和QPS

訪問 http://grafana.istio.jimmysong.io 查看 Service Mesh 的監控信息。

Grafana 監控

Istio 使用示例

爲了試用 Istio 中的各類功能,咱們須要爲應用構建多個版本,咱們爲 recommendation 構建 v2 版本的鏡像,看看如何使用 Istio 控制微服務的流量。

構建 recommendation:v2

咱們將構建新版的 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

修改 Istio RouteRules

如下全部路有規則都是針對 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 的智能路由(金絲雀發佈)

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

所謂的 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

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

參考

相關文章
相關標籤/搜索