揭開服務網格~Istio Service Mesh神秘的面紗
- 2022 年 7 月 17 日
- 筆記
- Kubernetes
一、寫在前面
下文跟大家介紹的Istio服務網格,我去逛他們的官網(istio的需要FQ)發現,其實官方文檔是真的真的好,各種概念給你講的清清楚楚,各種實戰的案例給你枚舉的明明白白,讓我一度有放棄寫本文的打算。還寫個毛,沒有誰寫的比官網更好、更詳細,網上的各種部落格,大概率也是都是對著文檔抄~。
所以大家想學學istio,官方英文文檔絕對是第一選擇,然後在本文中,我盡量多寫點自己的理解,以及介紹Istio的能力+告訴你對應的官方文檔的位置~
推薦收藏-閱讀原文,格式有所調整,閱讀體驗感更佳
推薦收藏-閱讀原文,格式有所調整,閱讀體驗感更佳
//mp.weixin.qq.com/s/UPQYOGZWkF9Njcv76C_v-g
//mp.weixin.qq.com/s/UPQYOGZWkF9Njcv76C_v-g
//mp.weixin.qq.com/s/UPQYOGZWkF9Njcv76C_v-g
推薦收藏-閱讀原文,格式有所調整,閱讀體驗感更佳
推薦收藏-閱讀原文,格式有所調整,閱讀體驗感更佳
二、微服務與K8S
下圖中是阿里的微服務框架Dubbo的架構圖,寫過相關程式碼的同學會比較清楚Dubbo中的各個組件及其作用。
- 註冊中心 保存服務名稱&服務地址的映射關係,當服務地址發生變動時, 主動通知消費者。
- 服務提供者:提供服務介面的實現類,註冊/暴露服務 (遠程註冊, 本地註冊)
- 服務消費者:啟動時從註冊中心拉取服務提供者的地址, 快取在本地,根據負載均衡策略選出一個服務進行遠程調用
- 監控中心:統計RPC過程的細節數據, 如: 服務調用次數, 調用時間
Ps:了解更多,可以看我這篇筆記【探究Dubbo的拓展機制】
無論是阿里的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架構
官網://istio.io/
中文版://istio.io/latest/zh/docs/ops/deployment/architecture/
推薦先完整的看一遍Concept篇://istio.io/latest/docs/concepts/traffic-management/
若是使用Istio這款服務網路產品,它會以side car的方式為我們業務Pod自動默認注入proxy容器,Proxy容器的底層是Envoy網路策略代理,由proxy統一提供網路相關能力。
在研發同學的視角來看,他只需要關注自己的業務邏輯就好~
不足之處:每個業務pod被自動注入一個用來實現網路策略的邊車proxy容器,進出業務容器的流量都要流經Proxy代理,看起來多了一步,感覺會變慢。好在Proxy與業務容器在同一個Pod中可共享NetworkNamespace,通訊使用本地迴環網卡、網路耗時可以忽略不計。
下圖是Istio的架構圖:
參考這篇://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的核心資源介紹
參考這篇://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的不同version
label的不同值劃分,如下
如下示例,參考://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 代理可以將流量發送到服務,就好像它實打實的在網格中一樣。
它的典型應用場景是:若我們開發的應用依賴較多的其他上下游服務,這時可以將我們的本地開發機上的應用接入進服務網格中,作為其中的一環,復用網格中的其他應用做我們的上下游,方便快速開發~
了解更多參考://istio.io/latest/docs/concepts/traffic-management/#service-entries
七、安裝
7.1、安裝istio
根據自己的K8S集群版本選擇要安裝的Istio版本://istio.io/latest/docs/releases/supported-releases/
下文使用Operator安裝://istio.io/latest/docs/setup/install/
下載istio客戶端工具://github.com/istio/istio/tags
# 下載
wget //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
安裝://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配置參考://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、安裝
參考://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,然後訪問://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
配置之後可以使用域名訪問://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
參考://istio.io/latest/docs/reference/config/networking/destination-rule/#LoadBalancerSettings
更過負載均衡配置項參考://istio.io/latest/docs/reference/config/networking/destination-rule/#LoadBalancerSettings-SimpleLB
9.2、金絲雀發布
首先我們在部署項目時需要兩個標籤去標記pod。
如上圖:app
、version
。其中的app標籤是給service使用的,version標籤用來給istio劃分subnet
- 使用DR換分subnet
- 使用vs做流量的route
- 使用新的deployment部署新的應用pod,version標籤值有別於老版本(此時vs不會將流量route過來)
- 修改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
除了匹配請求頭之外,更多匹配模式參考://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPMatchRequest
9.4、地址重定向
需求:將訪問www.1.com的流量跳轉到www.2.com
參考實現://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.local
rewrite到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、連接數控制
參考://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、服務熔斷
服務熔斷謹慎使用,比如有人惡意訪問我們的應用觸發了熔斷機制,被熔斷的服務不再處理任何請求,等待熔斷時間之後,服務被重啟,此時惡意攻擊者可能還是在攻擊
參考://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 //ratings:9080/ratings/0 | grep Code
9.8、故障注入
9.8.1、延時故障
什麼是延時故障:通過配置的方式延長本次請求的請求時長
目的:觀測請求的上游針對這種情況是如何處理的
參考://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPFaultInjection-Delay
參考://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、中斷故障
強行中斷本次請求,觀測上游的是如何處理的。
參考://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