istio流量管理:非侵入式流量治理


在服務治理中,流量管理是一個廣泛的話題,一般情況下,常用的包括:

  • 動態修改服務訪問的負載均衡策略,比如根據某個請求特征做會話保持;
  • 同一個服務有多版本管理,將一部分流量切到某個版本上;
  • 對服務進行保護,例如限制並發連接數、限制請求數、隔離故障服務實例等;
  • 動態修改服務中的內容,或者模擬一個服務運行故障等。

  在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 WorkloadGroupreference 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:可選,公開服務的端口
      • weight:轉發流量的比例0-100 ,各目標的和應為100。
      • headers:操作頭規則。
    • redirect:重定向規則
    • delegate:只能在RouteRedirect為空時設置,委托的VirtualServices 名稱
    • rewrite:重寫HTTP URI。
    • timeout:HTTP請求超時,默認禁用。
    • retries:HTTP請求重試策略。
    • fault:故障注入
    • mirror:流量鏡像
    • mirrorPercentage:對應mirror的比例
    • headers:操作http頭的規則
    • ...
  • 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
    • connectionPool:一致性hash
    • outlierDetection:離群值檢測
      • consecutiveGatewayErrors:滿足502 503 504 錯誤數彈出。
      • consecutive5xxErrors: 滿足5xx錯誤數彈出。
      • interval:探測時間間隔
      • baseEjectionTime:最小逐出時間。主機被驅逐的時間等於baseEjectionTime * 退出次數。
      • maxEjectionPercent:最大驅逐比例,默認10%。
      • minHealthPercent:最少健康比例,默認為0%
    • tls
    • portLevelSettings
  • 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 GatewayGateway 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:服務關聯的端點,workloadSelectorendpoints 二選一。
  • 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM