生產中的 Istio 和 Kubernetes。 第 2 部分. 追踪

在過去 文章 我們研究了 Service Mesh Istio 的基本元件,熟悉了該系統並回答了開始使用 Istio 時通常出現的主要問題。在這一部分中,我們將了解如何透過網路組織追蹤資訊的收集。

生產中的 Istio 和 Kubernetes。 第 2 部分. 追踪

當許多開發人員和系統管理員聽到 Service Mesh 這個詞時,他們首先想到的是追蹤。事實上,我們為每個網路節點新增了一個特殊的代理伺服器,所有 TCP 流量都經過該網路節點。看來現在可以輕鬆地發送有關網路上所有網路互動的資訊。不幸的是,實際上有許多細微差別需要考慮。讓我們看看它們。

誤解一:我們可以免費獲得線上健行數據。

事實上,為了相對自由,我們只能得到我們系統中透過箭頭連接的節點以及服務之間傳遞的資料速率(實際上只是單位時間的位元組數)。然而,在大多數情況下,我們的服務是透過某種應用層協定進行通訊的,例如 HTTP、gRPC、Redis 等。當然,我們希望看到專門針對這些協定的追蹤資訊;我們希望看到請求速率,而不是資料速率。我們想要了解使用我們的協定的請求的延遲。最後,我們希望查看請求從登入系統到接收使用者回應的完整路徑。這個問題已經不再那麼容易解決了。

首先,讓我們從 Istio 架構的角度來看一下發送追蹤跨度是什麼樣的。正如我們從第一部分中記得的那樣,Istio 有一個名為 Mixer 的獨立元件用於收集遙測資料。然而,在當前版本 1.0.* 中,發送是直接從代理伺服器(即 envoy proxy)完成的。 Envoy 代理程式支援使用開箱即用的 zipkin 協定發送追蹤範圍。可以連接其他協議,但只能透過插件。透過 Istio,我們立即得到了一個組裝並配置好的 envoy 代理,它只支援 zipkin 協定。例如,如果我們想使用 Jaeger 協定並透過 UDP 發送追蹤範圍,那麼我們需要建立自己的 istio-proxy 映像。 istio-proxy 支援自訂插件,但仍處於 alpha 版本。因此,如果我們不想進行大量自訂設置,則用於儲存和接收追蹤跨度的技術範圍就會減少。事實上,在主要係統中,現在您可以使用 Zipkin 本身或 Jaeger,但使用 zipkin 相容協定將所有內容傳送到那裡(效率低得多)。 zipkin 協定本身涉及透過 HTTP 協定將所有追蹤資訊傳送給收集器,這是相當昂貴的。

正如我已經說過的,我們想要追蹤應用程式級協議。這意味著每個服務旁邊的代理伺服器必須了解現在正在發生什麼類型的互動。預設情況下,Istio 將所有連接埠配置為普通 TCP,這表示不會發送任何追蹤。為了發送追蹤,您必須先在主網格配置中啟用此選項,並且非常重要的是,根據服務中使用的協定命名 kubernetes 服務實體的所有連接埠。也就是說,例如,像這樣:

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
  - port: 80
    targetPort: 80
    name: http
  selector:
    app: nginx

您也可以使用 http-magic 等複合名稱(Istio 將看到 http 並將該連接埠識別為 http 端點)。格式為:proto-extra。

為了不修補大量配置來確定協議,您可以使用一種骯髒的解決方法:在 Pilot 元件剛剛運行時修補它 執行協定定義邏輯。當然,最終,有必要將此邏輯更改為標準,並切換到所有連接埠的命名約定。

為了了解協定是否真正正確定義,您需要進入任何具有 envoy 代理程式的 sidecar 容器,並使用位置 /config_dump 向 envoy 介面的管理連接埠發出請求。在產生的配置中,您需要查看所需服務的操作欄位。它在 Istio 中用作發出請求的標識符。為了在 Istio 中自訂此參數的值(然後我們將在追蹤系統中看到它),有必要在啟動 sidecar 容器的階段指定 serviceCluster 標誌。例如,可以從向下的 kubernetes API 取得的變數這樣計算:

--serviceCluster ${POD_NAMESPACE}.$(echo ${POD_NAME} | sed -e 's/-[a-z0-9]*-[a-z0-9]*$//g')

了解特使中追蹤如何運作的一個很好的例子是 這裡.

用於發送追蹤跨度的端點本身也必須在 Envoy 代理程式啟動標誌中指定,例如: --zipkinAddress tracing-collector.tracing:9411

誤解二:我們可以透過開箱即用的系統以低廉的成本獲得完整的請求跟踪

不幸的是,事實並非如此。實現的複雜性取決於您已經如何實現服務互動。這是為什麼?

事實上,為了讓 istio-proxy 能夠理解傳入服務請求與離開相同服務的請求的對應關係,僅僅攔截所有流量是不夠的。您需要有某種通訊標識符。 HTTP Envoy 代理程式使用特殊標頭,Envoy 透過該標頭了解對服務的哪個特定請求會產生對其他服務的特定請求。此類標頭的清單:

  • x-請求-id,
  • x-b3-traceid,
  • x-b3-西班牙,
  • x-b3-parentspanid,
  • x-b3-採樣,
  • x-b3-標誌,
  • x-ot-span-上下文。

如果你有一個單點,例如一個基本的客戶端,你可以在其中添加這樣的邏輯,那麼一切都很好,你只需要等待這個庫為所有客戶端更新。但是,如果您有一個非常異質的系統,並且透過網路從一個服務轉移到另一個服務沒有統一,那麼這很可能是一個大問題。如果不加入這樣的邏輯,所有的追蹤資訊都將只是「單層」。也就是說,我們將接收所有服務間交互,但它們不會被黏合到通過網路的單一通道鏈中。

結論

Istio 提供了一個方便的工具來透過網路收集追蹤信息,但您必須了解,為了實現,您需要調整您的系統並考慮 Istio 實現的功能。因此,需要解決兩個要點:定義應用程式層級的協定(必須得到 envoy 代理程式的支援)和設定從來自服務的請求轉送有關請求到服務的連線資訊(使用標頭) ,對於 HTTP 協定)。當這些問題得到解決後,我們就有了一個強大的工具,可以讓我們透明地從網絡收集信息,即使是在用許多不同語言和框架編寫的非常異質的系統中。

在下一篇關於 Service Mesh 的文章中,我們將討論 Istio 的最大問題之一——每個 sidecar 代理容器對 RAM 的大量消耗,並討論如何處理它。

來源: www.habr.com

添加評論