Service Mesh Virtual Meetup 是 ServiceMesher 社區和 CNCF 聯合主辦的線上系列直播。本期爲 Service Mesh Virtual Meetup#1 ,邀請了四位來自不一樣公司的嘉賓,從不一樣角度展開了 Service Mesh 的應用實踐分享,分享涵蓋如何使用 SkyWalking 來觀測 Service Mesh,來自陌陌和百度的 Service Mesh 生產實踐,Service Mesh 的可觀察性和生產實踐以及與傳統微服務監控的區別。html
本文根據5月14日晚,G7 微服務架構師葉志遠的主題分享《Service Mesh 高可用在企業級生產中的實踐》整理。文末包含本次分享的視頻回顧連接以及 PPT 下載地址。git
談到 Service Mesh,人們老是想起微服務和服務治理,從 Dubbo 到 Spring Cloud (2016開始進入國內研發的視野,2017年繁榮)再到 Service Mesh (2018年開始被你們所熟悉),正所謂長江後浪推前浪,做爲後浪,Service Mesh 別無選擇,而 Spring Cloud 對 Service Mesh 滿懷羨慕,微服務架構的出現與繁榮,是互聯網時代架構形式的巨大突破。Service Mesh 具備必定的學習成本,實際上在國內的落地案例很少,大可能是雲商與頭部企業,隨着性能與生態的完善以及各大社區推進容器化場景的落地,Service Mesh 也開始在大小公司生根發芽,彌補容器層與 Kubernetes 在服務治理方面的短缺之處。本次將以一個選型調研者的視角,來看看 Service Mesh 中的可觀察性主流實踐方案。github
可觀察性(Observability)不是一個新名詞,它在好久以前就已經誕生了,可是它在 IT 領域倒是一個新興事物。可觀察性在維基百科中原文是這樣定義的:「In control theory, observability is a measure of how well internal states of a system can be inferred from knowledge of its external outputs. 」。雲原生領域第一次出現這個詞,是在雲原生理念方興未艾的2017年,在雲原生的思潮之下,運用傳統的描述方式已經不足以歸納這個時代的監控訴求,而 Observability 就顯得貼切許多。數據庫
回想一下傳統的監控方式,除去運維層面的主機監控、JVM 監控、消息隊列監控以外,有多少監控是事先就想好怎麼作的?不多!其實不少時候,咱們作的事情就是在故障發生以後,對故障覆盤的過程當中,除了 bug 重現與修復,也會去定製加一些監控,以指望下次發生一樣的狀況時有一個實時的告警。研發人員收到告警以後得以快速地處理問題,儘量地減小損失。因此,傳統的監控模式大多都是在作亡羊補牢的事情,缺乏一個主動性。編程
在雲原生時代的容器化體系當中就不同了,容器和服務的生命週期是緊密聯繫在一塊兒的,加上容器完美的隔離特性,再加上 Kubernetes 的容器管理層,應用服務跑在容器當中就顯得更加地黑盒化,相較在傳統物理主機或者虛擬機當中,排查問題的時候顯得很是不便。因此在雲原生時代強調的是可觀察性,這樣的監控永遠都是兵馬未動而糧草先行的,須要提早想好咱們要如何觀察容器內的服務以及服務之間的拓撲信息、各式指標的蒐集等,這些監測能力至關重要。後端
關於可觀察性在雲原生領域是什麼時候開始流行起來的,沒有一個很明確的時間。業界認爲可觀察性最先是由 Cindy Sridharan 提出的,其實一位德國柏林的工程師 Peter Bourgon 早在2017年2月就已經有文章在討論可觀察性了,Peter 算是業界最先討論可觀察性的開發者,他寫的著名的博文《Metrics, Tracing, and Logging》被翻譯成了多種語言。真正可觀察性成爲一種標準,是來自 Pivotal 公司的 Matt Stine 定義的雲原生標準,可觀察性位列其中,由此可觀察性就成爲了雲原生時代一個標準主題。安全
Peter Bourgon 提出的可觀察性三大支柱圍繞 Metrics、Tracing 和 Logging 展開,這三個維度幾乎涵蓋了應用程序的各類表徵行爲,開發人員經過收集並查看這三個維度的數據就能夠作各類各樣的事情,時刻掌握應用程序的運行狀況,關於三大支柱的理解以下:架構
此外,Peter Bourgon 在博文中還提到了三大支柱結合態的一些理想輸出形式,以及對存儲的依賴,Metrics、Tracing、Logging 因爲聚合程度的不一樣,對存儲依賴由低到高。更多細節,感興趣的同窗能夠查看文末的原文連接。app
Peter Bourgon 關於可觀察性三大支柱的思考不止於此,他還在2018年的 GopherCon EU 的分享上面再次討論了 Metrics、Tracing 和 Logging 在工業生產當中的深層次意義,此次他探討了4個維度。框架
在 CNCF Landscape 當中,有一塊區域專門用做展現雲原生場景下的可觀察性解決方案,裏面又分爲好幾個維度,圖中是截至2020年5月14日的最新版圖,將來還會有更多優秀的解決方案涌現出來。CNCF 目前畢業的10個項目庫當中,有3個是和可觀察性有關的,可見 CNCF 對可觀察性的重視程度。
談到這裏,不少同窗也許對於可觀察性相關的協議比較感興趣。目前比較火的有好幾個,OpenTracing、OpenCensus、OpenTelemetry、OpenMetrics 等等,目前比較火的是前三個。OpenMetrics 這個項目已經不維護了。
OpenTracing 能夠說是目前使用最廣的分佈式鏈路追蹤協議了,大名鼎鼎的 SkyWalking 就是基於它實現的,它定義了與廠商無關,與語言無關的鏈路追蹤協議 API,使得構建跨平臺的鏈路追蹤成爲一件比較輕鬆的事情,目前它在 CNCF 的孵化器當中茁壯成長。
OpenCensus 是谷歌提出的一個針對 Tracing 和 Metrics 場景的協議,背靠 Dapper 的加持與歷史背景,就連微軟也十分擁護,目前在商用領域十分流行。
其餘的協議好比 W3C Trace Context,呼聲也很高,它甚至對數據在頭部進行了壓縮,與實現層無關。也許 CNCF 意識到各類協議又在層出不窮,之後各成氣候,羣雄逐鹿,每個中間件都要作許多兼容,這對整個技術生態自己不利,所以 OpenTelemetry 橫空出世。從字面意思就知道,CNCF 會將可觀察性的「遙測」進行到底,它融合了 OpenTracing 和 OpenCensus 的協議內容,旨在提升雲原生時代可觀察性指標的統一收集與處理,目前 OpenTelemetry 已經進入 beta 版本,其中使人欣喜的是,Java 版本的 SDK 已經有一個相似 SkyWalking 的基於 byte-buddy 框架的無侵入式探針。目前已經能夠從47種 Java 庫當中自動探測獲取遙測數據,另外推出了可供使用的 Erlang、Go、Java、JavaScript、Python 的 API 和 SDK。此外,數據收集器 OpenTelemetry Collector 也可使用了,能夠用它接收 OpenTelemetry client 發射過來的數據,統一收集處理。目前 CNCF 對 Logging 相關的協議制定暫緩,可是有一個工做小組也在作這方面規範的事情。
要說 Service Mesh 與可觀察性的關係,那就是可觀察性是 Service Mesh 的功能子集。Service Mesh 是當今最爲火爆的技術理念之一,它致力於爲雲原生時代運行在容器當中的大規模服務提供統一的服務發現、邊緣路由、安全、流量控制、可觀察性等能力,它是對 Kubernetes 服務治理能力的補充強化。能夠說,Service Mesh 是雲原生容器化時代的必然產物,它將對雲上服務架構產生深遠的影響。Service Mesh 的架構理念是將容器服務運行單元當成一個個網格,在每組運行單元中劫持流量,而後由一個統一的控制面板作統一處理,全部網格與控制面板維持必定的聯繫,這樣,控制面板就得以做爲可觀察性解決方案與容器環境之間的橋樑。
市面上最爲常見的 Service Mesh 技術有 Linkerd、Istio、Conduit 等,可是要在生產環境落地必需要經受住嚴苛的性能、合理的架構、社區活躍度的評估。
Linkerd 是由 Buoyant 開發維護,算是 Service Mesh 領域第一代的產品,Linkerd1.x 基於 Scala 編寫,可基於主機運行,你們都知道 Scala 運行環境依賴 JDK,所以對資源的消耗相對較大。隨後官方進行了整改,推出了新一代的數據平面組件 Conduit,基於 Rust 和 Go 編寫,與 Linkerd 雙劍合璧,成爲 Linkerd2.x。整體來講,Linkerd2.x 性能有了較大的提高,也有可視化界面供操做,可是在國內就是不慍不火的,社區始終發展不起來。
轉頭看2017年出現的 Istio,也算是含着金湯勺出生的,由谷歌、IBM、Lyft 發起,雖然晚了 Linkerd 一年,可是一經推出,就受到普遍的關注與追捧。Istio 基於 Golang 編寫,完美契合 Kubernetes 環境,數據平面整合 Envoy,在服務治理方面職責分明,國內落地案例相較 Linkerd 更加普遍。
Istio 目前整體還算是一個年輕的開源中間件,大版本之間的組件架構有比較大的區別,好比 1.0 引入了Galley(如圖左),1.5 去掉了 Mixer,而且控制平面整合成單體,增長了 WASM 擴展機制(如圖右)。整體的架構形式沒有太大變化,數據面仍是關注流量的劫持與轉發策略的執行,控制面依然作遙測收集、策略下發、安全的工做。目前國內業界對於 Istio 的使用上,雲商與頭部公司處於領先位置,好比螞蟻金服自研了本身基於 Golang 的數據平面 MOSN,兼容 Istio,作了許多優化工做,對 Istio 在國內落地作出了表率,更多的信息能夠深刻了解,看如何打造更適合國內互聯網的 Service Mesh 架構。
雖然在 1.5 版本當中 Mixer 已經基本被廢棄掉,進入維護階段直到 1.7 版本,默認狀況下 Mixer 徹底關閉,可是目前多數落地方案仍是基於 1.0-1.4 這個版本區間,因此在沒有總體升級的狀況下,以及 WASM 性能不明朗的彷佛還,始終仍是離不開 Mixer 的。前面說到 Service Mesh 是雲原生容器環境與可觀察性之間的橋樑,Mixer 的 Adapter 能夠算得上是這個橋樑的鋼架主體了,而且具備良好的可擴展性。Mixer Adapter 除了爲流量作 Check 以外,更重要的是在預檢階段和報告階段收集遙測數據,遙測數據經過 Adapter 暴露或發射數據到各類觀察端,觀察端基於數據繪製豐富的流量軌跡與事件快照。經常使用的用於可觀察性的 Adapter 有對各類商用方案的適配,好比 Datadog、New Relic 等,開源方案 Apache SKyWalking、Zipkin、Fluentd、Prometheus 等,相關內容會在下文展開。
數據平面好比 Envoy 會向 Mixer 上報日誌信息(Log)、鏈路數據(Trace),監控指標(Metric)等數據,Envoy 上報的原始數據都是一些屬性信息(Attributes),屬性信息是名稱和類型的元數據,用來描述入口和出口流量和流量產生時的環境信息,而後 Mixer 會依照 LogEntry、Metric 或者 TraceSpan 模板配置的格式對屬性進行格式化,最後再交給 Mixer Adapter 作進一步處理,固然對於數據量龐大的 Log 信息和 Trace 信息能夠選擇直接上報處理端,Envoy 也原生支持一些特定組件。不一樣的 Adapter 須要不一樣的 Attributes,模板定義了 Attributes 到 Adapter 輸入數據映射的 schema,一個 Adapter 能夠支持多個模板。Mixer 當中又能夠抽象出三種配置模型:
下圖是 Metric 模板與 LogEntry 模板,在映射關係之上還能夠設定默認值,更多的設定能夠查看官方文檔。
下圖是 TraceSpan 模板,熟悉 OpenTracing 的同窗可能對映射內容比較熟悉,不少信息都是 OpenTracing 協議的標準值,好比 Span 的各類描述信息以及 http.method、http.status_code 等等,感興趣的同窗也能夠去看看 OpenTracing 的標準定義。
另外在Service Mesh中對於鏈路追蹤廣泛有一個問題,就是不管你在數據平面如何作流量劫持,如何透傳信息,以及如何生成或者繼承Span,入口流量和出口流量都有一個沒法串聯的問題,這個問題要解決仍是須要服務主容器來埋點透傳,將鏈路信息透傳到下一次請求當中去,這個問題是沒法避免的,而OpenTelemetry的後續推行,能夠解決這方面的標準化問題。
在 Istio Mixer Adapter 當中咱們能夠獲知,Istio 支持 Apache SKyWalking、Zipkin、Jaeger 的鏈路追蹤,這三個中間件都支持 OpenTracing 協議,因此使用 TraceSpan 模板同時接入也沒有什麼問題。三者稍有不一樣的地方是:
說到這裏要提一下 SkyWalking,它是由國人吳晟自主研發並開源的 APM 中間件了,能夠說是國人的驕傲吧。本次的分享第二場由高洪濤老師,SkyWalking 的核心貢獻者之一,也對 SkyWalking 作了題爲《Apache SkyWalking 在
Service Mesh 中的可觀察性應用》的分享,感興趣的同窗能夠關注一下。
Skywalking 提供了 Java、.NET、NodeJS、PHP、Python 的無侵入式插樁 SDK,另外提供 Golang 和 Lua 的有侵入式 SDK。
爲何 Golang 不能作成無侵入式的?這還得從語言特性提及,一般編程語言分爲編譯型語言、解釋型語言、中間型語言,像 Java 這種語言,在編譯的時候是編譯成字節碼,而後運行時再經過 JVM 去運行字節碼,這樣就能夠在這其中作不少的事情,能夠在編譯的過程當中把本來的代碼改掉。而像 Python、PHP、JS 和 Erlang,是使用的時候纔會進行逐行翻譯,因此也能夠在用的時候去加入一些額外的代碼。Golang、C、C++ 則是編譯型語言,在編譯與連接的時候已經將源碼轉換成了機器碼,因此在運行的時候是很難去改動的,這也就是 Golang 爲何不能作自動探針的緣由。另外 SkyWalking 是由國人發起的,因此用戶羣體基數很是大,迭代也很是地快,7.0版本之前支持基於 Mixer 的遙測與顯示,8.0以後又加入了從 Prometheus 或 Spring Sleuth 當中收集數據,另外8.0以後支持 Envoy ALS(access log service),不過須要開啓 ALS 接收器。
在 SkyWalking 的使用上,基本是使用 ES 來作存儲,可是有一些改動,將 service、endpoint、instance 這些信息放到關係數據庫,各個插樁 SDK 也加入到基礎鏡像,也能夠基於 SkyWalking 輕鬆實現服務接口粒度的調用次數統計。
另一個在雲原生鏈路追蹤領域收到普遍使用的是中間件是 Jaeger,它是由 Uber 開源,被 CNCF 接納,目前已是一個畢業項目。它原生支持 OpenTracing 協議,與市面上的其餘中間件也具備互通性,支持多種後端存儲以及具有靈活的擴展性。在 Envoy 中原生支持 Jaeger,當請求到達 Envoy 的時候,Envoy 會選擇建立 Span 或繼承 Span,以保證鏈路的連貫性,它支持 Zipkin 的 B3 系列 Header 透傳,以及 Jaeger 與 LightStep 的 Header。下圖是 Jaeger 當中對鏈路的展現,能夠經過 TraceId 準肯定位某一次請求。
傳統的日誌解決方案,ELK 能夠說是家喻戶曉的,從 Spring Cloud 盛行開始,它即是日誌解決方案的優良選擇。隨着技術的發展,近幾年又出現了 EFK 這種解決方案,存儲組件 ElasticSearch 和界面 Kibana 卻是沒有什麼特別大的變化,可是在嚴苛的線上環境與容器環境中,以及各類對資源敏感的場景下,對於日誌採集組件的要求也愈來愈高,目前比較流行的方案是使用 Fluentd 或者 Filebeat 替代 Logstash,下面是它們三者的一些介紹:
對於 Istio 中的日誌解決方案,儘管 Mixer 當中有提供 Fluentd Adapter,可是日誌的量級你們也知道,這種方式並很差,因此從 Envoy 去拿到原始的屬性日誌再進行加工發射到存儲端對應用是比較友好的,能夠節省出很大一部分資源。
在日誌維度中,若是要定位問題,最好與請求綁定起來,而綁定請求與日誌,須要一個特定的標識,能夠是 TransactionId 或者是 TraceId,因此鏈路追蹤與日誌融合是一個勢在必行的行業訴求,所以在選擇鏈路追蹤中間件的時候,必定要考慮到如何更好地獲取 TraceId 並與日誌結合起來。
那麼 Fluentd 就是最好的日誌收集和發射解決方案了嗎?
不是。Fluentd 的研發團隊又推出了更加輕量級的 Fluent Bit,它是使用純C編寫的,佔用資源更加少,從Fluentd 的 MB 級別直接降爲 KB 級別,更加適合做爲日誌收集器。而 Fluentd 插件種類很是繁多,目前共有接近上千種的插件了,因此它更適合做爲日誌的聚合處理器,在日誌收集以後的加工與傳輸中使用。在實際應用中,使用 Fluent Bit 可能會遇到一些問題,使用比較早期的版本可能會有配置動態加載的問題,解決方法就是另起一個進程控制 Fluent Bit 的啓停,同時監聽配置的變化,有變化則 reload。
關於上圖中的 Loki,它的核心思想正如項目介紹,「Like Prometheus, but for logs」,相似於 prometheus 的聚合日誌解決方案,2018年12月開源,短短兩年,卻已有接近1萬個 Star 了!它由 Grafana 團隊開發,由此能夠看出 Grafana 對於一統雲原生可觀察性的目的。
在雲原生時代,像之前那樣用昂貴的全文索引,如 ES,或者列式存儲,如 HBase,將大量的原始日誌直接存儲到昂貴的存儲介質之中的作法,彷佛已經不太穩當。由於原始日誌99%是不會被查詢到的,因此日誌也是須要作一些歸併,歸併以後壓縮成 gzip,而且打上各式標籤,這樣可能會更加符合雲原生時代精細化運做的原則。
而 Loki 能夠將大量的日誌存儲於廉價的對象存儲中,而且它爲日誌打標歸併成日誌流的這種方式得以讓咱們快速地檢索到對應的日誌條目。可是注意一點,想要使用 Loki 替代 EFK 是不明智的,它們針對的場景不同,對數據的完整性保證和檢索能力也有差異。
自從 Prometheus 出現以來,就緊緊佔據着監控指標的主要地位。Prometheus 應該是當前應用最廣的開源系統監控和報警平臺了,隨着以 Kubernetes 爲核心的容器技術的發展,Prometheus 強大的多維度數據模型、高效的數據採集能力、靈活的查詢語法,以及可擴展、方便集成的特色,尤爲是和雲原生生態的結合,使其得到了愈來愈普遍的應用。
Prometheus 於2015年正式發佈,於2016年加入 CNCF,並於2018年成爲第2個從 CNCF 畢業的項目(第一個是 Kubernetes,其影響力可見一斑)。目前 Envoy 支持 TCP 和 UDP statsd 協議,首先讓 Envoy 推送指標到 statsd,而後可使用 Prometheus 從 statsd 拉取指標,以供 Grafana 可視化展現。另外咱們也能夠提供 Mixer Adapter,接收處理遙測數據供 Prometheus 採集。
在 Prometheus 的實際使用當中可能會存在一些問題,好比 pod 被殺掉須要另外啓一個,致使 Prometheus 數據丟失,這就須要一個 Prometheus 的數據可持久化的高可用方案。CNCF 的沙箱項目裏面有一個項目叫作 Thanos,它的核心思想至關因而在 Prometheus 之上作了一個相似數據庫 sharding 的方案,它有兩種架構模式:Sidecar 與 Receiver。目前官方的架構圖用的 Sidecar 方案,Receiver 是一個暫時尚未徹底發佈的組件,Sidecar 方案相對成熟一些,更加高效也更容易擴展。
Service Mesh 解決方案當中的 Linkerd 和 Conduit 都有可視化界面。Istio 相對來講比較黑盒,一直被詬病,不過 Istio 社區聯合 Kiali,共同推出了一個可視化方案,提供以下功能:
下面是 Kiali 的架構,能夠比較清楚地看出,其自己是一個先後端分離的架構,而且能夠從 Prometheus 或者集羣特定 API 獲取指標數據,另外也囊括了 Jaeger 鏈路追蹤界面與 Grafana 展現界面,不過它們並不是開箱即用,Kiali 依賴的三方組件須要單獨部署。
在許多的中小型公司內部,其實 Service Mesh 仍是處於一個預研階段,實際落地的時候須要考慮的因素繁多,如何才能得到較好的的投入產出效能比,是每個作選型的人員都必需要經歷的。其實無論落地狀況,鑑於雲原生的可觀察性哲學來講,在落地的同時作好可觀察性,能夠同步解決不少問題,避免耗費過多的資源在無心義的事情上面,綜合可觀察性的三大支柱以及 Service Mesh 中對可觀察性的支持來講,總結以下:
葉志遠,G7 微服務架構師,Spring Cloud 中國社區聯合創始人,ServiceMesher 社區成員,《從新定義 Spring Cloud 實戰》做者,國內微服務領域早期實踐者,雲原生追隨者。
視頻回顧:https://www.bilibili.com/video/BV13K4y1t7Co
PPT 下載:https://github.com/servicemesher/meetup-slides/tree/master/2020/05/virtual