在服務治理中,流量管理是一個廣泛的話題,一般情況下,常用的包括:
- 動態修改服務訪問的負載均衡策略,比如根據某個請求特征做會話保持;
- 同一個服務有多版本管理,將一部分流量切到某個版本上;
- 對服務進行保護,例如限制並發連接數、限制請求數、隔離故障服務實例等;
- 動態修改服務中的內容,或者模擬一個服務運行故障等。
在Istio中實現這些服務治理功能時無須修改任何應用的代碼。較之微服務的SDK方式,Istio以一種更輕便、透明的方式向用戶提供了這些功能。用戶可以用自己喜歡的任意語言和框架進行開發,專注於自己的業務,完全不用嵌入任何治理邏輯。只要應用運行在Istio的基礎設施上,就可以使用這些治理能力。
總結Istio流量治理的目標:以基礎設施的方式提供給用戶非侵入的流量治理能力,用戶只需關注自己的業務邏輯開發,無須關注服務訪問管理。
istio流量治理的核心組件Pilot
在istio1.8中,istio的分為 envoy
(數據平面) 、istiod
(控制平面) 、addons
(管理插件) 及 istioctl
(命令行工具,用於安裝、配置、診斷分析等操作)組成。
Pilot是Istio控制平面流量管理的核心組件,管理和配置部署在Istio服務網格中的所有Envoy代理實例。
pilot-discovery為envoy sidecar提供服務發現,用於路由及流量的管理。通過kubernetes CRD資源獲取網格的配置信息將其轉換為xDS接口的標准數據格式后,通過gRPC分發至相關的envoy sidecar
Pilot組件包含工作在控制平面中的 pilot-discovery
和工作與數據平面的pilot-agent
與Envoy(istio-proxy)
pilot-discovery主要完成如下功能:
- 從service registry中獲取服務信息
- 從apiserver中獲取配置信息。
- 將服務信息與配置信息適配為xDS接口的標准數據格式,通過xDS api完成配置分發。
pilot-agent 主要完成如下功能
-
基於kubernetes apiserver為envoy初始化可用的boostrap配置文件並啟動envoy。
-
管理監控envoy的雲兄狀態及配置重載。
envoy
- 每個sidecar中的envoy是由pilot-agent基於生產的bootstrap配置進行啟動,並根據指定的pilot地址,通過xDS api動態獲取配置。
- sidecar形式的envoy通過流量攔截機制為應用程序實現入站和出站的代理功能。
Pilot的實現
在istio中的管理策略都是基於Kubernetes CRD的實現,其中有關於流量管理的CRD資源包括 VirtualService
EnvoyFilter
Gateway
ServiceEntry
Sidecar
DestinationRule
WorkloadEntry
WorkloadGroup
。reference istio-networking-crd-resouces
-
VirtualServices:用於定義路由,可以理解為envoy的
listener
=>filter
=>route_config
-
DestinationRule:用於定義集群,可以理解為envoy 的 cluster
-
Gateway:用於定義作用於
istio-ingress-gateway
-
ServiceEntry:用於定義出站的路由,作用於
istio-egress-gateway
-
EnvoyFilter:為envoy添加過濾器或過濾器鏈。
-
Sidecar:用於定義運行在sidecar之上的envoy配置。
Virtual Services和 Destination Rules是Istio流量路由功能的核心組件
istio流量流程概要
在控制面會經過如下流程:
- (1)管理員通過命令行或者API創建流量規則;
- (2)Pilot將流量規則轉換為Envoy的標准格式;
- (3)Pilot將規則下發給Envoy。
在數據面會經過如下流程:
- (1)Envoy攔截Pod上本地容器的Inbound流量和Outbound流量;
- (2)在流量經過Envoy時執行對應的流量規則,對流量進行治理。
路由規則 :Virtual Services
VirtualServices
是istio用於在其運行平台Kubernetes定義的配置,用來影響流量的路由規則;其本質就是為集群中envoy提供路由配置的。
VirtualServices名詞解釋
VirtualServices中一些流量路由定義的關鍵術語。
-
Services:服務的唯一應用名稱的單位,在Kubernetes之上 Services通常為Kubernetes Services資源。
-
Source:在上文中,下游發起請求的客戶端服務。
-
Host:客戶端請求服務時使用的地址
-
Service versions:service允許的不同版本的子集(通常為流量管理中的概念,如AB等)每個Service都有一個包含所有實例的默認版本。
VirtualServices資源說明
VirtualServices中主要有這些配置用於配置流量的路由定義。 reference virtual services
-
hosts:string[] 目標主機,可以是帶有統配符的DNS Name或IP
-
gateways:string[],這些資源生效的網關和sidecar的名稱。默認為名稱空間級別,跨名稱空間使用
<gateway namespace>/<gateway name>
-
mesh
默認值,表示生效與網格內所有sidecar -
僅應用於Gateway,該字段設置為Gateway的名稱。
-
忽略此字段:將應用於網格內部所有的sidecar
-
-
http: HTTP協議流量的路由規則表。
- match:[] 匹配的條件。一個列表內單項內容的條件具有AND,整個列表的條件為OR。
- name:
- uri:匹配值區分大小寫
exact:
精確匹配。prefix
:用於前綴匹配。regex
:基於正則表達式匹配。
- method:HTTP方法,參數與uri相同。
- ...
- route:[] 設置的http流量的轉發規則
- destination:請求轉發到的唯一標識符。
- host:允許平台及ServiceEntry的服務名稱,Kubernetes中為短名稱
reviews.default.svc.cluster.local
- subset,在DestinationRule中定義的子集
- port:可選,公開服務的端口
- host:允許平台及ServiceEntry的服務名稱,Kubernetes中為短名稱
- weight:轉發流量的比例0-100 ,各目標的和應為100。
- headers:操作頭規則。
- destination:請求轉發到的唯一標識符。
- redirect:重定向規則
- delegate:只能在
Route
和Redirect
為空時設置,委托的VirtualServices
名稱 - rewrite:重寫HTTP URI。
- timeout:HTTP請求超時,默認禁用。
- retries:HTTP請求重試策略。
- fault:故障注入
- mirror:流量鏡像
- mirrorPercentage:對應mirror的比例
- headers:操作http頭的規則
- ...
- match:[] 匹配的條件。一個列表內單項內容的條件具有AND,整個列表的條件為OR。
-
tcp:TCP流量的路由規則的有序列表
-
exportTo:允許
VirtualServices
其他名稱空間的sidecar與gateway使用。
VirtualServices配置實例
基於HTTP header的請求,將請求為/ratings/v2/
路徑,並且請求頭包含 end-user
值為jason
。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings-route
spec:
hosts:
- ratings.prod.svc.cluster.local
http:
- match:
- headers:
end-user:
exact: jason
uri:
prefix: "/ratings/v2/"
ignoreUriCase: true # 是否區分大小寫,僅exact和prefix生效。
route:
- destination:
host: ratings.prod.svc.cluster.local
委托其他virtualServices處理
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "bookinfo.com"
gateways:
- mygateway
http:
- match:
- uri:
prefix: "/productpage"
delegate:
name: productpage
namespace: nsA
- match:
- uri:
prefix: "/reviews"
delegate:
name: reviews
namespace: nsB
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: productpage
namespace: nsA
spec:
http:
- match:
- uri:
prefix: "/productpage/v1/"
route:
- destination:
host: productpage-v1.nsA.svc.cluster.local
- route:
- destination:
host: productpage.nsA.svc.cluster.local
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
namespace: nsB
spec:
http:
- route:
- destination:
host: reviews.nsB.svc.cluster.local
目標規則:DestinationRule
DestinationRule定義在完成路由配置后應用於服務流量的策略,即如何將流量調度至集群內,可以理解為DestinationRule定義的是envoy中的cluster。應用的內容也是envoy中cluster段的配置,如負載均衡配置,sidecar連接值及離群檢測。
DestinationRule字段說明
- host: 注冊表中的服務名稱,kubernetes平台中使用短名稱
- trafficPolicy:應用的流量策略。
- loadBalancer:使用的負載均衡算法,
- simple
- ROUND_ROBIN
- LEAST_CONN
- RANDOM
- PASSTHROUGH
- simple
- connectionPool:一致性hash
- outlierDetection:離群值檢測
- consecutiveGatewayErrors:滿足502 503 504 錯誤數彈出。
- consecutive5xxErrors: 滿足5xx錯誤數彈出。
- interval:探測時間間隔
- baseEjectionTime:最小逐出時間。主機被驅逐的時間等於
baseEjectionTime
* 退出次數。 - maxEjectionPercent:最大驅逐比例,默認10%。
- minHealthPercent:最少健康比例,默認為0%
- tls
- portLevelSettings
- loadBalancer:使用的負載均衡算法,
- subsets:[] 服務各個版本命名集。
- name:子集的名稱
- labels:標簽過濾器
- trafficPolicy:子集流量策略,繼承DestinationRule級別流量策略。
- exportTo:跨名稱空間使用。
DestinationRule配置實例
基於服務子集的配置
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: bookinfo-ratings
spec:
host: ratings.prod.svc.cluster.local
trafficPolicy:
loadBalancer:
simple: LEAST_CONN
subsets:
- name: testversionv3
labels:
version: v3
- name: testversionv2
labels:
version: v2
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
配置離群值
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews-cb-policy
spec:
host: reviews.prod.svc.cluster.local
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
http2MaxRequests: 1000
maxRequestsPerConnection: 10
outlierDetection:
consecutiveErrors: 7
interval: 5m
baseEjectionTime: 15m
集群網關入口:Gateway
Istio還提供了一種配置模型 Istio Gateway。Gateway
與 KubernetesIngress
相比,Gateway有高度的定制化與靈活性,並且允許將Istio功能應用於集群流量入口。
Gateway中運行的程序為envoy,它從控制平面接收相應的配置,並完成相關流量的傳輸;Gateway資源只負責網絡入口點的相關功能,具體的路由實現則由VirtualService完成。
Gateway 配置說明
Gateway定義了一個集群入口的負載均衡器,該負載均衡為運行在網格的邊緣代理,負責將外部流量引入集群的內部。
Gateway資源生效於Ingress
| Egress
Envoy Pod的標簽選擇器,使用selector定義:selector: app=istio-ingressgateway
。
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: study-gateway
namespace: default
spec:
selector: # 基於名稱空間中匹配pod的標簽從而生效的應用
app: istio-ingressgateway # 標簽可以是一個或多個
servers: # 描述對應的envoy的lintener的配置。
- port: # 設置envoy lintener
number: 90 # 端口號 (Required)
targetPort: # 可選 (Optional)
name: envoy_end # 分配給端口的標簽。
protocol: HTTP # 端口服務協議,HTTP|HTTPS|GRPC|HTTP2|MONGO|TCP|TLS
hosts: [ "*" , "text.studyenvoy.com" ] # 設置dnsName 可選的名稱空間,*|.
tls: # 與TLS相關的選項集 (Optional)
name: # 服務器的可選名稱,必須唯一 (Optional)
Gateway配置實例
基於istio Bookinfo示例的Gateway資源清單。
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:
- "*"
這里可以看到istio-ingress-gateway的pod的標簽 app=istio-ingressgateway
[root@master01 ~]# kubectl get pods -n istio-system --show-labels
NAME READY STATUS RESTARTS AGE LABELS
istio-ingressgateway-78b47bc88b-xqqpn 1/1 Running 0 22d app=istio-ingressgateway,
chart=gateways,
heritage=Tiller, install.operator.istio.io/owning-resource=unknown,
istio.io/rev=default,istio=ingressgateway,
operator.istio.io/component=IngressGateways,
pod-template-hash=78b47bc88b,
release=istio,service.istio.io/canonical-name=istio-ingressgateway,
service.istio.io/canonical-revision=latest
外部服務引入配置:ServiceEntry
在Istio中提供了ServiceEntry,可將網格外的服務加入網格中,像網格內的服務一樣進行管理。
在實現上就是把外部服務加入 Istio 的服務發現,這些外部服務因為各種原因不能被直接注冊到網格中。
ServiceEntry字段說明
- host:與ServiceEntry關聯的主機
- addresses:與服務關聯的虛擬IP地址。
- ports:
- number:服務的端口。
- protocol:服務公開的協議。HTTP|HTTPS|GRPC|HTTP2|MONGO|TCP| TLS之一。
- targetPort:目標端口號。
- location:
MESH_EXTERNAL
|MESH_INTERNAL
,決定是網格內部還是外部。 - resolution:服務發現機制。
- NONE:
- STATIC:指定靜態IP地址。
- DNS:通過DNS發現。
- endpoints:服務關聯的端點,
workloadSelector
與endpoints
二選一。 - exportTo:共享其他名稱空間
- subjectAltNames:如指定,將驗證服務器證書的使用者備用名稱是否與指定值之一匹配。
使用istio ingress gateway 配置一個網格外部的應用
部署應用程序
准備一個后端的應用
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpend-deply
namespace: kube-system
labels:
app: httpend-deply
spec:
replicas: 1
selector:
matchLabels:
app: httpend-deply
template:
metadata:
namespace: kube-system
name: httpend-deply
labels:
app: httpend-deply
spec:
containers:
- name: envoy-end
image: sealloong/envoy-end
imagePullPolicy: IfNotPresent
livenessProbe:
initialDelaySeconds: 3 # 首次探測延遲時間
periodSeconds: 2 # 定期重試
failureThreshold: 1 # 失敗重試次數
httpGet:
port: 90
path: ping
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: envoy-end
labels:
app: envoy-end
namespace: kube-system
spec:
type: NodePort # nodeport是為了驗證服務是否正常
ports:
- port: 90
name: envoy-end
targetPort: 90
nodePort: 30102
selector:
app: httpend-deply
應用Gateway和VirtualServices
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: envoyend-gateway
namespace: kube-system
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 1090
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: envoy-end
namespace: kube-system
spec:
hosts:
- "*"
gateways:
- envoyend-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
host: envoy-end
port:
number: 1090
應用DestinationRule
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: envoy-end
namespace: kube-system
spec:
host: envoy-end
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
應用ServiceEntry
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: envoy-end
namespace: kube-system
spec:
hosts:
- "envoy-end"
ports:
- number: 90
name: http
protocol: HTTP
location: MESH_EXTERNAL
resolution: DNS