揭開服務網格~Istio Service Mesh神祕的面紗

2022-07-17 21:03:10

一、寫在前面

下文跟大家介紹的Istio服務網格,我去逛他們的官網(istio的需要FQ)發現,其實官方檔案是真的真的好,各種概念給你講的清清楚楚,各種實戰的案例給你列舉的明明白白,讓我一度有放棄寫本文的打算。還寫個毛,沒有誰寫的比官網更好、更詳細,網上的各種部落格,大概率也是都是對著檔案抄~。

所以大家想學學istio,官方英文檔案絕對是第一選擇,然後在本文中,我儘量多寫點自己的理解,以及介紹Istio的能力+告訴你對應的官方檔案的位置~

推薦收藏-閱讀原文,格式有所調整,閱讀體驗感更佳

推薦收藏-閱讀原文,格式有所調整,閱讀體驗感更佳

https://mp.weixin.qq.com/s/UPQYOGZWkF9Njcv76C_v-g

https://mp.weixin.qq.com/s/UPQYOGZWkF9Njcv76C_v-g

https://mp.weixin.qq.com/s/UPQYOGZWkF9Njcv76C_v-g

推薦收藏-閱讀原文,格式有所調整,閱讀體驗感更佳

推薦收藏-閱讀原文,格式有所調整,閱讀體驗感更佳

二、微服務與K8S

下圖中是阿里的微服務架構Dubbo的架構圖,寫過相關程式碼的同學會比較清楚Dubbo中的各個元件及其作用。

  • 註冊中心 儲存服務名稱&服務地址的對映關係,當服務地址發生變動時, 主動通知消費者。
  • 服務提供者:提供服務介面的實現類,註冊/暴露服務 (遠端註冊, 本地註冊)
  • 服務消費者:啟動時從註冊中心拉取服務提供者的地址, 快取在本地,根據負載均衡策略選出一個服務進行遠端呼叫
  • 監控中心:統計RPC過程的細節資料, 如: 服務呼叫次數, 呼叫時間

Ps:瞭解更多,可以看我這篇筆記【探究Dubbo的拓展機制】

https://www.cnblogs.com/ZhuChangwu/p/12174031.html

無論是阿里的Dubbo或是Spring生態中的SpringCloud微服務架構也罷,普遍存在的現象是:開發者在基礎此類微服務架構開發專案時不可避免的需要構建諸如Euraka、Zuul偏網路層面的專案,以及寫相關的程式碼。

再之後Kubernetes生態逐漸成熟,像Dubbo之類微服務的能力,如:服務發現、服務註冊、負載均衡、動態水平擴充套件之類的能力,K8S元件其實都已經原生支援了。

就如上簡圖,對於K8S來說,使用者只需要提供一個容器映象即可,它能幫我們將映象編排/部署進Pod中,並提供了完整的將Pod暴露出去提供服務的資源物件和解決方案,而且支援全部變成語言。

對於Java應用來說,看起來開發者只需要將SpringBoot編譯產出的Jar包打包進一個有JVM執行環境的Docker映象中,再把映象的地址告訴K8S,它便能將Java應用啟動部署好對外提供服務。

這時再回頭看SpringCloud那套微服務架構的又是什麼Eureka、又是什麼Zull、Feign等等元件,好像確實沒啥存在的必要了~

當然對於一些存量的專案來講,若是完全棄用Eureka類似的元件,在程式碼層面的改造成本不亞於重寫~,再就是像Eureka這種元件也是可以部署進K8S中提供服務發現能力的,具體怎麼搞、要不要搞,見仁見智~

三、服務網格與K8S

還是先回到這張簡圖,首先得肯定的是,K8S本來就是支援編排/部署、服務發現、負載均衡等一系列能力的。

然後我很直觀的感覺:大家吹捧的服務網格,本質上其實是對K8S流量排程&流量治理能力的增強。

要是說:服務網格實現了將業務邏輯和網路策略的隔離,不能說不對,但不是重點,因為原生的K8S各元件已經具備這個能力了。

所以說劃重點:

  • K8S本身是有流量排程和流量治理能力,但是能力弱。
  • 服務網路這種產品的中心思想是:流量治理,四個字,尤其是在負載呼叫鏈路治理業務場景下尤為出色。

所以其實如果你不想用什麼Istio的金絲雀釋出、或者是流量治理能力,完全可不不用服務網格能力。就原生的Ingress+service+deployment完全可以滿足我們部署web服務的需求。

四、常見的產品

