敖小劍,資深碼農,十六年軟件開發經驗,微服務專家,Service Mesh 佈道師,Servicemesher.com 社區聯合創始人。專一於基礎架構和中間件,Cloud Native 擁護者,敏捷實踐者,堅守開發一線打磨匠藝的架構師。曾在亞信、愛立信、惟品會等任職,目前就任螞蟻金服,在中間件團隊負責 Service Mesh 等產品開發。本文整理自他在 QCon 上海 2018 上的演講。
你們好,我是來自螞蟻金服中間件團隊的敖小劍,目前是螞蟻金服 Service Mesh 項目的 PD。我同時也是 Servicemesher 中國技術社區的創始人,是 Service Mesh 技術在國內最先的佈道師。
我今天給你們帶來的主題是"長路漫漫踏歌而行:螞蟻金服 Service Mesh 實踐探索"。nginx
在去年的 QCon 上海,我曾經作過一個名爲"Service Mesh:下一代微服務的演講,不知道今天現場是否有當時聽過去年這場演講的同窗?(備註:現場調查的結果,大概十幾位聽衆聽過去年的演講。)
c++
固然,今天咱們的內容不是繼續作 Service Mesh 的佈道,按秀濤(QCon 主編)的要求,今年要好好講一講實踐。因此今天我不會像去年那樣給你們詳細解釋 Service Mesh 是什麼,能作什麼,有什麼優點。而是結合過去一年中螞蟻金服的實踐經驗,結合螞蟻金服的 SOFAMesh 產品,幫助你們更深入的理解 Service Mesh 技術。git
在開始今天的內容分享以前,咱們先來熱個身,溫習一下去年的內容。去年我是來 QCon 佈道的,而佈道的核心內容就是告訴你們:Service Mesh 是什麼?
github
爲了幫忙你們回答,我給出一個提示圖片,瞭解 Service Mesh 的同窗對這張圖片應該不會陌生。編程
這裏咱們一塊兒回顧一下 Service Mesh 的正式定義:小程序
Service Mesh 是一個 基礎設施層,用於處理服務間通信。現代雲原生應用有着複雜的服務拓撲,服務網格負責在這些拓撲中 實現請求的可靠傳遞。api
在實踐中,服務網格一般實現爲一組 輕量級網絡代理,它們與應用程序部署在一塊兒,而 對應用程序透明。安全
加粗部分是重點:服務器
基礎設施層:這是 Service Mesh 的定位,今天內容的最後一個部分我會和你們詳細展開這個話題;微信
服務間通信:這是 Service Mesh 的功能和範圍;
實現請求的可靠傳遞:是 Service Mesh 的目標;
輕量級網絡代理:是 Service Mesh 的部署方式;
對應用程序透明:是 Service Mesh 的重要特性,零侵入,Service Mesh 的最大優點之一。
今天的內容會有這些:
先給你們快速介紹一下咱們的 SOFAMesh 項目,讓你們對故事的背景有個大體的瞭解;
而後給你們介紹一下爲何咱們選擇了用 Golang 語言來實現數據平面,這個是過去一年中各方對咱們產品方案最大的疑惑;
再繼續給你們分享一下過去一年中咱們在 Service Mesh 落地中遇到的典型問題和解決方案,給你們一些比較實際感覺
而後咱們將探索一下服務間通信的範圍,看看 Service Mesh 能夠在哪些領域獲得應用;
再接下來,給你們介紹一下在這一年實踐中的最大感悟,和你們聊聊基礎設施對服務網格的意義,這也是今年最想和你們分享的內容;
最後,總結一下今天的內容,分享一些信息。
OK,讓咱們開始今天的第一個部分,給你們快速介紹一下 SOFAMesh,目標在展開咱們的各類實踐和探索以前,讓你們瞭解一下背景。
SOFAMesh 是螞蟻金服推出的 Service Mesh 開源產品,你們能夠簡單的理解爲是 Istio 的落地加強版本。咱們有兩個原則:
跟隨社區
體如今 SOFAMesh 是 fork 自 Istio,並且緊跟 Istio 的最新版本,確保和上游保持同步。
咱們在 Istio 上的改動都在 SOFAMesh 項目中開源出來,並且在驗證完成後咱們也會聯繫 Istio,反哺回上游。
實踐檢驗
一切從實踐出發,不空談,在實際生產落地中,發現問題,解決問題。在解決問題的過程當中,不將就,不湊合,努力挖掘問題本質,而後追求以技術創新的方式來解決問題。
原則上:Istio 作好的地方,咱們簡單遵循,保持一致;Istio 作的很差或者疏漏的地方,咱們努力改進和彌補。
全部這一切,以 實際落地 爲出發點,同時知足將來的技術大方向。
SOFAMesh 的產品規劃,這是目前正在進行的第一階段。架構繼續延續 Istio 的數據平面和控制平面分離的方式,主要工做內容是:
用 Golang 開發 Sidecar,也就是咱們的 SOFAMosn 項目,替代 Envoy。
集成 Istio 和 SOFAMosn,同時針對落地時的需求和問題進行擴展和補充,這是咱們的 SOFAMesh 項目
在這個架構中,和 Istio 原版最大的不一樣在於咱們沒有選擇 Istio 默認集成的 Envoy,而是本身用 Golang 開發了一個名爲 SOFAMosn 的 Sidecar 來替代 Envoy。
爲何?
咱們的第二部份內容將給你們解答這個問題。
MOSN 的全稱是 "Modular Observable Smart Network",正如其名所示,這是一個模塊化可觀察的智能網絡。這個項目有很是宏大的藍圖,由螞蟻金服的系統部門和中間件部門聯手 UC 大文娛基礎架構部門推出,準備將原有的網絡和中間件方面的各類能力在 Golang 上從新沉澱,打形成爲將來新一代架構的底層平臺,承載各類服務通信的職責。
Sidecar 模式是 MOSN 目前的主要形式之一,參照 Envoy 項目的定位。咱們實現了 Envoy 的 xDS API,和 Istio 保持兼容。
在 Istio 和 Envoy 中,對通信協議的支持,主要體如今 HTTP/1.1 和 HTTP/2 上,這兩個是 Istio / Envoy 中的一等公民。而基於 HTTP/1.1 的 REST 和基於 HTTP/2 的 gRPC,一個是目前社區最主流的通信協議,一個是將來的主流,Google 的寵兒,CNCF 御用的 RPC 方案,這兩個組成了目前 Istio 和 Envoy(乃至 CNCF 全部項目)的黃金組合。
而咱們 SOFAMesh,在第一時間就遇到和 Istio/Envoy 不一樣的狀況,咱們須要支持 REST 和 gRPC 以外的衆多協議:
SOFARPC:這是螞蟻金服大量使用的 RPC 協議 (已開源);
HSF RPC:這是阿里集團內部大量使用的 RPC 協議 (未開源);
Dubbo RPC: 這是社區普遍使用的 RPC 協議 (已開源);
其餘私有協議:在過去幾個月間,咱們收到需求,指望在 SOFAMesh 上運行其餘 TCP 協議,大部分是私有協議。
爲此,咱們須要考慮在 SOFAMesh 和 SOFAMosn 中增長這些通信協議的支持,尤爲是要可讓咱們的客戶很是方便的擴展支持各類私有 TCP 協議。
爲何不直接使用 Envoy?
幾乎全部瞭解 SOFAMesh 產品的同窗,都會問到這個問題,也是 SOFAMesh 被質疑和非議最多的地方。由於目前 Envoy 的表現的確是性能優越,功能豐富,成熟穩定。
咱們在技術選型時也是重點研究過 Envoy,能夠說 Envoy 很是符合咱們的需求,除了一個地方:Envoy 是 c++。
這裏有個選擇的問題,就是數據平面應該選擇什麼樣的編程語言?
圖中列出了目前市場上主要的幾個 Service Mesh 類產品在數據平面上的編程語言選擇。
首先,基於 Java 和 Scala 的第一時間排除,實踐證實,JDK/JVM/ 字節碼這些方式在部署和運行時都顯得過重,不適合做爲 Sidecar;
Nginmesh 的作法有些獨特,經過 Golang 的 agent 獲得信息而後生成配置文件塞給 nginx,實在不是一個正統的作法;
Conduit(後改名爲 Linkerd2.0)選擇的 Rust 是個劍走偏鋒的路子,Rust 自己極其適合作數據平面,可是 Rust 語言的普及程度和社區大小是個極大的欠缺,選擇 Rust 意味着基本上沒法從社區借力;
Envoy 選擇的 c++;
國內華爲和新浪微博選擇了 Golang。
咱們在選擇以前,內部作過深刻討論,焦點在於:將來的新一代架構的底層平臺,編程語言棧應該是什麼?最終一致以爲應該是 Golang,配合部分 Java。
對於 Sidecar 這樣一個典型場景:
要求高性能,低資源消耗,有大量的併發和網絡編程;
要能被團隊快速掌握,尤爲新人能夠快速上手;
要和底層的 k8s 等基礎設施頻繁交互,將來有 Cloud Native 的大背景;
很是重要的:要能被社區和將來的潛在客戶接受和快速掌握,不至於在語言層面上有太高的門檻;
不考慮其餘因素,知足 Sidecar 場景的最理想的編程語言,天然是非 Golang 莫屬。
可是到具體的技術選型時,面對要不要使用 Envoy,決策依然是很是艱難:關鍵在於,c++ 有 Envoy 這樣成熟的產品存在,能夠直接拿來用;而 Golang 沒有能夠和 Envoy 平起平坐的產品能夠選擇,須要白手起家。
兩個選擇各有優劣,短時間看:
直接使用 Envoy,優點在於這是一個成熟項目,表現穩定,並且也是 Isto 默認的 Sidecar,自己速度快,資源消耗低。能夠直接拿來用,上手超簡單,投入少而收益快;
開發本身的 Golang 版本的 Sidecar,全是劣勢:這是一個全新項目,工做量很是大,並且技術上頗有挑戰,還有須要自行完成和 Istio 集成的額外工做量以及維護成本,最大的挑戰還在於 Envoy 豐富甚至繁多的功能,要向 Envoy 對齊須要很是大的努力。
能夠說,短時間內看,選擇 Envoy 遠比自行開發 Golang 版本要現實而明智。
可是,前面咱們有說到,對於 MOSN 項目,咱們有很是宏大的藍圖:準備將原有的網絡和中間件方面的各類能力從新沉澱和打磨,打形成爲將來新一代架構的底層平臺,承載各類服務通信的職責。這是一個須要一兩年時間打造,知足將來三五年乃至十年需求的長期規劃項目,咱們若是選擇以 Envoy 爲基礎,短時間內天然一切 OK,快速得到各類紅利,迅速站穩腳跟。
可是:後果是什麼?Envoy 是 C++ 的,選擇 Envoy 意味着咱們後面沉澱和打磨的將來通信層核心是 c++ 的,咱們的語言棧將不得不爲此修改成以 c++ 爲主,這將嚴重偏離既定的 Golang + Java 的語言棧規劃。
而一旦將時間放到三五年乃至十年八年這個長度時,選擇 Envoy 的劣勢就出來了:
C++ 帶來的開發和維護成本時遠超 Golang,時間越長,改動越多,參與人數越多,使用場景越多,差異越明顯;
從目前的需求上看,對 Envoy 的擴展會很是多,包括通信協議和功能。考慮到將來控制平面上可能出現的各類創新,必然須要數據平面作配合,改動會長期存在;
Golang 仍是更適合雲原生時代,選擇 Golang,除了作 Sidecar,鍛煉出來的團隊還能夠用 Golang 去完成其餘各類產品。固然選擇 Envoy 也能夠這麼幹,可是這樣一來之後系統中就真的都是 c++ 的產品了;
另外 Envoy 目前的官方定位只有 Sidecar 一種模式,而咱們規劃中的 MSON 項目覆蓋了各類服務通信的場景;
往後如何和 Envoy 協調是個大難題。尤爲咱們後續會有很是多的創新想法,也會允許快速試錯以鼓勵創新,選擇 Envoy 在這方面會有不少限制。
因此,最後咱們的選擇是:先難後易,着眼將來。忍痛(真的很痛)捨棄 Envoy,選擇用 Golang 努力打造咱們的 SOFAMosn 項目。
對於一樣面臨要不要選擇 Envoy 的同窗,我給出的建議是:Envoy 是否適合,取決因而不是想「動」它。
若是隻是簡單的使用,或者少許的擴展,那麼其實你接觸到的只是 Envoy 在冰山上的這一小部分,這種狀況下建議你直接選擇 Envoy;
若是你和咱們同樣,將 Service Mesh 做爲將來架構的核心,預期會有大量的改動和擴展,同時你又不肯意讓本身的主流編程語言技術棧中 c++ 佔據主流,那麼能夠參考咱們的選擇。
固然,對於本來就是以 c/c++ 爲主要編程語言棧的同窗來講,不存在這個問題。
今天的第三部分,給你們介紹一下 SOFAMesh 在落地期間遇到的典型問題。
這裏給你們列出了三個主要問題:
通信協議擴展
前面也剛談到過,就是咱們會須要支持很是多的 TCP 協議,包括各類私有協議。固然這個其實更應該歸爲需求,後面詳細展開。
平滑遷移傳統架構
所謂傳統架構指的是傳統的 SOA 架構,如基於 Dubbo 的不少現有應用,咱們但願它們可以在 Service Mesh 中直接跑起來,而沒必要必定要先進行微服務改造。
適配異構體系
異構體系指的是,當咱們進行 Service Mesh 落地時,會存在新舊兩條體系,好比說新的應用是基於 Service Mesh 開發的,而舊的應用是基於傳統框架好比說 Dubbo 或者是 Spring Cloud。
當咱們作應用遷移的時候,考慮到原來的存量應用會有不少的,好比上千個應用,這些應用確定不可能說一個晚上所有切過去。中間必然會有一個過渡階段,在這個過渡階段新舊體系中的應用應該怎麼通信,如何才能作到最理想。
咱們如今正在作方案,就是如今 POC 中。咱們如今給本身設定的目標,就是但願給出一套方案,可讓現有應用不作代碼改動,而後能夠在新舊兩邊隨便切,以保證平滑遷移。
固然這套方案如今正在作 POC,方案還未最終定型,因此今天咱們不會包含這一塊的細節。你們若是有興趣的話能夠稍後關注咱們的這個方案。
今天給你們主要分享前面兩個部分,咱們詳細展開。
第一個要解決的問題是如何快速的擴展支持一個新的通信協議。
這個問題主要源於如今 Istio 的設計,按照 Istio 如今的方式,若是要添加一個新的通信協議,是有幾大塊工做要作的:
添加協議的 Encoder 和 Decoder;
也就是協議的編解碼,這個沒得說,確定要加的;
修改 Pilot 下發 Virtual Host 等配置;
修改 Sidecar 如 Envoy,MOSN 去實現請求匹配。
後二者是大量重複的,就技術實現而言,須要修改的內容和現有的東西差很少,可是必需要再改出一份新的來。由於咱們協議比較多,由此帶來的改動量很是大。根據咱們以前的實踐,以這樣的方式加一個新的通信協議可能須要幾天的工做量,並且每次改動都重複大量代碼。
在這裏咱們最後給出了一個名爲 x-protocol 的通用解決方案,細節咱們這裏不展開,只給你們看個結果。根據咱們最新的驗證狀況,若是咱們要添加一個新的通信協議,大概就是一兩百行代碼,一兩個小時就能完成。即便加上測試,基本上也能夠控制在一天以內,咱們就可以爲 SOFOMesh 新增一個通信協議的支持。
第二個要解決的問題就是讓傳統架構的存量應用上 Service Mesh 的問題。
就是剛纔說的現有大量的基於 SOA 框架的程序,這些應用以傳統的 SOA 方式開發,若是直接挪到 Service Mesh 下,如 Istio,會遇到問題:由於 Istio 用的服務註冊是經過 k8s 來進行,而 k8s 的服務註冊模型和原有的 SOA 模型是不匹配的。
SOA 框架當中,一般是以接口爲單位來作服務註冊,也就是一個應用裏面部署多個接口的,在運行時是一個進程裏面有多個接口(或者說多個服務)。其實是以接口爲粒度,服務註冊和服務發現,包括服務的調用都是以接口爲粒度。可是有個問題,部署到 Istio 中後,Istio 作服務註冊是以服務爲粒度來作服務註冊,這個時候無論是註冊模型,仍是按接口調用的方式都不一致,就是說經過 Interface 調用是調不通的。
左邊的代碼實例,你們能夠看獲得,通常狀況下 Dubbo 程序是按照 Interface 來註冊和發現,調用時也是經過 Interface 來調用。另外,在這個地方,除了經過接口調用以外,還有另一個問題:服務註冊和服務發現的模型,從原來的一對 N,也就是一個進程 N 個接口,變成了要一對一,一個進程一個服務。
怎麼解決這個問題?最正統的作法是,是先進行 微服務改造:把原有的 SOA 的架構改爲微服務的架構,把現有應用拆分爲多個微服務應用,每一個應用裏面一個服務(或者說接口),這樣應用和服務的關係就會變成一對一,服務註冊模型就能夠匹配。
可是在執行時會有難處,由於微服務改造是一個比較耗時間的過程。咱們遇到的實際的需求是:能不能先不作微服務改造,而先上 Service Mesh ?由於 Service Mesh 的功能很是有吸引力,如流量控制,安全加密。那能不能先把應用搬遷到 Service Mesh 上來,先讓應用跑起來,後面再慢慢的來作微服務改造。
這就是咱們實際遇到的場景,咱們須要找到方案來解決問題:註冊模型不匹配,原有用接口調用的代碼調不通。
咱們設計了一個名爲 DNS 通用選址方案 的解決方案,用來支持 Dubbo 等 SOA 框架,允許經過接口名來調用服務。
細節不太適合展開,給你們介紹最基本的一點,就是說咱們會在 DNS 中增長記錄,如圖上左下角所示標紅的三個接口名,咱們會在 DNS 中把這個三個接口指向當前服務的 Cluster IP。k8s 的 Cluster IP 一般是一個很是固定的一個 IP,每一個服務在 k8s 部署時都會分配。
在增長完 DNS 記錄以後,再經過 Interface 的方式去調用,中間在咱們的 Service Mesh 裏面,咱們會基於 Cluster IP 信息完成實際的尋址,並跑通 Istio 的全部功能,和用服務名調用等同。
這個功能在現有的 SOFAMesh 中已經徹底實現,你們能夠去試用。稍後咱們會將這個方案提交給 k8s 或者 Istio 社區,看看他們是否願意接受這樣一個更通用的尋址方式。
在這裏咱們提出這樣一個設想:先上車後補票。所謂"先上車"是指說先上 Service Mesh 的車,"後補票"是指後面再去補微服務拆分的票。好處是在微服務拆分這個巨大的工做量完成以前,提早受益於 Service Mesh 提供的強大功能;同時也可讓部署變得舒服,由於不須要強制先所有完成微服務拆分才能上 Service Mesh 。有了這個方案,就能夠在應用不作微服務拆分的狀況下運行在 Service Mesh 上,而後再從容的繼續進行微服務拆分的工做,這是咱們提出這個解決方案的最大初衷。
固然,這裏面有比較多的技術實現細節,裏面有不少細節的東西實在是不適合在這裏一一展開。同時也涉及到比較多的 k8s 和 Istio 底層技術細節,須要你們對 k8s kubeproxy 網絡轉發方案和 Istio 的實現有比較深的認知才能徹底理解。這裏給出了幾篇文章,你們若是對這幾個技術有興趣,能夠經過這些文章來了解裏面的技術細節,今天就不在這裏繼續展開了。
MOSN 和 x-protocol 介紹:
Service Mesh 數據平面 SOFAMosn 深層揭祕
http://www.servicemesher.com/blog/sofa-mosn-deep-dive/
螞蟻金服開源 Go 語言版 Service Mesh 數據平面 SOFAMosn 性能報告
http://www.servicemesher.com/blog/sofa-mosn-performance-report-0.1.0/
螞蟻金服開源的 SOFAMesh 的通用協議擴展解析
http://www.servicemesher.com/blog/ant-financial-sofamesh-common-protocol-extension/
Dubbo on x-protocol——SOFAMesh 中的 x-protocol 示例演示
http://www.servicemesher.com/blog/dubbo-on-x-protocol-in-sofa-mesh/
X-protocol 特性的詳細講解:
SOFAMesh 中的多協議通用解決方案 x-protocol 介紹系列 (1)-DNS 通用尋址方案
https://skyao.io/post/201809-xprotocol-common-address-solution/
SOFAMesh 中的多協議通用解決方案 x-protocol 介紹系列 (2)- 快速解碼轉發
https://skyao.io/post/201809-xprotocol-rapid-decode-forward/
SOFAMesh 中的多協議通用解決方案 x-protocol 介紹系列 (3)-TCP 協議擴展]
https://skyao.io/post/201809-xprotocol-tcp-protocol-extension/
總結一下,咱們解決了以下幾個問題:
能夠快速的用幾個小時就在 SOFAMesh 中添加一個新的通信協議;
可讓 SOA 應用在 SOFAMesh 上繼續經過接口進行調用,不須要改代碼;
能夠實現不作 SOA 程序的微服務改造,就直接搬遷到 SOFAMesh,提早受益。
第四塊,涉及到流量劫持的方案。
Service Mesh 有一個很重要的特性,就是無侵入,而無侵入一般是經過流量劫持來實現的。經過劫持流量,在客戶端服務器端無感知的狀況下,能夠將 Service Mesh 的功能插進去。一般特別適合於相似安全加密等和現有應用的業務邏輯徹底分離的場合。
但 Istio 的流量劫持方案作的還不夠好,目前 Istio 只給了一個方案就是 iptables。這個方案有比較多的問題,因此咱們有幾個思路:
優化 iptables
優化 iptables 主要是爲了減小對 Host 主機的影響。
用 iptables 有兩種思路:一個是 pod only,就是說在 pod 裏面作 iptables,這個 Istio 的官方作法,可是這樣須要 ROOT 權限以便修改 iptables 配置;還有一種思路用 Host 主機上的 iptables,這個話能夠不用 ROOT 權限。咱們對比以後,仍是以爲放在 pod 裏面更好一點,由於性能損耗比較小一些,因此暫時咱們用的是在 pod 中方案,但咱們會進行優化,好比把 iptables 的模塊簡化到最小。
調研 IPVS 方案
咱們如今正在調研 IPVS 方案。主要是 iptables 方案存在部署問題,就是 iptables 這個模塊常常被限制使用。現場有沒有作運維的同窗?大家的機器上開啓了 iptables 嗎?我能告訴你們的是,到目前爲止,螞蟻金服內部的機器上,iptables 不只僅是禁用,而是整個 iptables 模塊都被卸載。緣由是性能、安全、維護等你們周知的緣由,總之咱們螞蟻金服內部是沒有這個模塊的。
爲了解決這個問題,咱們如今正在調研 IPVS 的方案,準備用 IPVS 來替換 iptables。這塊工做正在進行,目前方案已經驗證,可是還有一些細節沒有完善,後面有更多的消息也給你們繼續介紹。
輕量級客戶端的實踐
另外還有一個實踐是考慮不作流量劫持。好比說,最典型的 RPC 方案,由於 RPC 一般來講老是會有一個客戶端的。在上 Service Mesh 以後,能夠將原來的客戶端的一些功能如服務發現、負載均衡、限流等精簡,造成一個新的輕量級客戶端,但此時終究仍是有一個客戶端在的。
這個時候,若是能知道 Sidecar 的訪問地址,是能夠不進行流量劫持的,由客戶端直接將請求發給 Sidecar 就行了。因此,最基本的想法就是經過環境變量或者配置給出 Sidecar 的地址,告訴客戶端 Sidecar 就在 localhost 的 8080 端口。而後客戶端 SDK 簡單讀取一下,接下來直接將請求發過去就行了。這個方案能夠輕鬆的繞開流量劫持的問題。
這個方案咱們內部也實踐過,早期用來替代多語言客戶端的版本用的是這個方案。固然,實踐中發現流量劫持仍是有必要的,這是另一個話題,後面有機會再詳細解釋。
但上面這三個都不是今天的重點,今天的重點是下面這個 Cilium + eBPF 的思路,這是咱們目前最密切關注的一個方案。
Cilium 是一個很新的項目,Cilium 的思路中會涉及到底層通信中 TCP 堆棧的問題。
這裏的圖片顯示了用 iptables 和輕量級客戶端方案的網絡調用細節,左邊是客戶端 Service 和它的 Sidecar 之間的調用過程,能夠看到它走了兩次的 TCP 堆棧。而後還有 iptables 的攔截。輕量級客戶端方案和流量劫持方案的差異在於減小一次 iptables,避開了 iptables 的性能消耗。可是即便沒有 iptables,最終仍是要走整個調用流程,雖然 Loopback 環回地址比 network 網絡通信快不少,可是它終究仍是走了兩次 TCP 堆棧,兩次 TCP 堆棧這裏是有性能消耗的。
而 Cilium 則給出了一個很好的思路:想辦法繞開 TCP 堆棧。
Cilium 方案的好處,就在於在 socket 這個層面就完成了請求的轉發,經過 sockmap 技術實現 redirect,固然這個技術細節我們就不在這裏展開。今天主要是講一下這個思路的好處和價值。Cilium 方案最大的好處,是能夠繞開兩次 TCP 堆棧,繞開兩次 TCP 堆棧的好處,則會帶來一個出乎意外甚至違背常識的結果:Cilium 劫持能夠比輕量級客戶端不劫持更快!這可能顛覆你們的觀念。
咱們來體會一下。流量劫持,如 iptables,是要在原來的調用鏈當中插入一段,增長消耗致使性能降低,對吧?這是流量劫持最容易給人的留下的負面印象,就是流量劫持是有消耗的,因此優化的思路一般都在於減小這個消耗,或者選擇不作劫持從而避開這個消耗。那 Cilium 的作法則是給出另一種解決流量劫持問題的思路:經過繞開兩次 TCP 堆棧和其餘底層細節,更快的將請求轉發給 Sidecar!
Cilium 的這個思路是咱們很是讚揚的,經過這樣的方式減小服務和 Sidecar 之間的性能損失,能夠解決 Service Mesh 中相當重要的一個問題:性能與架構的取捨。
熟悉 Service Mesh 技術的同窗,應該多少都有這樣的認知: Service Mesh 是一門中庸的藝術。在性能與架構之間, Service Mesh 選擇犧牲性能來換取架構。在傳統的侵入式框架中,客戶端業務代碼和框架代碼之間是經過函數來進行調用的,速度很是快徹底能夠忽略。而 Service Mesh 是強行把框架和類庫剝離出來,將上述的方法調用變成一個遠程調用,以犧牲了一次遠程調用的開銷爲代價來換取整個架構的優化空間。這是 Service Mesh 技術和傳統侵入式框架的一個本質差別,也是 Service Mesh 技術和傳統侵入式框架全部差別的源頭。
這是 Service Mesh 技術最爲重要的一次取捨:捨棄一次遠程調用的開銷,換取更富有彈性的架構和更豐富的功能。
Service Mesh 技術的發展,也由此出現兩個大方向:一方面是繼續在架構上獲取好處,更多的功能,更豐富的使用場景,各類創新,竭盡量的獲取紅利;另外一方面,是在舍字上下功夫,儘量的將性能損失降到最低,以求獲得前面的最大好處而將付出的代價降到最低。
咱們在前面列出的這四個實踐,均可以說是在這條貪心的路上一步一步的探索和嘗試,但願能夠將 Service Mesh 架構上的捨棄的部分再儘量多的要回一部分。
固然,Cilium 在實際落地的時候仍是會有一些問題,好比說如今最大的問題是 Cilium 對 Linux 內核的版本要求特別高,最低要求是 4.9 推薦 4.10,而後裏面的部分特性要求是 4.14。Linux 內核 4.14 是 2017 年末才發佈的,而目前 Linux 內核最新版本才 4.18。Cilium 要求的 Linux 內核的版本實在太新了,部署時很難知足。另外就是 Cilium 仍是存在一些安全問題,主要是 eBPF 是將代碼直接注入到內核運行,效率好是好,可是確定會存在安全隱患。
咱們接下來會重點跟蹤 Cilium 技術,也有可能會給出其它的相似方案,有興趣的同窗能夠關注咱們的進展。
繼續給你們介紹今天的第四部份內容,對服務間通信範圍的探索。
Service Mesh 起初關注的是東西向通信,即系統內部各個服務之間的通信,而這一般都是同步的,走 REST 或者 RPC 協議。
在 Service Mesh 的實踐過程當中,咱們發現,Service Mesh 能夠提供的功能:
請求轉發:如服務發現,負載均衡等;
路由能力:如強大的 Content Based Routing 和 Version Based Routing ;
服務治理:基於路由能力而來的灰度發佈,藍綠部署,版本管理和控制;
糾錯能力:限流,熔斷,重試,測試目的的錯誤注入;
安全類:身份,認證,受權,鑑權,加密等。
能夠適用於 Service Mesh 以外的其餘領域,也就是說咱們能夠在其餘領域引入並重用這些能力,實現比單純的東西向通信更普遍的服務間通信。
第一個探索的方向是 API Gateway,和東西向通信直接對應的南北向通信。
主要緣由是南北向通信和東西向通信在功能上高度重疊,如服務發現,負載均衡,路由,灰度,安全,認證,加密,限流,熔斷...... 所以,重用東西向通信的這些能力就成爲天然而然的想法。
傳統侵入式框架下,重用這些能力的方式是基於類庫方式,也就是在 API Gateway 的實現中,典型如 Zuul,引入東西向通信中的類庫。而 Service Mesh 下,思路有所不一樣,重用的再也不是類庫,而是 Sidecar:經過將 Sidecar 用於南北向通信,重用 Sidecar 的請求轉發和服務治理功能。
將 Service Mesh 引入 API Gateway 的優點在於:
統一微服務和 API Gateway 兩套體系;
大量節約學習 / 開發 / 維護的成本;
能夠在南北向通信中得到 Service Mesh 的各類特性;
能夠經過 Service Mesh 的控制平面增強對南北向通信的控制力。
這個方向上,業界也有一些探索:
Ambassador: Kubernetes-native microservices API gateway,基於 Envoy 構建,開源項目;
Gloo: The Function Gateway built on top of Envoy,一樣是基於 Envoy,不過這個不只僅用於傳統的微服務 API Gateway,也能夠用於 Serverless 架構的 Function;
Kong:在最近宣佈,即將發佈的 1.0 版本,kong 將再也不是單純的 API Gateway,而是轉型爲服務控制平臺。可謂是一個反向的探索案例:從 API Gateway 向 Service Mesh 切。
而咱們的思路也很是明確:在 SOFAMesh 和 SOFAMosn 的基礎上,打造新的 API Gateway 產品,以此來統一東西向通信和南北向通信。目前該項目已經啓動,後續也會做爲開源項目公佈出來,對這個話題有興趣的同窗能夠保持關注。
前段時間咱們在考慮 Serverless 方向時,恰好看到 Google 新推出了它的 Serverless 新項目 Knative,時間點很是的巧。和其餘 Serverless 項目不一樣的是,Knative 項目關注的是 Serverless 平臺的標準化和規範化。
Knative 項目是基於 kubernetes 和 Istio 的,在 Knative 中 Istio 用於實現部分組件之間的通信。在 Knative 項目中,對因而否應該引入 Istio 存在很大爭議,由於以爲 Istio 過重了,爲了少許需求引入 Istio 有些興師動衆。不過這個問題對於原本就已經在用 Istio 的咱們來講不是問題。
目前在 Serverless,尤爲 Knative 方面,咱們還在探索,目前的初步想法是這樣:
Serverless 很重要
尤爲 Knative 的出現,昭示着 Serverless 領域新的玩法出現,Serverless 平臺出現標準化和統一化的契機
Kubernetes + Serverless + Service Mesh(尤爲是擴展範圍以後的 Service Mesh)是一個很好的組合
從下向上,從底層基礎設施到服務間通信再到 Function,在應用和系統之間造成了一套完整的支撐體系。
後續咱們的產品策略,會繼續深刻調研 knative,一邊 POC 一邊規劃產品,固然結合實際業務須要以落地爲目標依然是基本要求。而後,很是天然的,咱們會將標準版本的 Istio 替換爲咱們的 SOFAMesh 和 SOFAMosn。
舉例,目前咱們在計劃嘗試使用 Serverless 的典型場景:
小程序;
AI:Serverless AI Layer,一站式機器學習平臺;
Databus: 大數據處理。
這是咱們目前探索和規劃中的服務間通信的完整藍圖:
Service Mesh
負責東西向通信,實踐中就是咱們的 SOFAMesh 產品,基於 Istio 的擴展加強版;
API Gateway
負責南北向通信,還在探索中,咱們在嘗試基於 SOFAMosn 和 SOFAMesh 開發新的 API Gateway 產品;
Serverless
負責異步通信,事件驅動模型,粒度也從服務級別細化到 Function 級別,目前在積極探索和實踐 knative。
這裏給出一個咱們的預測:在雲原生的時代,服務間通信的將來都會是 Service Mesh 這種方式,將服務間通信的職責剝離並下沉。
這是今天的最後內容。前面四個部分的內容基本上都是給你們介紹咱們的產品實踐,落地遇到的問題,以及咱們正在作的一些探索,比較偏實際。第五部分會特殊一點,可能就有點 務虛 了。這塊要講是在過去一年當中,在項目落地的過程當中的特別感覺,其中最關鍵的一點就是基礎設施和服務網格之間的關係,或者說基礎設施對服務網格的意義。
裏面有一個時代背景:Cloud Native,雲原生。而在今年 6 月,CNCF 技術監督委員會經過了 Cloud Native 的定義,中文翻譯如上。
這裏咱們將關注點放在標紅的這一句來:雲原生的表明技術包括容器、服務網格、微服務、不可變基礎設施和聲明式 API。
對於雲原生架構,螞蟻金服的策略是:積極擁抱! 咱們將來的架構也會往這個方向演進。
對於前面列舉的雲原生表明技術:
容器:大阿里在容器技術上有很是深度的積累,實踐多年,而新版本的 Sigma3.* 版本也將基於 k8s;
微服務:微服務的前身,SOA 服務化,在大阿里也是實踐多年, Dubbo / HSF / SOFA 可謂名滿江湖,目前也在陸陸續續的微服務改造中;
不可變基礎設施和聲明式 API:也是高度承認和長期實踐的技術。
對於 Service Mesh 的定位,咱們是這樣理解的:
Service Mesh 是承上啓下的重要一環;
一方面充分利用底層系統能力;
一方面爲上層應用提供堅實的底座。
對於 Service Mesh,咱們有一個重要判斷,這也是今天最想和你們分享的一點:Service Mesh 的歸宿,或者說最終的形態,是下沉到基礎設施!
從 Service Mesh 的發展看,從簡單的 Proxy,到功能完善的 Sidecar(如 Linkerd 和 Envoy),再到以 Istio 爲表明的第二代 Service Mesh,演進的方式如上圖:
第一步:從應用剝離
經過將原有的方法調用改成遠程調用,將類庫的功能套上 Proxy 的殼子,Service Mesh 成功的將服務間通信從程序中剝離出來,今後服務間通信再也不是應用程序的一部分。
這一點是你們最容易接受的,對吧?這一步也是最容易實現的,只要搭起來一個 Sidecar 或者說 Proxy,將原有類庫的功能塞進去就行了。
第二步:下沉爲抽象層
這些剝離出來的服務間通信的能力,在剝離以後,開始下沉,在應用程序下造成一個單獨的抽象層,成爲 服務間通信專用基礎設施層。此時,這些能力以一個完成的形態出現,再也不存在單獨的類庫或者框架形式。
第二步和第一步每每是一脈相承的,一旦走出了第一步,天然而然會繼續。由於服務間通信被抽取出來以後,繼續往前發展,就會很天然地把它就變成一個基礎設施層。
第三步:融入基礎設施
繼續下沉,和底層基礎設施密切聯繫,進而融爲一體,成爲平臺系統的一部分,典型就是和 kubernetes 結合。
Istio 在這方面作了一個很是大的創新,Istio 的創新,不只僅在於增長控制平面,也在於和 kubernetes 的結合。
若是你們有在去年 QCon 聽過個人演講,會發現我在去年的時候對 Service Mesh 的理解和如今不太同樣。在去年的這個時候,我認爲 Istio 最大的創新是增長了控制平面。可是,今年我以爲還再加一個關鍵點,除了控制平面的增長以外,Istio 很重要的一點是開始跟 k8s 融合,充分利用 k8s 的能力。k8s 表明的是底層基礎設施,全部的各類能力在 k8s 上沉澱。在 Istio 上,已經可以看到這樣一個很是明顯的趨勢: Service Mesh 已經開始和底層基礎設施密切聯繫,融爲一體,成爲整個平臺系統的一部分。
你們注意體會這中間的細微差別,第一步和第二步,將服務間通信的能力抽取出來沉澱成一個抽象層,而若是止步於第二步的話,這個抽象層和底層基礎設施是沒有任何關係的。注意,好比說 Linkerd 或者 Envoy,在部署的時候,無論是物理機、虛擬機或者容器,都沒有任何關係,自己也不利用底層的任何能力,可謂涇渭分明。可是一旦演進到了 Istio,包括如今的 Linkerd 2.0,就會發現轉爲第三步的這種形態。
今天想跟你們說的是,Service Mesh 的將來,是將服務間通信的能力下沉到基礎設施,而後充分利用底層基礎設施的能力來架構整個體系。而再也不將底層基礎設施抽象成爲就是一個簡單的操做系統抽象:給我 cpu,給我內存,給我網絡,給我 IO,其餘的事情和底層沒有任何關係,我本身上面所有搞定。這個思路在 Service Mesh 的將來發展中是不合適的, Service Mesh 將來必定是經過和基礎設施融合的方式來實現。
注意這個方式跟傳統方式的差別,不只僅在於技術,而是這個方式會混淆兩個傳統的部門:一個叫作中間件,就像我所在的部門,或者有些公司叫作基礎架構部門;還有一個部門一般是運維部門或者叫作系統部門,負責維護底層基礎設施。大部分公司通常這兩個部門在組織架構上是分離的。作 k8s 的同窗,和作微服務框架好比 Dubbo,Spring Cloud 的同窗,一般是兩個不一樣的組織架構,彼此涇渭分明。第三步要走通的話,就會要求中間件部門和基礎設施部門關係要協調的特別好,要密切的合做,才能將事情作好。
這是在過去這一年當中,咱們在實踐中獲得的最大的一個感覺,也是今天整個演講中最但願給你們分享的內容。
這裏拋出一個問題,和傳統的 Spring Cloud,Dubbo 等侵入式框架相比:
Service Mesh 的本質差別在哪裏?
若是去年的我來回答這個問題,那我會告訴你:下移,沉澱,造成一個通信層。而今天,我會告訴你們,除了這點以外,還有第二點:充分利用底層基礎設施。這是 Dubbo,Spring Cloud 歷來沒有作到的!
這是今天最想和你們分享的觀點,也是過去一年實踐中最大的感悟:
Service Mesh 和 Spring Cloud / Dubbo 的本質差別,不只僅在於將服務間通信從應用程序中剝離出來,更在於一路下沉到基礎設施層並充分利用底層基礎設施的能力。
最後,咱們總結一下今天的內容:
給你們介紹了一下咱們的 SOFAMesh 項目,若是你們有計劃應用 Service Mesh 技術,想上 Istio,能夠嘗試瞭解一下咱們的這個項目,會讓你們落地更舒服一些;
其次給你們介紹了選擇 Golang 的緣由,主要是由於語言棧的長期選擇。若是有正在進行 Service Mesh 技術選擇的同窗,能夠做爲參考。若是和咱們同樣,更願意在將來保持 Golang 和 Java 爲主要語言棧,則能夠參考咱們的方案,固然咱們更但願大家能夠和咱們一塊兒來共建 SOFAMesh 這個開源項目;
而後給你們分享了咱們遇到的幾個典型問題,如何快速的支持更多通信協議,如何讓傳統的 SOA 架構的應用程序在不進行代碼修改的狀況下也能從 Service Mesh 中受益,實現系統的平滑遷移。對於準備實際落地的同窗會有幫助,因爲時間所限未能將細節展開,你們能夠會後查看資料或者直接找咱們交流;
對服務間通信的範圍進行了探討,從原有的東西向通信,擴展到南北向通信,還有在 serverless 項目中的使用。但願可以讓你們瞭解到 Service Mesh 技術能夠應用的更多場景;
最後談了一下切身感覺:Service Mesh 技術要想徹底發揮做用,須要和底層基礎設施融合,以充分發揮基礎設施的能力。這塊的認知,會影響到 Service Mesh 的技術選型,產品方案,甚至影響組織關係。可謂相當重要,但願每位有志於此的同窗能認認真真的審視這個問題。
Service Mesh 是一個新生事物,新事物在剛出現時老是會遇到各類挑戰和質疑,尤爲在它自身還不夠徹底成熟的時候。而 Service Mesh 背後的 Cloud Native,更是一場史無前例的巨大變革。
咱們心懷美好願景,憧憬將來的 Cloud Native 架構,那裏有咱們的 Service Mesh,有 k8s,有微服務...... 而新的架構,新的技術,歷來都不是能一蹴而就的,更不存在一路順風之類的美好而天真的想法。
道路歷來都是人走出來的,或者說,趟出來的。做爲國內 Service Mesh 技術的先驅者,咱們坦言 Service Mesh 技術還不夠成熟,還有不少問題等待解決,還有很是多的挑戰在前面等着咱們。但咱們有信心相信,咱們的方向是正確的,咱們今天的每一份努力,每一份付出,都在讓咱們離目標更近一步。
魯迅先生說:地上本沒有路,走的人多了,也便成了路。在 Service Mesh 的這個方向,相信會出現愈來愈多努力探索的身影。這條路,咱們終究會努力趟出來!
長路漫漫,吾輩當踏歌而行!
目前 SOFAMesh 和 SOFAMosn 項目都已經在 github 開源,地址以下:
sofa-mesh: https://github.com/alipay/sofa-mesh
sofa-mosn: https://github.com/alipay/sofa-mosn
歡迎你們關注這兩個項目的進展,若是能 star 一下表示支持就更好了,感激涕零!
更但願能夠一塊兒來參與這兩個項目的建設,期待 Issue,期待 PR!
對 Service Mesh 技術感興趣的同窗,能夠關注 servicemesher 社區,這是一箇中立的純技術社區,聚集了當前國內大部分 Service Mesh 的技術人員。我本人也是 servicemesher 社區的創始人之一,這個社區的使命是傳播 Service Mesh 技術,增強行業內部交流,促進開源文化構建,推進 Service Mesh 在企業落地。
能夠經過訪問社區網站 http://www.servicemesher.com 獲取各類技術資訊和社區活動信息,能夠關注 servicemesher 社區的微信公衆號獲得及時的信息推進。咱們擁有一個龐大的翻譯組,除了翻譯各類 Service Mesh 相關的技術博客和新聞,還負責 Envoy 和 Istio 兩個項目官方文檔的平常維護。
也歡迎你們加入 servicemesher 社區的微信交流羣,請按照 servicemesher.com 網站的 "聯繫咱們" 頁面的要求加入微信交流羣。
最後,厚顏推薦一下我本身的我的技術博客 https://skyao.io ,歡迎瀏覽和交流。
今天的內容到此結束,很是感謝你們的聆聽,有緣下次再會!謝謝你們!
相關連接:
SOFA 文檔: http://www.sofastack.tech/
SOFA: https://github.com/alipay
SOFAMosn:
https://github.com/alipay/sofa-mosn
延伸閱讀:
長按關注,獲取分佈式架構乾貨
歡迎你們共同打造 SOFAStack https://github.com/alipay