K8s相關資料可參考鏈接: Kubernetes簡介
1 什么是Service Mesh
Service Mesh 是一個專門處理服務通訊的基礎設施層。它的職責是在由雲原生應用組成服務的復雜拓撲結構下進行可靠的請求傳送。在實踐中,它是一組和應用服務部署在一起的輕量級的網絡代理,並且對應用服務透明。
以上這段話有四個關鍵點:
- 本質:基礎設施層。
- 功能:請求分發。
- 部署形式:網絡代理。
- 特點:透明。
下圖是Service Mesh整體架構圖。整個系統分為控制平面(上面深藍色框)和數據平面(下面所有的虛線框)。
圖中每個虛線框代表一個節點(相當於kubernetes中的worker node),綠色的APP是在節點中運行的各類應用程序,淺藍色的Sidecar相當於是一個網絡通信的代理,每個節點需要與外界通信,都是通過這個代理完成的。控制平面通過xDS協議把配置信息下發給Sidecar,這些配置信息包括節點的路由信息,需要監聽的端口等。
2 Istio
Service Mesh是一種理念,而Istio則是這種理念的一個具體實現方案。
Istio 提供了一個完整的解決方案,可以以統一的方式去管理和監測你的微服務應用。同時,它還具有管理流量、實施訪問策略、收集數據等方面的能力,而所有的這些都對應用透明,幾乎不需要修改業務代碼就能實現。
下圖是Istio的架構圖,也分為控制平面和數據平面,控制平面實現配置的下發,安全認證,流量監控等功能。數據平面是承載服務的主題,即Kubernetes中的worker node。圖中的Proxy即是Service Mesh中的Sidecar,負責節點流量的轉發。在Istio官方使用的Proxy是Envoy。而MOSN是阿里開發的一個開源的Proxy。(MOSN的相關知識可參考官網文檔https://mosn.io/docs/)
Istio 流量管理的核心組件就是 Pilot。Pilot 主要功能就是管理和配置部署在特定 Istio 服務網格中的所有 sidecar 代理實例。它管理 sidecar 代理之間的路由流量規則,並配置故障恢復功能,如超時、重試和熔斷。
當在Kubernetes中使用Istio的時候,其作用主要有如下幾點:
- 監控服務注冊中心(如 Kubernetes)的服務注冊情況。在 Kubernetes 環境下,會監控 service、endpoint、pod、node 等資源信息。
- 監控 Istio 控制面信息變化,在 Kubernetes 環境下,會監控包括 RouteRule、 VirtualService、Gateway、EgressRule、ServiceEntry 等以 Kubernetes CRD(K8s自定義資源) 形式存在的 Istio 控制面配置信息。
- 將上述兩類信息合並組合為 sidecar 可以理解的(遵循 Envoy data plane api 的)配置信息,並將這些信息以 gRPC 協議提供給 sidecar。
由以上幾點看出,pilot起到了連接Kubernetes和數據平面的作用,它將由kubernetes產生的配置信息轉化成數據平面可以識別的格式然后下發給數據平面。
3 資源
Service、Gateway、Virtualservice、destinationrule 資源之間的關系 如下圖
3.1 Service
metadata.name:給服務命名,該名稱在命名空間內唯一,用於標識該服務。
spec.ports.name:給服務使用的端口命名。
spec.ports.port:外部訪問該服務時使用的端口。
spec.ports.protocol:該服務的協議。
spec.ports.targetPort:提供服務的pod實際使用的端口。
spec.selector:選擇具有指定標簽的pod作為提供服務的實體。
spec.type:類型被指定為ClusterIP后,系統會自動為該服務分配一個IP地址,該IP地址可用於對該服務進行訪問,該IP地址是一個虛擬的IP,沒有承載實體,也就是說該IP不能ping通,只有結合該服務的端口使用。
apiVersion: v1 kind: Service metadata: labels: XXXX:XXX name: test-cdn-svc-cm-agent-1 namespace: test spec: ports: - name: test-agent port: 3400 protocol: TCP targetPort: 3400 selector: XXXX:XXX sessionAffinity: None type: ClusterIP status: loadBalancer: {}
3.2 Gateway
Gateway相關字段說明:
spec.selector:指定執行該gateway定義的路由規則的pod。即該gateway定義的規則會下發到具有這些標簽的pod上去。
spec.servers.hosts:gateway指向的服務的域名,*號表示任意域名都滿足要求。
spec.servers.port:指定gateway需要監聽的端口名稱,端口號,協議。
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: labels: XXX: XXX name: test-http-gateway-1 namespace: test-node spec: selector: XXXX:XXX servers: - hosts: - '*' port: name: test1httpListener number: 13401 protocol: HTTP
3.3 Virtualservice
Virtualservice相關字段說明:
spec.gateways:virtualservice必須關聯gateway來使用,此處指定關聯的gateway。(Istio官方規定virtualservice可關聯gateway使用,也可以不關聯gateway)
spec.http:是一個具體的路由項,這里的意識是當前綴匹配到“/”時(即任意前綴),指定路由目的地址為test-1-http.test-node.svc.cluster.local,端口為3401。timeout表示連接超時時間。
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: labels: XXX:XXX name: test-cdn-http-vs-1 namespace: test-node spec: gateways: - test-http-gateway-1 hosts: - '*' http: - match: - uri: prefix: / route: - destination: host: test-1-http.test-node.svc.cluster.local port: number: 3401 timeout: 4s
關於gateway和virtualservice的說明:
gateway和virtualservice都是在Istio中定義的資源,Kubernetes中沒有這個資源。
從它們的關系圖中可知,gateway是把流量引進來,然后流量具體要交個哪個服務處理是由virtualservice決定的
3.4 DestinationRule
destinationrule可以將流量進行更加細化的區分,比如可以根據同一個服務的不同版本來決定流量的轉發。destinationrule可以用於實現金絲雀發布,灰度發布等功能,具體字段如下:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: bookinfo-ratings spec: # 含義同VirtualService中destination的host字段一致。 host: ratings.prod.svc.cluster.local # 流量策略,包括負載均衡、連接池策略、異常點檢查等 trafficPolicy: # 負載均衡策略,支持隨機負載均衡 /按權重負載均衡 /最少請求負載均衡 / hash輪訓等 loadBalancer: simple: CONSISTENT_DST #simple: ROUND_ROBIN #simple: LEAST_CONN #simple: RANDOM #simple: PASSTHROUGH # 連接池策略 connectionPool: # tcp連接池設置 tcp: maxConnections: 100 connectTimeout: 30ms tcpKeepalive: time: 7200s interval: 75s http: http2MaxRequests: 1000 maxRequestsPerConnection: 10 # 異常點檢查 outlierDetection: consecutiveErrors: 7 interval: 5m baseEjectionTime: 15m # tls設置 tls: mode: MUTUAL clientCertificate: /etc/certs/myclientcert.pem privateKey: /etc/certs/client_private_key.pem caCertificates: /etc/certs/rootcacerts.pem # 服務端點集合 subsets: # subset名稱可以用於路由規則中的流量拆分,與virtualService的subset的引用 - name: testversion # 使用標簽對服務注冊表中的服務端點進行篩選 labels: version: v3 trafficPolicy: loadBalancer: simple: ROUND_ROBIN
https://martinfowler.com/articles/microservices.html