產品 簡介
Linkerd 是一款高效能網路代理程式,標誌著Service Mesh時代的開始。
Envoy 有C++開發的,為雲原生應用而設計,是一款高效能的網路代理
Istio 底層為Envoy,是Service Mesh的典型實現
Kuma 是一款基於Envoy構建的服務網路控制平面,Kuma設計的資料平面和控制平面可以極大的降低開發團隊使用服務網格的難度。

五、Istio架構

官網:https://istio.io/

中文版:https://istio.io/latest/zh/docs/ops/deployment/architecture/

推薦先完整的看一遍Concept篇:https://istio.io/latest/docs/concepts/traffic-management/

若是使用Istio這款服務網路產品,它會以side car的方式為我們業務Pod自動預設注入proxy容器,Proxy容器的底層是Envoy網路策略代理,由proxy統一提供網路相關能力。

在研發同學的視角來看,他只需要關注自己的業務邏輯就好~

不足之處:每個業務pod被自動注入一個用來實現網路策略的邊車proxy容器,進出業務容器的流量都要流經Proxy代理,看起來多了一步,感覺會變慢。好在Proxy與業務容器在同一個Pod中可共用NetworkNamespace,通訊使用本地迴環網路卡、網路耗時可以忽略不計。


下圖是Istio的架構圖:

參考這篇:https://istio.io/latest/docs/ops/deployment/architecture/

  • Istio將服務網路劃分成兩大部分
    • Control plane:控制平面,由Pilot、Citadel、Galley組成(istio1.5之前這三個元件獨立為3個pod部署,1.5之後融合成istiod),負責服務發現、設定、認證,是設定進行統一的管理然後分發給不通的資料平面。
    • Data plance:資料平面
  • 控制平面
    • Pilot:為Eonvoy提供服務發現能力,為AB測試、金絲雀釋出、流量熔斷、重試、超時提供流量管控能力
    • Citadel:可用於升級服務網格中未加密的流量。
    • Galley:設定管理,驗證設定資訊的正確性,經過驗證後的設定才會傳送給Proxy使用,使用網格設定協定(Mesh Configuration Protol)和其他元件進行設定互動。
  • 每個業務Pod中都會被注入一個Proxy容器(Envoy),業務容器進出的流量都會流經proxy排程。
    • 服務發現、負載均衡、服務熔斷、健康檢查、基於流量百分比劃分的灰度釋出、故障注入、豐富的度量指標
  • Ingress traffic:管控入口流量。
  • Egress traffic:管控出口流量。
  • 東西流量:pod間相互存取的流量。
  • 南北流量:從Ingress traffic進來的流量,從Egress traffic出去的流量。

六、Istio的核心資源介紹

參考這篇:https://istio.io/latest/docs/concepts/traffic-management/

6.1、VirtualService

  • K8S中的Serivce最終生成的是iptables規則或者是ipvs規則
  • VirtualService最終生成的Istio規則

我們都知道K8S中原生的Service本質上代理著一組Pod,當我們存取Service時,它可以將流量下發到它代理的那組Service上,無論是隨機還是輪詢,原生的Service所做的,其實只是簡單的:流量下發

而VirtualService相較於原生的Service的流量下發能力外,還有流量管理的能力,劃重點:管理東西流量。

比如:按比例管理流量打到相同應用的不同版本的Pod中(金絲雀釋出)

比如:根據不同的使用者來源、根據請求中攜帶的不同header管理流量(A/B 測試)

VS模版

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
	# 可以是ip地址、DNS名稱、K8S中的Service名、FQDN、也可以是萬用字元*
  hosts:
  - reviews
  http:
  # 匹配規則,不強制有
  - match:
    # 匹配請求頭:end-user 完全等於 jason的流量
    - headers:
        end-user:
          exact: jason
    # 命中匹配後,將流量route到哪裡去
    route:
    - destination:
    		# 指定路由到host=reviews的service中
    		# 有名稱空間限制,推薦寫成:${svc-name}.${namespace}.svc.cluster.local
        host: reviews
        # subset是由dr資源劃分的版本號,也就是v2版本的reviews
        subset: v2
  # 從上到下匹配,若未匹配到響應的請求頭,預設走下面這條設定      
  - route:
    - destination:
        host: reviews
        subset: v3

6.2、Destination Rule

大白話講講上下文:

比如現在我們有個程式碼庫叫:usercenter 使用者中心。然後上線釋出這個程式碼庫,編譯產出、打包映象、通過Deployment資源將映象部署進K8S中,併為Pod搭上標籤app=usercenter,得到了一組具有app=usercenter標籤的 pod。然後再通過一個叫svc-usercenter代理有app=usercenter的pod對外提供服務。

然後我們對usercenter進行一次比較大的迭代升級,為了使用Istio的特性,於是我們新搞一個Deployment V2部署最新的映象,然後給pod多打一個叫version=v2的label,因為這組新的pod也有app=usercenter的標籤,所以他們也能被svc-usercenter代理。

但是問題是我們不直接使用原生K8S的Service而是使用Istio的VirtualService,通過vs的規則可以找到svc-usercenter的不同subset,那這個子集是如何劃分的呢?答案就是:通過DestinationRule資源,根據pod的不同versionlabel的不同值劃分,如下

如下範例,參考:https://istio.io/latest/docs/reference/config/networking/destination-rule/

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-destination-rule
spec:
	# 後端真實服務service地址
	# 有名稱空間限制,推薦寫成:${svc-name}.${namespace}.svc.cluster.local
  host: my-svc
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  # 帶有version=v1的pod劃分進subset=v1
  - name: v1
    labels:
      version: v1
   # 帶有version=v2的pod劃分進subset=v2
  - name: v2
    labels:
      version: v2
    # 負載均衡策略為隨機
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
  # 帶有version=v3的pod劃分進subset=v3的子集      
  - name: v3
    labels:
      version: v3

6.3、Gateway

  • 通過VistualService管理東西流量
  • 通過Gateway管理南北流量

之前是使用Ingress代理Service,接受最外層的HTTP/TCP流量,並將流量轉發到不同的Service中

使用Istio之後,Istio提供Gateway元件IngressGateway在網格的最外層接收HTTP/TCP流量,並將請求轉發到網格內部的VS,也支援出口流量的管理,可以將出口流量固定從EgressGateway的服務中代理出去。

注意:IngressGateway、EgressGateway是兩類Pod

範例:一般Gateway上只設定埠、主機名、證書

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: ext-host-gwy
spec:
  selector:
   	# ingress-gateway/egress-gateway pod的標籤
    app: my-gateway-controller
  # 設定不同的入口,也就是不同主機地址及其port  
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - ext-host.example.com
    # 也可以是萬用字元*
    # - "*"
    tls:
      mode: SIMPLE
      credentialName: ext-host-cert

6.4、SE

使用ServiceEntry資源物件可以將一個服務網格外部的應用新增進服務網格的服務登入檔中,新增完之後,Envoy 代理可以將流量傳送到服務,就好像它實打實的在網格中一樣。

它的典型應用場景是:若我們開發的應用依賴較多的其他上下游服務,這時可以將我們的本地開發機上的應用接入進服務網格中,作為其中的一環,複用網格中的其他應用做我們的上下游,方便快速開發~

瞭解更多參考:https://istio.io/latest/docs/concepts/traffic-management/#service-entries

七、安裝

7.1、安裝istio

根據自己的K8S叢集版本選擇要安裝的Istio版本:https://istio.io/latest/docs/releases/supported-releases/

下文使用Operator安裝:https://istio.io/latest/docs/setup/install/

下載istio使用者端工具:https://github.com/istio/istio/tags

# 下載
wget https://github.com/istio/istio/releases/download/1.11.6/istio-1.11.6-linux-amd64.tar.gz
# 解壓
tar -xzvf istio-1.11.6-linux-amd64.tar.gz
# 將工具放到/usr/local/bin下
mv istio-1.11.6/bin/istioctl /usr/local/bin/

# 檢視
$ istioctl version
no running Istio pods in "istio-system"
1.11.6

安裝:https://istio.io/latest/docs/setup/install/operator/#install

自動部署istio的operator

$ istioctl operator init

檢視operator是否正常

$ kubectl get pod -n istio-operator
NAME                              READY   STATUS    RESTARTS   AGE
istio-operator-55f48b7495-r8hnn   1/1     Running   0          5m8s

通過CRD安裝Istio

vim istio-operator.yaml

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  namespace: istio-system
  name: example-istiocontrolplane
spec:
  profile: default
  components:
  	# 預設igressGateways使用Loadbalancer,為相容自己的K8S叢集,改成NodePort型別
    ingressGateways:
    - name: istio-igressgateway
      enabled: true
      k8s:
        service:
          type: NodePort
          ports:
          - port: 15020
            nodePort: 30520
            name: status-port
          - port: 80
            # 通過宿主機ip+30080可存取到服務網格內的應用
            nodePort: 30080
            name: http2
            targetPort: 8080
          - port: 443
            nodePort: 30443
            name: https
            targetPort: 8443

更多istio-operator設定參考:https://istio.io/latest/docs/reference/config/istio.operator.v1alpha1/

安裝:

$  istioctl manifest apply -f istio-operator.yaml
✔ Istio core installed
✔ Istiod installed
✔ Ingress gateways installed
✔ Installation complete

檢視安裝結果:

$ kubectl get po,svc -n istio-system

7.2、安裝kiali和jaeger

進入istio的解壓目錄安裝

$  kubectl apply -f samples/addons/kiali.yaml
serviceaccount/kiali created
configmap/kiali created
clusterrole.rbac.authorization.k8s.io/kiali-viewer created
clusterrole.rbac.authorization.k8s.io/kiali created
clusterrolebinding.rbac.authorization.k8s.io/kiali created
role.rbac.authorization.k8s.io/kiali-controlplane created
rolebinding.rbac.authorization.k8s.io/kiali-controlplane created
service/kiali created
deployment.apps/kiali created

檢視狀態

$  kubectl get svc,po -n istio-system -l app=kiali
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)              AGE
service/kiali   ClusterIP   192.168.138.0   <none>        20001/TCP,9090/TCP   65s

NAME                         READY   STATUS    RESTARTS   AGE
pod/kiali-787bc487b7-fhjpq   1/1     Running   0          65s

將kiali的svc型別修改成NodePort

$ kubectl edit svc kiali -n istio-system

安裝jaeger

$ kubectl apply -f samples/addons/jaeger.yaml

7.3、安裝Prometheus和Kibana

Istio可以展示請求數量的統計,請求的持續時間,這些指標可以使用Prometheus採集

Istio內建了Promethetus和Garfana的安裝檔案

$ kubectl create -f samples/addons/prometheus.yaml -f samples/addons/grafana.yaml

八、官方練習專案Book-Info

8.1、安裝

參考:https://istio.io/latest/docs/examples/bookinfo/

建立專案:

$ kubectl create ns bookinfo
# 要新增istio-injection=enabled後,才會被自動注入istio的proxy
$ kubectl label ns bookinfo istio-injection=enabled
$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n bookinfo

部署完之後可以發現,pod每個業務Pod都含有兩個容器,除了我們自己的業務容器之外還被注入了一個Istio的Proxy容器,使用的映象是docker.io/istio/proxyv2:1.11.6,若

在kiali中檢視,可以在kiali中開啟Auto Injection(其實就是給namespace新增label:istio-injection=enabled

將productpage-svc修改成NodePort,然後存取:http://10.10.10.201:30916/productpage

存取幾次之後可以在Kiali中檢視到流量的鏈路

8.2、使用域名的方式釋出

類比Ingress去理解,在Ingress中我們可以用域名的方式去釋出服務,前提是我們得先安裝好IngressController(相當於Nginx),然後通過建立Ingress資源物件(相當於nginx.conf)去生成IngressController的設定。

在Istio架構體系中,和IngressController作用相當的軟體是:IngressGateway,之前已經裝過了,如下

再就是如何設定IngressGateway?答案是:通過建立Gateway資源物件設定IngressGateway

產品名: Ingress Istio
類比功能: IngressController IngressGateway
類比功能: Ingress Gateway

BookInfo專案的Gateway設定和VS設定如下

$ vim samples/bookinfo/networking/bookinfo-gateway.yaml
# 修改vs的host為具體的域名

# 建立
$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -n bookinfo

bookinfo-gateway.yaml詳情如下:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
  	# 這個標籤由istio-igressgateway-65846c5 pod攜帶
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    # 接受所有域名的流量
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  # 當前vs僅對如下域名生效
  - "bookinfo.kubeeasy.com"
  gateways:
  # 指定和哪個gateway繫結
  - bookinfo-gateway
  http:
  - match:
    - uri:
        exact: /productpage
    - uri:
        prefix: /static
    - uri:
        exact: /login
    - uri:
        exact: /logout
    - uri:
        prefix: /api/v1/products
    route:
    - destination:
    		# host的值為真實的svc的name,由於在同一個名稱空間下,可以不加svc.local字尾
        host: productpage
        port:
        	# svc的埠號
          number: 9080

檢視資源

$ kubectl get gw,vs -n bookinfo
NAME                                           AGE
gateway.networking.istio.io/bookinfo-gateway   3m32s

NAME                                          GATEWAYS               HOSTS                       AGE
virtualservice.networking.istio.io/bookinfo   ["bookinfo-gateway"]   ["bookinfo.kubeeasy.com"]   3m32s

修改本機host,將bookinfo.kubeeasy.com解析成istio-system名稱空間下ingressgateway-pod所在機器ip

設定之後可以使用域名存取:http://bookinfo.kubeeasy.com:30916/productpage


生產環境參考

九、Istio實用的能力

9.1、支援的負載均衡演演算法

預設負載均衡演演算法是:輪詢

全域性負載均衡設定

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: bookinfo-ratings
spec:
  host: ratings.prod.svc.cluster.local
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN

也可以設定指定subset的負載均衡

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-destination-rule
spec:
	# 後端真實服務service地址
	# 有名稱空間限制,推薦寫成:${svc-name}.${namespace}.svc.cluster.local
  host: my-svc
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  # 帶有version=v1的pod劃分進subset=v1
  - name: v1
    labels:
      version: v1
   # 帶有version=v2的pod劃分進subset=v2
  - name: v2
    labels:
      version: v2
    # 負載均衡策略為隨機,它的優先順序大於上面的RANDOM 
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN

參考:https://istio.io/latest/docs/reference/config/networking/destination-rule/#LoadBalancerSettings

更過負載均衡設定項參考:https://istio.io/latest/docs/reference/config/networking/destination-rule/#LoadBalancerSettings-SimpleLB

9.2、金絲雀釋出

首先我們在部署專案時需要兩個標籤去標記pod。

如上圖:appversion。其中的app標籤是給service使用的,version標籤用來給istio劃分subnet

  1. 使用DR換分subnet
  2. 使用vs做流量的route
  3. 使用新的deployment部署新的應用pod,version標籤值有別於老版本(此時vs不會將流量route過來)
  4. 修改vs調整切換流量

Step1:首先建立DR

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-destination-rule
spec:
	# 後端真實服務service地址,通過這個service可以找到endpoint全集
	# 然後根據不同的標籤將endpoint全集劃分成不同的subnet
  host: my-svc
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  # 帶有version=v1的pod劃分進subset=v1
  - name: v1
    labels:
      version: v1
   # 帶有version=v2的pod劃分進subset=v2
  - name: v2
    labels:
      version: v2
    # 負載均衡策略為隨機
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
  # 帶有version=v3的pod劃分進subset=v3的子集      
  - name: v3
    labels:
      version: v3

Step2:建立VirtualService,將流量全部打到指定service的subnet-v1的endpoint上

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
	# 可以是ip地址、DNS名稱、K8S中的Service名、FQDN、也可以是萬用字元*
  hosts:
  - reviews
  http:
  - route:
    - destination:
    		# service 名稱
        host:  my-svc
        subset: v1

Step3:使用新的deployment部署新的應用pod,version標籤值有別於老版本(此時vs不會將流量route過來)

Step4:修改vs調整切換流量

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
	# 可以是ip地址、DNS名稱、K8S中的Service名、FQDN、也可以是萬用字元*
  hosts:
  - reviews
  http:
  - route:
    - destination:
    		# service 名稱
        host:  my-svc
        subset: v1
      # 80%的流量轉發到v1版本的subset中  
      weight: 80  
  - route:
    - destination:
    		# service 名稱
        host:  my-svc
        subset: v2
			# 80%的流量轉發到v2版本的subset中        
      weight: 20    

9.3、AB測試

什麼是:所謂AB測試就是說將新上線的服務推播給部分指定的人群,比如先開放給公司內部的人,或者是先開放給某個城市的人使用。

怎麼做:在Istio中的VS可以通過匹配請求頭的方式完成流量的劃分,如下match部分,以此來實現AB測試。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
	# 可以是ip地址、DNS名稱、K8S中的Service名、FQDN、也可以是萬用字元*
  hosts:
  - reviews
  http:
  # 匹配規則,不強制有
  - match:
    # 匹配請求頭:end-user 完全等於 jason的流量
    - headers:
        end-user:
          exact: jason
    # 命中匹配後,將流量route到哪裡去
    route:
    - destination:
    		# 指定路由到host=reviews的service中
        host: reviews
        # subset是由dr資源劃分的版本號,也就是v2版本的reviews
        subset: v2
  # 從上到下匹配,若未匹配到響應的請求頭,預設走下面這條設定      
  - route:
    - destination:
        host: reviews
        subset: v3

除了匹配請求頭之外,更多匹配模式參考:https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPMatchRequest

9.4、地址重定向

需求:將存取www.1.com的流量跳轉到www.2.com

參考實現:https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPRedirect

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - "bookinfo.v111.com"
  gateways:
  - bookinfo-gateway
	http:
  - match:
    - uri:
        exact: /v1/getProductRatings
    redirect:
      uri: /v2/bookRatings
      authority: bookinfo.v222.com

將請求:bookinfo.v111.com/v1/getProductRatings的流量轉發到bookinfo.v222.com/v2/bookRatings

9.5、地址重寫

如:存取ratings.prod.svc.cluster.localrewrite到ratings.prod.svc.cluster.local/index.html

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings-route
spec:
  hosts:
  - ratings.prod.svc.cluster.local
  http:
  - match:
    - uri:
        prefix: /
    rewrite:
      uri: /index.html
    route:
    - destination:
        host: ratings.prod.svc.cluster.local
        subset: v1

9.6、連線數控制

參考:https://istio.io/latest/docs/reference/config/networking/destination-rule/#OutlierDetection

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews-cb-policy
spec:
  host: reviews.prod.svc.cluster.local
  # 可設定在subset級別
  trafficPolicy:
  	# 連線池的設定,可以和熔斷detection分開使用
    connectionPool:
      tcp:
      	# 最大的連線數
        maxConnections: 100
      http:
      	# 最大請求數
        http2MaxRequests: 1000
        # 每個請求最大的連結數
        maxRequestsPerConnection: 10

超過最大的連線數外的請求會被拒絕不處理。

9.7、服務熔斷

服務熔斷謹慎使用,比如有人惡意存取我們的應用觸發了熔斷機制,被熔斷的服務不再處理任何請求,等待熔斷時間之後,服務被重啟,此時惡意攻擊者可能還是在攻擊

參考:https://istio.io/latest/docs/reference/config/networking/destination-rule/#OutlierDetection

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews-cb-policy
spec:
  host: reviews.prod.svc.cluster.local
  # 可設定在subset級別
  trafficPolicy:
  	# 連線池的設定,可以和熔斷detection分開使用
    connectionPool:
      tcp:
      	# 最大的連線數
        maxConnections: 100
      http:
      	# 最大請求數
        http2MaxRequests: 1000
        # 每個請求最大的連結數
        maxRequestsPerConnection: 10
    outlierDetection:
    	# 持續出現7個5xx錯誤後,服務熔斷
      consecutive5xxErrors: 7
      # 每間5分鐘探測一次
      interval: 5m
      # 熔斷的時間
      baseEjectionTime: 15m 
      # 被熔斷服務的最大百分比
      maxEjectionPercent: 50

限制最大連線數和熔斷一起設定效果是:超過最大請求數的連線被拒絕處理,返回5xx狀態碼,當5xx出現的數量達到consecutive5xxErrors設定的閾值之後,會觸發熔斷,熔斷時常baseEjectionTime

bookinfo專案中有fortio壓測工具

$ kubectl apply -f samples/httpbin/sample-client/fortio-deploy.yaml -n bookinfo

壓測命令-c指定並行數,-n 傳送的請求數

$ kubectl exec -ti $fortio-pod-name -n bookinfo -- fortio load -c 2 - qps 0 -n 20 -loglevel Warning http://ratings:9080/ratings/0 | grep Code

9.8、故障注入

9.8.1、延時故障

什麼是延時故障:通過設定的方式延長本次請求的請求時長

目的:觀測請求的上游針對這種情況是如何處理的

參考:https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPFaultInjection-Delay

參考:https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPFaultInjection

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews-route
spec:
  hosts:
  - reviews.prod.svc.cluster.local
  http:
  - match:
    - sourceLabels:
        env: prod
    route:
    - destination:
        host: reviews.prod.svc.cluster.local
        subset: v1
    # 新增故障    
    fault:
    	# 故障型別為delay
      delay:
        # 故障注入的比例
        percentage:
          value: 10
        # 延時時間  
        fixedDelay: 5s
9.8.2、中斷故障

強行中斷本次請求,觀測上游的是如何處理的。

參考:https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPFaultInjection-Abort

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings-route
spec:
  hosts:
  - ratings.prod.svc.cluster.local
  http:
  - route:
    - destination:
        host: ratings.prod.svc.cluster.local
        subset: v1
    fault:
    	# 中斷故障
      abort:
        # 中斷0.1%的請求
        percentage:
          value: 0.1
        # 中斷的錯誤狀態碼  
        httpStatus: 400