從微服務到雲原生---入門
[TOC]
微服務
微服務架構(Microservice Architecture)是一種架構概念,旨在通過將功能分解到各個離散的服務中以實現對解決方案的解耦。
微服務是一種架構風格,一個大型複雜軟體應用由一個或多個微服務組成。系統中的各個微服務可被獨立部署,各個微服務之間是鬆耦合的。每個微服務僅關注於完成一件任務並很好地完成該任務。在所有情況下,每個任務代表著一個小的業務能力。
架構演進
微服務架構區別於傳統的單體軟體架構,是一種為了適應當前網際網路後臺服務的「三高需求:高併發、高效能、高可用」而產生的的軟體架構。
單體架構
單體應用程式的優點
- 開發簡單,功能都在單個程式內部,便於軟體設計和開發規劃。
- 容易部署,程式單一不存在分散式叢集的複雜部署環境,降低了部署難度。
- 容易測試,沒有各種複雜的服務呼叫關係,都是內部呼叫方便測試。
- 高效通訊,程式間可直接呼叫,通訊成本低。
單體應用程式的缺點
- 開發效率低:所有的開發在一個專案改程式碼,遞交程式碼相互等待,程式碼衝突不斷。
- 程式碼維護難:程式碼功能耦合在一起,依賴程度過高,新人不知道何從下手,牽一髮而動全身。
- 部署不靈活:構建時間長,任何小修改必須重新構建整個專案,這個過程往往很長。
- 穩定性不高:一個微不足道的小問題,可以導致整個應用掛掉。
- 擴充套件性不夠:無法滿足高併發情況下的業務需求。
微服務架構
2014年,Martin Fowler 與 James Lewis 共同提出了微服務的概念,定義了微服務是由以單一應用程式構成的小服務,自己擁有自己的行程與輕量化處理,服務依業務功能設計,以全自動的方式部署,與其他服務使用 API 通訊。同時服務會使用最小的規模的集中管理能力,服務可以用不同的程式語言與資料庫等元件實現 。「維基百科」
鑑於「單體應用程式」有上述的缺點,單個應用程式被劃分成各種小的、互相連線的微服務,一個微服務完成一個比較單一的功能,相互之間保持獨立和解耦合,這就是微服務架構。
微服務架構的優點
- 程式碼解耦易維護:每個服務獨立開發,只專注做一件事,邏輯清晰,新人容易上手。獨立應用更易優化,
- 多團隊協作開發:每個服務都能夠由專注於該服務的團隊獨立開發。開發人員可以自由選擇任何有用的技術,只要該服務符合API要求。
- 獨立按需擴充套件:每個服務都可以獨立部署,獨立調整資源。可以僅部署滿足其容量和可用性限制的服務的例項數。此外,可以使用最符合服務資源要求的硬體。
- 獨立執行穩定:每個服務獨立執行,發生故障影響面可控,不會導致整個系統down掉。
微服務架構的缺點
- 應用間通過網路呼叫,通訊成本高,通訊效率降低。網路間呼叫容易出現問題,失敗機率增大。應用規模變大後,服務治理難度增大。
- 系統整體架構及呼叫關係複雜,開發人員對整個系統瞭解會有侷限。
- 應用間呼叫會產生分散式事務,業務實現難度更大,對開發人員要求更高。
微服務現狀
為了解決上面微服務架構缺點「服務治理」就出現了。出現了眾多的元件,如:服務註冊、配置中心、服務監控、服務容錯(降級、熔斷、限流、超時、重試)等。幸好,有巨人的肩膀可以借給我們站上去,通過引入「微服務框架」來幫助我們完成服務治理。
SpringCloud
Dubbo
阿里巴巴公司開源的一個Java高效能優秀的服務框架,使得應用可通過高效能的 RPC 實現服務的輸出和輸入功能,可以和 Spring框架無縫整合。 Apache Dubbo |ˈdʌbəʊ| 是一款高效能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向介面的遠端方法呼叫,智慧容錯和負載均衡,以及服務自動註冊和發現 。2011 年末對外開源,僅支援 Java 語言。
下一代微服務
在微服務架構下,基礎架構團隊一般會為應用提供一個封裝了各種服務治理能力的 SDK,這種做法雖然保障了應用的正常執行,但缺點也非常明顯,每次基礎架構團隊迭代一個新功能都需要業務方參與升級才能使用,尤其是 bugfix 版本,往往需要強推業務方升級,這裡面的痛苦程度每一個基礎架構團隊成員都深有體會。
隨之而來的就是應用使用的 SDK 版本差別非常大,生產環境同時跑著各種版本的 SDK,這種現象又會讓新功能的迭代必須考慮各種相容,就好像帶著枷鎖前進一般,這樣隨著不斷迭代,會讓程式碼維護非常困難,有些祖傳邏輯更是一不小心就會掉坑裡。
同時這種 “重” SDK 的開發模式,導致異構語言的治理能力非常薄弱,如果想為各種程式語言都提供一個功能完整且能持續迭代的 SDK 其中的成本可想而知。
2018 年的時候,Service Mesh 在國內持續火爆,這種架構理念旨在把服務治理能力跟業務解耦,讓兩者通過程式級別的通訊方式進行互動。在這種架構模式下,服務治理能力從應用中剝離,執行在獨立的程式中,迭代升級跟業務程式無關,這就可以讓各種服務治理能力快速迭代,並且由於升級成本低,因此每個版本都可以全部升級,解決了歷史包袱問題,同時 SDK 變 “輕” 直接降低了異構語言的治理門檻,再也不用為需要給各個語言開發相同服務治理能力的 SDK 頭疼了。
Service Mesh(服務網格)被認為是下一代微服務架構,Service Mesh並沒有給我們帶來新的功能,它是用於解決其他工具已經解決過的服務網路呼叫、限流、熔斷和監控等問題,只不過這次是在Cloud Native 的 kubernetes 環境下的實現。
Service Mesh 有如下幾個特點:
- 應用程式間通訊的中間層
- 輕量級網路代理
- 應用程式無感知
- 解耦應用程式的重試/超時、監控、追蹤和服務發現
目前幾款流行的 Service Mesh 開源軟體 Istio) 、 Linkerd)和MOSN都可以直接在kubernetes 中整合,其中Linkerd已經成為雲原生計算基金會 CNCF (Cloud Native Computing Foundation) 成員。
Service Mesh之於微服務,就像TCP/IP之於網際網路,TCP/IP為網路通訊提供了面向連線的、可靠的、基於位元組流的基礎通訊功能,你不再需要關心底層的重傳、校驗、流量控制、擁塞控制。
雲原生
雲原生是一種構建和執行應用程式的方法,是一套技術體系和方法論。雲原生(CloudNative)是一個組合詞,Cloud+Native。Cloud表示應用程式位於雲中,而不是傳統的資料中心;
Native表示應用程式從設計之初即考慮到雲的環境,原生為雲而設計,在雲上以最佳姿勢執行,充分利用和發揮雲平臺的彈性+分散式優勢。Pivotal公司的Matt Stine於2013年首次提出雲原生(CloudNative)的概念;
雲原生架構總結為:微服務+容器化+DevOps+持續交付。CNCF,全稱為Cloud Native Computing Foundation,中文譯為“雲原生計算基金會”。
容器技術(Docker)
簡介
2010年一位年輕小夥子在美國舊金山成立了一家名叫【dotCloud】的公司, 開發了 Docker的核心技術,從此開啟了容器技術的時代。
Docker是一個基於LXC的高階容器引擎。簡單地說,docker是一個輕量級的虛擬化解決方案,或者說它是一個超輕量級的虛擬機器(容器)。
Docker是一個開源的引擎,可以輕鬆的為任何應用建立一個輕量級的、可移植的、自給自足的容器。當前應用的執行時也從物理機時代、虛擬機器時代向容器化時代演進。
Docker入門請讀:https://segmentfault.com/a/1190000016749553
理念
Docker 的理念為“Build, Ship and Run Any App, Anywhere”
架構
容器化解決了軟體開發過程中一個令人非常頭疼的問題,用一段對話描述:
測試人員:你這個功能有問題。
開發人員:我本地是好的啊。
開發人員編寫程式碼,在自己本地環境測試完成後,將程式碼部署到測試或生產環境中,經常會遇到各種各樣的問題。明明本地完美執行的程式碼為什麼部署後出現很多 bug,原因有很多:不同的作業系統、不同的依賴庫等,總結一句話就是因為本地環境和遠端環境不一致。
容器化技術正好解決了這一關鍵問題,它將軟體程式和執行的基礎環境分開。開發人員編碼完成後將程式打包到一個容器映象中,映象中詳細列出了所依賴的環境,在不同的容器中執行標準化的映象,從根本上解決了環境不一致的問題。
問題與挑戰
在業務發展初期只有幾個微服務,這時用 Docker 就足夠了,但隨著業務規模逐漸擴大,容器越來越多,運維人員的工作越來越複雜,這個時候就需要編排系統解救運維同學。儘管Docker為容器化的應用程式提供了開放標準,但隨著容器越來越多出現了一系列新問題:
- 如何管理、協調和排程這些容器?
- 如何在升級應用程式時不會中斷服務?
- 如何監視應用程式的執行狀況?
- 如何批量重新啟動容器裡的程式?
為解決這些問題出現了很很多容器編排技術,現在業界比較流行的有:K8S、Mesos、Docker Swarm。
一個成熟的容器編排系統需要具備以下能力:
- 處理大量的容器
- 服務註冊發現、負載均衡
- 鑑權和安全性
- 管理服務通訊
- 多平臺部署
容器編排(K8S)
簡介
Kubernetes 是用於自動部署,擴充套件和管理容器化應用程式的開源系統。
K8S(Kubernetes)是Google研發的容器協調器,已捐贈給CNCF,現已開源。脫胎於Google內部久負盛名的大規模叢集管理系統Borg,是Google在容器化基礎設施領域十餘年實踐經驗的沉澱和昇華。
採用了非常優雅的軟體工程設計和開源開放的態度,使得使用者可以根據自己的使用場景、通過靈活插拔的方式,採用自定義的網路、儲存、排程、監控、日誌等模組。
Kubernetes在容器編排領域已經成為無可爭辯的事實標準。
理念
自動化的容器部署、擴充套件和管理
架構
在K8S中,由Master控制節點和Worker節點共同構成一個叢集,如下圖所示:
Master
用於管理、監控K8S叢集的節點,包含如下元件
- etcd:分散式KV資料庫,使用Raft協議,用於儲存叢集中的相關資料,專案地址:https://github.com/etcd-io/etcd
- API Server:叢集統一入口,以restful風格進行操作,同時交給etcd儲存(是唯一能訪問etcd的元件);提供認證、授權、訪問控制、API註冊和發現等機制,可以通過kubectl命令列工具,dashboard視覺化皮膚,或者sdk等訪問
- Scheduler:節點的排程,選擇node節點應用部署
- Controller Manager:處理叢集中常規後臺任務,一個資源對應一個控制器,同時監控叢集的狀態,確保實際狀態和最終狀態一致
Worker(Node)
用於執行應用的節點,包含元件如下:
- kubelet:相當於Master派到node節點代表,管理本機容器,上報資料給API Server
- Container Runtime:容器執行時,K8S支援多個容器執行環境:Docker、Containerd、CRI-O、Rktlet以及任何實現Kubernetes CRI (容器執行環境介面) 的軟體
- kube-proxy:實現服務(Service)抽象元件,遮蔽PodIP的變化和負載均衡
核心功能
K8S 提供功能如下:
服務發現和負載均衡
Kubernetes 可以使用 DNS 名稱或自己的 IP 地址公開容器,如果進入容器的流量很大, Kubernetes 可以負載均衡並分配網路流量,從而使部署穩定。
儲存編排
Kubernetes 允許你自動掛載你選擇的儲存系統,例如本地儲存、公共雲提供商等。
自動部署和回滾
你可以使用 Kubernetes 描述已部署容器的所需狀態,它可以以受控的速率將實際狀態 更改為期望狀態。例如,你可以自動化 Kubernetes 來為你的部署建立新容器, 刪除現有容器並將它們的所有資源用於新容器。
自動完成裝箱計算
Kubernetes 允許你指定每個容器所需 CPU 和記憶體(RAM)。 當容器指定了資源請求時,Kubernetes 可以做出更好的決策來管理容器的資源。
自我修復
Kubernetes 重新啟動失敗的容器、替換容器、殺死不響應使用者定義的 執行狀況檢查的容器,並且在準備好服務之前不將其通告給客戶端。
金鑰與配置管理
Kubernetes 允許你儲存和管理敏感資訊,例如密碼、OAuth 令牌和 ssh 金鑰。 你可以在不重建容器映象的情況下部署和更新金鑰和應用程式配置,也無需在堆疊配置中暴露金鑰。
核心概念
Pod
Pod本意是豌豆莢的意思,此處指的是K8S中資源排程的最小單位,豌豆莢裡面的小豆子就像是Container,豌豆莢本身就像是一個Pod
- Pod是最小排程單元
- Pod裡面會包含一個或多個容器(Container)
- Pod內的容器共享儲存及網路,可通過localhost通訊
Deployment
Deployment 是在 Pod 這個抽象上更為上層的一個抽象,它可以定義一組 Pod 的副本數目、以及這個 Pod 的版本。一般大家用 Deployment 這個抽象來做應用的真正的管理,而 Pod 是組成 Deployment 最小的單元。
- 定義一組Pod的副本數量,版本等
- 通過控制器維護Pod的數目
- 自動恢復失敗的Pod
- 通過控制器以指定的策略控制版本
Service
Pod是不穩定的,IP是會變化的,所以需要一層抽象來遮蔽這種變化,這層抽象叫做Service
- 提供訪問一個或者多個Pod例項穩定的訪問地址
- 支援多種訪問方式ClusterIP(對叢集內部訪問)NodePort(對叢集外部訪問)LoadBalancer(叢集外部負載均衡)
Service的工作方式:
不論哪種,kube-proxy都通過watch的方式監控著kube-APIServer寫入etcd中關於Pod的最新狀態資訊,它一旦檢查到一個Pod資源被刪除了 或 新建,它將立即將這些變化,反應再iptables 或 ipvs規則中,以便iptables和ipvs在排程Clinet Pod請求到Server Pod時,不會出現Server Pod不存在的情況。
userspace
Client Pod要訪問Server Pod時,它先將請求發給本機核心空間中的service規則,由它再將請求,轉給監聽在指定套接字上的kube-proxy,kube-proxy處理完請求,並分發請求到指定Server Pod後,再將請求遞交給核心空間中的service,由service將請求轉給指定的Server Pod。由於其需要來回在使用者空間和核心空間互動通訊,因此效率很差。
iptables
此工作方式是直接由核心中的iptables規則,接受Client Pod的請求,並處理完成後,直接轉發給指定ServerPod。
ipvs
它是直接有核心中的ipvs規則來接受Client Pod請求,並處理該請求,再有核心封包後,直接發給指定的Server Pod。
Volume
Volume就是儲存卷,在Pod中可以宣告捲來問訪問檔案系統,同時Volume也是一個抽象層,其具體的後端儲存可以是本地儲存、NFS網路儲存、雲端儲存(阿里雲盤、AWS雲盤、Google雲盤等)、分散式儲存(比如說像 ceph、GlusterFS )
- 宣告在Pod中容器可以訪問的檔案系統。
- 可以被掛載在Pod中一個或多個容器的指定路徑下。
- 支援多種後端儲存,如NAS等。
Ingress
Ingress 公開了從叢集外部到叢集內服務的 HTTP 和 HTTPS 路由。對叢集中服務的外部訪問進行管理的 API 物件,典型的訪問方式是 HTTP。
Ingress 可以提供負載均衡、SSL 終結和基於名稱的虛擬託管。
下面是一個將所有流量都傳送到同一 Service 的簡單 Ingress 示例:
Namespace
Namespace(命令空間)是用來做資源的邏輯隔離的,比如上面的Pod、Deployment、Service都屬於資源,不同Namespace下資源可以重名。同一Namespace下資源名需唯一
- 一個叢集內部的邏輯隔離機制(鑑權、資源等)
- 每個資源都屬於一個Namespace
- 同一個Namespace中資源命名唯一
- 不同Namespace中資源可重名
問題與挑戰
- 隨著業務的不斷髮展,微服務的數量越來越多,微服務間的通訊網路也變得十分複雜,微服務間的通訊拓撲構成了一個巨大複雜的網路,治理難度加大。
- 對於流量管控功能較弱,服務間訪問的管理如服務的熔斷、限流、動態路由、呼叫鏈追蹤等都不在K8S的範圍。
- 使用門檻高,由於框架元件多,對於業務開發人員,就需要掌握較多非業務的知識,增加了業務開發人員的挑戰。
- 跨語言是微服務的優勢之一,它可以讓不同語言編寫的服務通過暴露介面服務呼叫的方式開放能力。而使用類庫的微服務,將被類庫支援的語言限制。
服務網格(Istio)
簡介
現代應用程式通常被設計成微服務的分散式集合,每個服務執行一些離散的業務功能。服務網格是專門的基礎設施層,包含了組成這類體系結構的微服務網路。 服務網格不僅描述了這個網路,而且還描述了分散式應用程式元件之間的互動。所有在服務之間傳遞的資料都由服務網格控制和路由。
隨著分散式服務的部署——比如基於 Kubernetes 的系統——規模和複雜性的增長,它可能會變得更加難以理解和管理。需求可以包括發現、負載平衡、故障恢復、度量和監視。微服務體系結構通常還有更復雜的操作需求,比如 A/B 測試、canary 部署、速率限制、訪問控制、加密和端到端身份驗證。
服務到服務的通訊使分散式應用成為可能。在應用程式叢集內部和跨應用程式叢集路由這種通訊變得越來越複雜。 Istio 有助於減少這種複雜性,同時減輕開發團隊的壓力。
Istio簡介
Istio 是一個開源服務網格,它透明地分層到現有的分散式應用程式上。 Istio 強大的特性提供了一種統一和更有效的方式來保護、連線和監視服務。 Istio 是實現負載平衡、服務到服務身份驗證和監視的路徑——只需要很少或不需要更改服務程式碼。它強大的控制平面帶來了重要的特點,包括:
- 使用 TLS 加密、強身份認證和授權的叢集內服務到服務的安全通訊
- 自動負載均衡的 HTTP, gRPC, WebSocket,和 TCP 流量
- 通過豐富的路由規則、重試、故障轉移和故障注入對流量行為進行細粒度控制
- 一個可插入的策略層和配置 API,支援訪問控制、速率限制和配額
- 對叢集內的所有流量(包括叢集入口和出口)進行自動度量、日誌和跟蹤
Istio為微服務應用提供了一個完整的解決方案,可以以統一的方式去檢測和管理微服務。同時,它還提供了管理流量、實施訪問策略、收集資料等功能,而所有這些功能都對業務程式碼透明,即不需要修改業務程式碼就能實現。
有了Istio,就幾乎可以不需要其他的微服務框架,也不需要自己去實現服務治理等功能,只要把網路層委託給Istio,它就能幫助完成這一系列的功能。簡單來說,Istio就是一個提供了服務治理能力的服務網格,是Kubernetes的好幫手。
Istio的多樣化特性可以讓你高效地執行分散式微服務架構,並提供一種統一的方式來保護、連線和監控微服務。
理念
連線、安全、控制和可觀測服務
Service Mesh 是微服務時代的 TCP/IP 協議。
架構
Istio的架構從邏輯上分成資料平面(Data Plane)和控制平面(Control Plane),Kubernetes的架構也具有相似的結構,分為控制節點和計算節點。毫無疑問,這樣的設計可以很好地解耦各個功能元件。
- 資料平面:由一組和業務服務成對出現的Sidecar代理(Envoy)構成,它的主要功能是接管服務的進出流量,傳遞並控制服務和Mixer元件的所有網路通訊(Mixer是一個策略和遙測資料的收集器,稍後會介紹)。
- 控制平面:主要包括了Pilot、Mixer、Citadel和Galley共4個元件,主要功能是通過配置和管理Sidecar代理來進行流量控制,並配置Mixer去執行策略和收集遙測資料(Telemetry)。
Istio的網路
核心功能
類別 | 功能 | 說明 |
---|---|---|
流量管理 | 請求路由 | A/B測試、金絲雀釋出等,包括對叢集出入口、及叢集內部的流量的控制。比如某應用新版本釋出,可以配置為5%的流量流向新版本,95%的給舊版本 |
流量轉移 | 與上一條請求路由類似,可以平滑的將流量從舊版本轉移到新版本上 | |
負載均衡 | 目前支援3種方式,輪詢、隨機和帶權重的最少請求 | |
服務發現 | 帶心跳的健康檢查,失敗率超標的Pod移出負載均衡池 | |
故障處理 | 超時、重發、熔斷、上游併發請求或下游連線數限制等 | |
微調 | 支援用特殊的請求頭引數,覆蓋預設的超時、重發值 | |
故障注入 | 由Enovy在正常的叢集中人為注入故障,比如TCP包損壞或延遲、HTTP錯誤碼等,支援按百分比注入,比如給10%的流向服務A的請求包增加5秒延遲 | |
多重匹配 | 上述規則的配置,支援按多種條件匹配,且支援and或or的方式匹配多條規則 | |
Gateway | 接管叢集入口的流量,替代了Ingress,從而對入口流量執行其他規則 | |
Service Entry | 接管叢集內部訪問外部服務的流量,從而對出口流量執行一些規則 | |
映象 | 支援將特定的流量映象到服務路徑之外,而不影響主服務路徑的正常執行 | |
安全 | 名稱空間訪問控制 | 支援配置某名稱空間的所有或個別服務可以被其他名稱空間訪問 |
服務級別訪問控制 | 允許或禁止訪問某個服務 | |
雙向TLS | HTTPS加密傳輸 | |
其他安全策略 | ||
策略 | 速率限制 | 比如限制每秒的請求次數 |
黑白名單 | 支援基於IP或屬性的黑名單、白名單 | |
遙測 | 日誌收集 | 支援將Prometheus、Jaeger等系統插入Mixer,從而完成資料的採集 |
指標採集 | ||
分散式追蹤 |
流量治理
Istio的流量管理是通過Pilot和Envoy這兩個元件實現的,將流量和基礎設施進行了解耦。Pilot負責配置規則,並把規則分發到Envoy代理去實施;而Envoy按照規則執行各種流量管理的功能,比如動態請求路由,超時、重試和熔斷,還可以通過故障注入來測試服務之間的容錯能力。下面對這些具體的功能進行逐一介紹。
路由
不同需求開發在測試、釋出階段往往需要將特殊 pod 與基準服務 pod 進行聯合除錯,通過 virtual rule 和 destination rule 的配置規則,可以精確的將特性流量轉到不同的微服務的指定特性 pod 上。
通過 istio 可以快速構建下圖所示的基準環境、分支特性環境的通訊過程,適應業務的需要。將請求動態路由到微服務的多個版本。
超時
可使用 Istio 在 Envoy 中設定請求超時時間,方便的控制應用間呼叫的超時時間。
重試
可設定請求重試次數與重試間隔時間,方便恢復服務。
熔斷
熔斷,是建立彈性微服務應用程式的重要模式。熔斷能夠使您的應用程式具備應對來自故障、潛在峰值和其他未知網路因素影響的能力。
流量映象
流量映象,也稱為影子流量,映象會將實時流量的副本傳送到映象服務。映象流量發生在主服務的關鍵請求路徑之外。
閘道器
服務間通訊是通過Envoy代理進行的。同樣,我們也可以在整個系統的入口和出口處部署代理,使得所有流入和流出的流量都由代理進行轉發,而這兩個負責入口和出口的代理就叫作入口閘道器和出口閘道器。它們相當於整個微服務應用的邊界代理,把守著進入和流出服務網格的流量。圖2-6展示了Ingress和Egress在請求流中的位置,通過設定Envoy代理,出入服務網格的流量也得到了控制。
入口閘道器(Ingress)
除了支援 Kubernetes Ingress,Istio還提供了另一種配置模式,Istio Gateway。與 Ingress
相比,Gateway
提供了更簡單方便的自定義性和靈活性,並允許將 Istio 功能(例如監控和路由規則)應用於進入叢集的流量。
出口閘道器(Egress)
由於預設情況下,來自Pod 的所有出站流量都會重定向到其 Sidecar 代理,叢集外部 URL 的可訪問性取決於代理的配置。預設情況下,Istio 將 Envoy 代理配置為允許訪問未知服務的請求。儘管這為入門 Istio 帶來了方便,但是,通常情況下,應該配置更嚴格的控制策略來管理和管制對外訪問。
故障處理
Istio的故障處理都由Envoy代理完成。Envoy提供了一整套現成的故障處理機制,比如超時、重試、限流和熔斷等。這些功能都能夠以規則的形式進行動態配置,並且執行執行時修改。這使得服務具有更好的容錯能力和彈性,並保證服務的穩定性。
故障注入
簡單來說,故障注入就是在系統中人為地設定一些故障,來測試系統的穩定性和系統恢復的能力。比如為某服務設定一個延遲,使其長時間無響應,然後檢測呼叫方是否能處理這種超時問題而自身不受影響(如及時終止對故障發生方的呼叫,避免自己受到影響且使故障擴充套件)。
Isito支援注入兩種型別的故障:延遲和中斷。延遲是模擬網路延遲或服務過載的情況;中斷是模擬上游服務崩潰的情況,表現為HTTP的錯誤碼和TCP連線失敗。
服務管理
服務發現與負載均衡
服務發現的前提條件是具有服務註冊的能力。目前Kubernetes這類容器編排平臺也提供了服務註冊的能力。Istio基於平臺實現服務發現和負載均衡時,需要通過Pilot和Envoy協作完成,如圖2-7所示。Pilot元件會從平臺獲取服務的註冊資訊,並提供服務發現的介面,Envoy獲得這些資訊並更新到自己的負載均衡池。Envoy會定期地對池中的例項進行健康檢查,剔除離線的例項,保證服務資訊的實時性。
可觀測性
1.策略
在微服務應用中,除了流量管理以外,常常還需要進行一些額外的控制,比如限流(對呼叫頻率、速率進行限制)、設定白名單和黑名單等。
Istio中的策略控制是依靠Mixer完成的。Envoy代理在每次網路請求時,都會呼叫Mixer進行預先檢查,確定是否滿足對應的策略。同時,Mixer又可以根據這些來自流量的資料,進行指標資料的採集和彙總,這就是遙測功能。
2.遙測(Telemetry)
遙測是工業上常用的一種技術,它是指從遠端裝置中收集資料,並傳輸到接收裝置進行監測。在軟體開發中,遙測的含義引申為對各種指標(metric)資料進行收集,並監控、分析這些指標,比如我們經常聽到的BI資料分析。
Mixer的一大主要功能就是遙測。前面已經說過,Envoy代理會傳送資料給Mixer,這就使得Mixer具有了資料收集的能力。在本章2.3節對Mixer的介紹中讀者已經瞭解到Mixer的外掛模型,也就是介面卡。Mixer可以接入不同的後端設施作為介面卡,來處理收集到的指標資料,比如日誌分析系統、監控系統等。
核心元件
Envoy
Istio的核心原理,是網路代理,攔截下所有想攔截的TCP流量。通過對攔截下來的流量的解析和修改。
Envoy本質上是一個為面向服務的架構而設計的7層代理和通訊匯流排。Envoy基於C++11開發而成,效能出色。Envoy包括但不限於以下功能:
• 動態服務發現
• 負載均衡
• TLS證照解除安裝
• HTTP/2 & gRPC 代理
• 熔斷器
• 健康檢查、基於百分比流量拆分的灰度釋出
• 故障注入
• 豐富的度量指標
Pilot
Pilot是為我們提供Istio管理配置臺,如智慧路由(如A/B測試、金絲雀釋出等)、彈性(超時、重發、熔斷等)等功能的管理系統,它提供了一系列rules api,允許運維人員指定一系列高階的流量管理規則。Pilot負責將我們的配置轉換並寫入到每個sidecar(Enovy)。
簡單來說,Pilot的主要任務有兩個。
- 從平臺(如Kubernetes)獲取服務資訊,完成服務發現。
- 獲取Istio的各項配置,轉換成Envoy代理可讀的格式並分發。
Mixer
Mixer混合了各種策略以及後端資料採集或遙測系統的介面卡,從而實現了前端Proxy與後端系統的隔離與匯合。Mixer是一個靈活的外掛模型(無論是k8s還是Istio,實現上都很青睞於外掛模型,這是一個很靈活的實現方式),它一端連著Envoy,同時我們可以將日誌、監控、遙測等各種系統“插入”到Mixer的另一端中,從而得到我們想要的資料或結果。
Citadel
它管理著叢集的金鑰和證照,是叢集的安全部門。典型的如果我們的服務是跨網路通訊(Istio允許我們建立一個安全的叢集的叢集網路),開發人員想省事懶得對通訊資料進行加解密和身份認證,這事就可以交給Citadel來處理了。更詳細的說,Istio各個模組在安全性上分別扮演以下角色:
• Citadel,用於金鑰和證照管理
• Sidecar和周邊代理,實現客戶端和伺服器之間的安全通訊
• Pilot,將授權策略和安全命名資訊分發給代理
• Mixer,管理授權和審計
Galley
目前這個元件的作用是驗證使用者編寫的Istio api配置。從官網的說法來看,後面這個元件會逐步接管獲取配置、處理和分配的工作,比如從k8s的資料中心(etcd)獲取叢集資訊的活,理論上應該交給Galley。Galley的定位類似於k8s的api server元件,提供叢集內統一的配置資訊介面,從而將使用者配置的細節隔離開來。
其它元件
Kiali : 專用於 istio 系統的視覺化的APM軟體。
Jaeger: 是一個用於分散式鏈路追蹤的開源軟體,提供原生 OpenTracing
支援。
效能評估
官方給出了對最新版本V1.1.4的效能測試結果。在由1000個服務和2000個sidecar組成,每秒產生70000個網格範圍內的請求的網格中,得到以下結果:
• Envoy在每秒處理 1000 請求的情況下,使用 0.6 個 vCPU 以及 50 MB 的記憶體。
• istio-telemetry在每秒1000個網格範圍內的請求的情況下,消耗了0.6個vCPU。
• Pilot使用了 1 個 vCPU 以及 1.5 GB 的記憶體。
• Envoy在第 90 個百分位上增加了 8 毫秒的延遲。
問題與挑戰
- 底層技術門檻大大增加,需要有更專業的基礎平臺的開發和運維來維護該複雜的平臺,對人員知識量及專業度要求極高。
- 平臺層若出現問題,調查難度較大,一般業務開發對網路、儲存、安全等方面知識薄弱,好在平臺一般都會提供各種工具協助。
- 業務開發人員也需要了解容器化或服務網格相關原理,對人員技能要求較高。
下一代雲原生?
WASM
WebAssembly是一種新的編碼方式,可以在現代的網路瀏覽器中執行 ,是一個可移植、體積小、載入快並且相容 Web 的全新格式程式規範。WebAssembly 是由主流瀏覽器廠商組成的 W3C 社群團體 制定的一個新的規範。
高效:WebAssembly 有一套完整的語義,實際上 wasm 是體積小且載入快的二進位制格式, 其目標就是充分發揮硬體能力以達到原生執行效率
安全:WebAssembly 執行在一個沙箱化的執行環境中,甚至可以在現有的 JavaScript 虛擬機器中實現。在web環境中,WebAssembly將會嚴格遵守同源策略以及瀏覽器安全策略。
開放:WebAssembly 設計了一個非常規整的文字格式用來、除錯、測試、實驗、優化、學習、教學或者編寫程式。可以以這種文字格式在web頁面上檢視wasm模組的原始碼。
標準:WebAssembly 在 web 中被設計成無版本、特性可測試、向後相容的。WebAssembly 可以被 JavaScript 呼叫,進入 JavaScript 上下文,也可以像 Web API 一樣呼叫瀏覽器的功能。當然,WebAssembly 不僅可以執行在瀏覽器上,也可以執行在非web環境下。
Serverless
2019 年,Serverless 被 Gartner 稱為最有潛力的雲端計算技術發展方向,並被賦予是必然性的發展趨勢。從行業趨勢看,Serverless 是雲端計算必經的一場革命。
Serverless ,被稱為無伺服器,可以解讀為一種軟體系統架構方法,通常稱為 Serverless 架構。代表的是無需理解、管理伺服器,按需使用,按使用付費的產品。Serverless 產品中,其中可以包含儲存、計算等多種型別的產品,而典型的計算產品,就是雲函式這種形態。
- 免運維:不需要管理伺服器主機或者伺服器程式。
- 彈性伸縮:根據負載進行自動規模伸縮與自動配置。伸縮範圍零到無窮大。
- 按需付費:根據使用情況決定實際成本。
- 高可用:具備隱含的高可用性。
分散式應用執行時(Dapr)
Dapr 是 Distributed Application Runtime (分散式應用執行時)的縮寫。是一種可移植的,事件驅動的執行時,用於構建跨雲和邊緣的分散式應用。號稱:“Any language, any framework, anywhere”