【譯文連載】 理解Istio服務網格(第六章 可觀測性)
全書目錄
-
第一章 概述
-
第二章 安裝
-
第三章 流控
-
第四章 服務彈性
-
第五章 混沌測試
本文目錄
第6章 可觀測性
6.1 分散式呼叫鏈跟蹤(tracing)
6.1.1 基本概念
6.1.2 Jaeger
6.1.3 Istio對分散式呼叫跟蹤的支援
6.2 遙測(Metric)
6.3 服務圖(Service graph)
第6章 可觀測性
微服務架構管理中最大的挑戰之一是如何通過簡單方法就能瞭解系統各個元件之間的關係。終端使用者的一次會話可能會流經多個甚至幾十個獨立部署的微服務,因此,發現哪裡有效能瓶頸或錯誤變得尤為重要。
本章中,我們會通過Jaeger實現呼叫鏈跟蹤、通過Grafana和Prometheus實現遙測資料收集和展示,通過Kiali生成服務視覺化圖。
Istio的Mixer模組由istio-policy和istio-telemetry服務組成,執行在istio-system名稱空間的兩個獨立的pod中。下面的命令能很容易地將它們找出來,因為它們都帶有同樣的標籤:
oc get pods -l istio=mixer -n istio-system
oc get services -l istio=mixer -n istio-system
6.1 分散式呼叫鏈跟蹤(tracing)
通常,瞭解微服務系統架構所做的第一件事情就是看那些服務參與了終端使用者會話。當多個團隊部署了大量互相獨立的微服務時,要理解它們之間的依賴會非常困難。Istio的Mixer模組帶有開箱即用的能力,從分散式服務中獲取跟蹤跨度(tracing span)。這意味著跟蹤功能是與程式語言無關的,因此使用不同語言進行程式設計的團隊都可以使用它。
6.1.1 基本概念
分散式呼叫鏈跟蹤這概念起源於Google發表的論文《Dapper,大規模分散式系統的跟蹤系統》。它具有以下幾個核心概念。
OpenTracing:是CNCF(雲原生計算基金會)下的一個專案,其中包含了一套分散式呼叫跟蹤的標準規範、各種語言的API、程式設計框架和函式庫。其目的是定義一套分散式呼叫跟蹤的標準,以統一各種分散式呼叫跟蹤的實現。目前已有大量支援OpenTracing規範的跟蹤程式(Tracer),包括Jaeger和Zipkin等。在微服務應用中採用OpenTracing API實現分散式呼叫各種,可以避免供應商鎖定,從而以最小的代價和任何相容OpenTracing的基礎設施對接。
跨度(span):是兩個服務之間的一次請求與響應過程,比如一次REST呼叫或者資料庫操作。Jaeger將其定義為“系統中的一個邏輯的互動單元,具有操作名稱(operation time)、操作開始時間(start timestamp)和結束時間(finish timestamp)”。跨度是分散式呼叫跟蹤的最小跟蹤單位。
呼叫鏈(trace):是分散式系統中的一個端到端事務,Jaeger將其定義為“資料或執行穿過系統的路徑,可視為跨度的有向無環圖”。
跨度上下文(Span context):這是分散式呼叫跟蹤的上下文資訊,包括Trace ID,Span ID以及其它需要傳遞到下游服務的內容。一個OpenTracing的實現需要將跨度上下文通過某種序列化機制在程序邊界上進行傳遞,以將不同程序中的跨度關聯到一個呼叫鏈上。在基於HTTP協議的分散式呼叫中,通常使用HTTP Header來傳遞跨度上下文資訊。Zipkin使用b3 HTTP Header,Jaeger使用 uber-trace-id HTTP Header。Istio/Envoy支援b3 HTTP Header和x-ot-context Header。
跨度的資料結構中主要包括以下內容:
-
Name:Span所代表的操作名稱,例如REST介面對應的資源名稱。
-
Start timestamp:Span所代表操作的開始時間
-
Finish timestamp:Span所代表的操作的的結束時間
-
Tags:一系列標籤,每個標籤由一個鍵值對組成。該標籤可以是任何有利於呼叫鏈分析的資訊,例如方法名,URL等。
-
SpanContext:用於跨程序邊界傳遞Span相關資訊,在進行傳遞時需要結合一種序列化協議使用。
-
References:該Span引用的其它關聯Span,主要有兩種引用關係,Childof和FollowsFrom。
o Childof: 最常用的一種引用關係,表示Parent Span和Child Span之間存在直接的依賴關係。例PRC服務端Span和RPC客戶端Span,或者資料庫SQL插入Span和ORM Save動作Span之間的關係。
o FollowsFrom:如果Parent Span並不依賴Child Span的執行結果,則可以用FollowsFrom表示。例如網上商店購物付款後會向用戶發一個郵件通知,但無論郵件通知是否傳送成功,都不影響付款成功的狀態,這種情況則適用於用FollowsFrom表示。
一條呼叫鏈(trace)可被認為是一個由多個跨度(span)組成的有向無環圖,多個跨度組成一個請求的完整呼叫鏈。而分散式跟蹤系統要實現的,就是記錄每次傳送和接受動作的識別符號和時間戳,將一次請求涉及到的所有服務串聯起來,只有這樣才能搞清楚一次請求的完整呼叫鏈。圖6-1是一個分散式呼叫的例子,客戶端發起請求,請求首先到達負載均衡器(load balancer),接著經過認證(auth)服務,計費(billing)服務,然後請求資源(resource),最後返回結果。
圖6-1. 一個分散式呼叫示例
分散式跟蹤系統負責採集和儲存呼叫鏈資料,然後通常會使用包含時間軸的時序圖來將這個呼叫鏈展現出來,橫座標是時間,圓角矩陣是請求的各個執行階段,如圖6-2所示。
圖6-2. 分散式跟蹤系統生成的時序圖
6.1.2 Jaeger
Jaeger是Uber推出的一款開源分散式跟蹤系統,相容OpenTracing API,於2017年9月加入CNCF基金會,其架構如圖6-3所示。
圖6-3. Jaeger架構
Jaeger 主要由以下幾部分組成:
-
Client – Jaeger的客戶端,實現了符合OpenTracing API標準的SDK,支援主流程式語言。客戶端直接整合在應用程式碼中,應用程式通過其API寫入資料,客戶端庫把呼叫鏈資訊按照應用程式指定的取樣策略傳遞給Agent。在應用中呼叫Jaeger Client庫記錄跨度的過程通常被稱為埋點。
-
Agent - 它是一個監聽在UDP埠上接收跨度資料的網路守護程序,它會將資料批量傳送給Collector。它被設計成一個基礎元件,部署在宿主機上。Agent將Client 庫和Collector 解耦,為Client庫遮蔽了路由和發現Collector的細節。
-
Collector - 接收Agent傳送來的資料,然後將資料寫入後端儲存。Collector被設計成無狀態的元件,因此您可以同時執行任意數量的Collector。
-
Data Store - 後端儲存被設計成一個可插拔的元件,支援將資料寫入Cassandra和Elastic search。
-
Query - 接收查詢請求,然後從後端儲存系統中檢索呼叫鏈並通過UI進行展示。Query 是無狀態的,您可以啟動多個例項,把它們部署在Nginx這樣的負載均衡器後面。
6.1.3 Istio對分散式呼叫跟蹤的支援
Istio利用Envoy的分散式呼叫跟蹤功能來為網格中的應用提供開箱即用的跟蹤能力。Istio支援接入多種跟蹤後端系統(tracing backend),包括Zipkin、Jaege和LightStep。Istio支援與分散式跟蹤系統的兩種整合方式:
-
基於Envoy的整合(Envoy-based)
-
基於Mixer的整合(Mixer-based)
Istio支援與LightStep、Zipkin以及與Zipkin API相相容的後端比如Jaeger進行基於Envoy的整合。在這種整合中,Envoy邊車代理直接向後端跟蹤系統傳送跟蹤資訊。它負責:
-
為每個流經它的請求產生請求ID(request ID)和跟蹤頭(trace headers,比如x3-B3-TraceID)
-
為每個流經它的請求根據請求及其響應的元資料產生跟蹤跨度
-
傳送所產生的跟蹤跨度資訊到跟蹤後端
-
轉發跟蹤頭給被代理的應用
以請求ID為例,Envoy使用x-request-id頭去唯一地定位一個請求,併為它做日誌和跟蹤。Envoy會為每個從外部進入網格的請求產生x-request-id並放到HTTP頭中,也會為不帶有此資訊的內部請求產生此ID。
Istio還支援以基於Mixer的方式與某些跟蹤後端進行整合,比如Stackdriver。在這種方式中,Envoy負責為每個流經它的請求產生請求ID和跟蹤頭(比如x3-B3-TraceID),並非同步傳送給Mixer,同時轉發跟蹤頭給被代理的應用;Mixer則負責為每個請求產生跟蹤跨度資料,並把這些資料發給所配置的跟蹤後端。
儘管Envoy能夠自動產生跟蹤資訊,它還是要依賴應用將跟蹤頭資訊傳遞給後續請求。在應用中,應用需要從進來的請求中獲取以下資訊並傳遞到出去的請求中:
· x-request-id
· x-b3-traceid
· x-b3-spanid
· x-b3-parentspanid
· x-b3-sampled
· x-b3-flags
· x-ot-span-context
對於某些應用,如果所選擇的框架支援自動傳遞這些HTTP頭,那麼就不用顯式傳遞跟蹤上下文了。比如,Spring Boot框架在github中有個開源專案https://github.com/opentracing-contrib/java-spring-cloud ,能支援自動跟蹤。我們customer和preference示例程式使用符合OpenTracing標準的TracerResolver庫(https://github.com/jaegertracing/jaeger-client-java/tree/master/jaeger-tracerresolver),它會被自動載入。
在筆者的測試環境中,Istio採用基於Envoy的方式與後端跟蹤系統Jaeger整合。Jaeger的服務和pod名稱為istio-tracing,採用的Jaeger映象是docker.io/jaegertracing/all-in-one,它包含jaeger-agent、jaeger-collector和jaeger-query這三個元件。其中,Envoy代理被配置為自動地將跟蹤資訊傳送到jaeger-collector服務,jaeger-collector負責將跟蹤資料寫入儲存卷。要注意的是,這個儲存卷採用的是pod所在宿主機上的臨時資料夾。因此,當istio-tracing這個pod被重建後,所儲存的資料都會丟失。因此,在生產系統中,要考慮使用持久儲存來儲存資料。
執行下面的命令來開啟Jaeger介面:
minishift openshift service tracing --in-browser
你可以從下拉列表中選擇customer服務,再展開所產生的跟蹤,如圖6-4所示:
圖6-4. Jager中的customer-preference-recommendation跟蹤的展示
Istio能為所有流經網格的請求產生跟蹤資訊。這在開發階段會很有用,能幫助你進行充分的除錯;但是在某些時候,比如效能測試時或在生產系統中,這會對系統性能帶來一定壓力,而且數量龐大的資料也會佔用大量儲存空間。為了解決這個問題,Jaeger支援設定取樣率。取樣率通過Istio Pilot的“PILOT_TRACING_SAMPLING”環境變數進行配置。當PILOT_TRACING_SAMPLING的值為100時,表示全取樣,也就是每一次請求都會取樣;當PILOT_TRACING_SAMPLING值為50時,表示1/2取樣,也就是每兩次請求會取樣一次。Istio中的PILOT_TRACING_SAMPLING的預設值為1,表示每100個請求取樣一次。具體請查閱Jaeger官方文件。可通過下面的命令進行檢視或修改:
oc edit deployment istio-pilot -n istio-system
6.2 遙測(Metric)
Istio的另一個核心功能是網路流量的可觀測性。因為網格內服務間的所有流量都會經過Envoy代理,Istio的控制平面就能從這些代理收集日誌和指標,從而讓你可深入地瞭解網格的狀況。Istio控制平面中的一元件為Mixer,其在K8S中有兩個獨立的部署,一個是istio-policy,另一個是istio-telemetry。前者提供控制策略,後者提供遙測資料收集。
Istio網格中的每個pod中都會有一個Envoy代理,它負責在發出每個請求前呼叫istio-policy來檢查前置條件,並在請求結束後呼叫istio-telemetry來發送遙測資料。為提高效能,Envoy代理會在本地快取策略和遙測資料,以減少呼叫Mixer的次數。Mixer可配置多種後端,其中Metric後端負責接收遙測資料。在Istio部署中,通常會使用Prometheus來作為遙測後端。Prometheus(普羅米修斯)是一款開源彈性監控解決方案,它將其資料儲存至時序資料庫,且提供了多維度的資料模型、強大的查詢語言和簡單的面板來生成被監控資源的報表。
圖6-5. Mixer及其各種後端
預設地,Isito會利用Prometheus和Grafana來儲存和展示服務網格中的測量資料。在Istio的預設部署中會部署Prometheus和Grafana服務,並做了基本配置,添加了若干度量指標,使得基本遙測資料能被收集到和展示出來。通過Istio提供的CRD,還能自定義度量指標,並使得它們被自動地收集到。Grafana是一款開源資料視覺化看板,可指定多個數據源執行查詢,將枯燥的資料轉化為多維度的面板。Isito中的Grafana將Prometheus作為其資料來源,提供了多個為Istio定製的面板(Dashboard),能從多個維度展示Istio服務網格的狀態。這些服務之間的基本互動過程如圖6-6所示。
圖6-6. 有關服務之間的基本互動流程
執行下面的命令可直接在瀏覽器中開啟Prometheus面板: minishift openshift service prometheus --in-browser
在Prometheus面板中,你可以自定義測量項並圖形化結果。比如,你可以檢視recommendation服務的v2版本的總請求數,如圖6-7所示:
istio_requests_total{destination_app="recommendation", destination_version="v2"}
圖6-7.Prometheus面板
你還可以檢視pod的記憶體使用量: container_memory_rss{container_name="customer"}
Prometheus是一個非常強大的從Kubernetes/OpenShift叢集中收集和展現測量資料的工具。目前它是CNCF聯盟中頂級的已畢業專案之一。關於它的更多資訊,請訪問Prometheus官網。
執行下面的命令去獲得Grafana介面的URL: minishift openshift service grafana --url
在Grafana面板左上側選擇Istio Workload Dashboard,如圖6-8所示:
圖6-8. Grafana中的Istio Workload 面板
6.3 服務圖(Service graph)
早期Istio就提供了開箱即用的基本的服務圖形化功能。現在,Istio有了一個新的功能更全面的服務圖形化工具和總體監控監控方案,那就是由紅帽團隊建立的Kiali,如圖6-9所示。Kiali專案為一些有趣的問題提供了答案:我的Istio服務網格中有哪些微服務?它們之間是如何連線的?
本書寫作時,Kiali還需要被單獨安裝,安裝步驟還比較複雜。Kiali需要知道Jaeger和Granfana的URL,並需被設定給一些環境變數。Kiali安裝步驟如下:
# URLS for Jaeger and Grafana
export JAEGER_URL="https://tracing-istio-system.$(minishift ip).nip.io"
export GRAFANA_URL="https://grafana-istio-system.$(minishift ip).nip.io"
export IMAGE_VERSION="v0.10.0"
curl -L http://git.io/getLatestKiali | bash
如果安裝時碰到問題,請訪問Kiali使用者論壇https://groups.google.com/forum/#!forum/kiali-users。象Istio一樣,Kiali也是一個快速發展中的專案。它的主選單和Graph面板如圖6-9所示。
圖6-9. Kiali面板
Kiali的架構如圖6-10所示。它包括兩個元件Kiali front-end和Kiali back-end。前者用於介面展示,它從Kiali back-end獲取資料並展現給使用者;後者和Istio通訊,獲取和處理資料,並將資料通過Kiali front-end展現給使用者。Kiali依賴於Istio,它通過底層平臺API和Prometheus獲取Istio的資料和配置。當前Kiali支援OKD和Kubernetes,利用它們的API去獲得叢集和服務網格的配置,比如名稱空間、服務、部署等等。Kiali直接與Prometheus通訊,使用儲存在Prometheus中的資料,計算出服務網格的拓撲結構,展示遙測資料,計算健康狀態以及展示存在的問題等。
圖6-10. Kiali架構
Kiali還可以與Grafana整合,在其Workload介面中新增View in Granfana連結,點選後直接跳轉至Grafana介面,展示該應用的遙測資料,如圖6-11所示。
圖6-11. 在Kiali中整合Grafana連結
Kiali還可以與Jaeger整合,在其頁面中可以直接檢視服務的分散式呼叫跟蹤資訊,如圖6-12所示。具體配置方法請查閱https://kiali.io/documentation/distributed-tracing/。
圖12. 在Kiali中查詢服務的分散式呼叫跟蹤資訊
在Istio中,Kiali與Grafana和Jaeger的整合,是在ConfigMap kiali中配置的。它會被掛載到kiali pod中,成為kiali的配置檔案/kiali-configuration/config.yaml。在譯者的環境中,其內容如下:
istio_namespace: istio-system
auth:
strategy: login
server:
port: 20001
web_root: /kiali
external_services:
tracing:
in_cluster_url: http://tracing.istio-system/jaeger
url: http://tracing-istio-system.router.default.svc.cluster.local/jaeger
grafana:
url: http://grafana-istio-system.router.default.svc.cluster.local
prometheus:
url: http://prometheus:9090
本章中,你已經看到了好幾個開箱即用的工具和第三方工具,Istio使得你的應用的各個微服務元件變得越來越可視和可觀測。在前面章節中介紹瞭如何引入錯誤和網路延遲,現在,通過這些工具,你就能更好地跟蹤問題在哪裡了。
書籍英文版下載連結為 https://developers.redhat.com/books/introducing-istio-service-mesh-microservices/,作者 Burr Sutter 和 Christian Posta。
本中文譯稿版權由本人所有。水平有限,錯誤肯定是有的,還請海涵。
感謝您的閱讀,歡迎關注我的微信公眾號:
&n