詳細了解 Linkerd 2.10 基礎功能,一起步入 Service Mesh 微服務架構時代


Linkerd 提供了許多功能,如:自動 mTLS自動代理注入分布式追蹤故障注入高可用性HTTP/2 和 gRPC 代理負載均衡多集群通信重試和超時遙測和監控流量拆分(金絲雀、藍/綠部署)等。

Linkerd 2.10 中文手冊持續修正更新中:

Linkerd 2.10 系列

功能概述

  • 自動 mTLS:Linkerd 自動為網格應用程序之間的所有通信啟用相互傳輸層安全性 (TLS)。
  • 自動代理注入:Linkerd 會自動將數據平面代理注入到基於 annotations 的 pod 中。
  • 容器網絡接口插件:Linkerd 能被配置去運行一個 CNI 插件,該插件自動重寫每個 pod 的 iptables 規則。
  • 儀表板和 Grafana:Linkerd 提供了一個 Web 儀表板,以及預配置的 Grafana 儀表板。
  • 分布式追蹤:您可以在 Linkerd 中啟用分布式跟蹤支持。
  • 故障注入:Linkerd 提供了以編程方式將故障注入服務的機制。
  • 高可用性:Linkerd 控制平面可以在高可用性 (HA) 模式下運行。
  • HTTP、HTTP/2 和 gRPC 代理:Linkerd 將自動為 HTTP、HTTP/2 和 gRPC 連接啟用高級功能(包括指標、負載平衡、重試等)。
  • Ingress:Linkerd 可以與您選擇的 ingress controller 一起工作。
  • 負載均衡:Linkerd 會自動對 HTTP、HTTP/2 和 gRPC 連接上所有目標端點的請求進行負載平衡。
  • 多集群通信:Linkerd 可以透明且安全地連接運行在不同集群中的服務。
  • 重試和超時:Linkerd 可以執行特定於服務的重試和超時。
  • 服務配置文件:Linkerd 的服務配置文件支持每條路由指標以及重試和超時。
  • TCP 代理和協議檢測:Linkerd 能夠代理所有 TCP 流量,包括 TLS 連接、WebSockets 和 HTTP 隧道。
  • 遙測和監控:Linkerd 會自動從所有通過它發送流量的服務收集指標。
  • 流量拆分(金絲雀、藍/綠部署):Linkerd 可以動態地將一部分流量發送到不同的服務。

HTTP、HTTP/2 和 gRPC 代理

Linkerd 可以代理所有 TCP 連接,並將自動為 HTTP、HTTP/2 和 gRPC 連接
啟用高級功能(包括指標、負載平衡、重試等)。

  • 由於早期版本中的 bug,使用 grpc-go 的 gRPC 應用程序必須使用 1.3 或更高版本。
  • 由於早期版本中的 bug,使用 @grpc/grpc-js 的 gRPC 應用程序必須使用 1.1.0 或更高版本。

TCP 代理和協議檢測

Linkerd 能夠代理所有 TCP 流量,包括 TLS 連接、WebSockets 和 HTTP 隧道。

大多數情況下,Linkerd 無需配置即可完成此操作。
為此,Linkerd 執行 protocol detection(協議檢測) 以確定
流量是 HTTP 還是 HTTP/2(包括 gRPC)。如果 Linkerd 檢測到連接
是 HTTP 或 HTTP/2,Linkerd 將自動提供 HTTP 級別的指標(metrics)和路由(routing)。

如果 Linkerd 不能確定連接是使用 HTTP 還是 HTTP/2,
Linkerd 會將連接代理為普通 TCP 連接,
應用 mTLS 並像往常一樣提供字節級指標(byte-level metrics)。

客戶端啟動的 HTTPS(Client-initiated HTTPS) 將被視為 TCP,而不是 HTTP,
因為 Linkerd 將無法觀察連接上的 HTTP 事務。

配置協議檢測

在某些情況下,Linkerd 的協議檢測無法運行,
因為它沒有提供足夠的客戶端數據。
這可能會導致創建連接延遲 10 秒,
因為協議檢測代碼會等待更多數據。
在使用“服務器優先(server-speaks-first)”協議或服務器
在客戶端發送數據之前發送數據的協議時,經常會遇到這種情況 ,
可以通過為 Linkerd 提供一些額外的配置來避免。

不管底層協議是什么,客戶端發起的 TLS 連接不需要任何額外的配置,
因為 TLS 本身是一個客戶端優先協議(client-speaks-first)。

配置協議檢測有兩種基本機制:
不透明端口(opaque ports)和跳過端口(skip ports)。
將端口標記為不透明(opaque)會指示 Linkerd 將連接代理為 TCP 流,而不是嘗試協議檢測。
將端口標記為跳過(skip)會完全繞過代理。
不透明端口通常是首選(因為 Linkerd 可以提供 mTLS、TCP 級別的指標等),
但至關重要的是,不透明端口只能用於集群內部的服務。

默認情況下,Linkerd 會自動將一些端口標記為不透明,
包括 SMTP、MySQL、PostgresQL 和 Memcache 的默認端口。
使用這些協議、使用默認端口且位於集群內部的服務不需要進一步配置。

下表總結了一些常見的 server-speaks-first 協議以及處理它們所需的配置。
“on-cluster config” 列指的是 destination 在同一個集群時的配置;
當目的地在集群外部時,“集群外配置(off-cluster config)”。

Protocol Default port(s) On-cluster config Off-cluster config
SMTP 25, 587 none* skip ports
MySQL 3306 none* skip ports
MySQL with Galera replication 3306, 4444, 4567, 4568 opaque ports for 3306, 4444; and skip ports for 4567, 4568 skip ports
PostgreSQL 5432 none* skip ports
Redis 6379 opaque ports skip ports
ElasticSearch 9300 opaque ports skip ports
Memcache 11211 none* skip ports

* 如果使用標准端口,則無需配置。如果使用非標准端口,則必須將該端口標記為不透明(opaque)。

將端口標記為不透明

您可以使用 config.linkerd.io/opaque-ports 注釋將端口標記為不透明。
這指示 Linkerd 跳過該端口的協議檢測。

可以在工作負載(workload)、服務(service)或
命名空間(namespace)上設置此注釋。
在工作負載上設置它會告訴該工作負載的
被 mesh 的客戶端(meshed clients)跳過與工作負載建立的連接的協議檢測,
並告訴 Linkerd 在反向代理(reverse-proxying)傳入連接時跳過協議檢測。
在服務上設置它會告訴被 mesh 的客戶端(meshed clients)在代理連接到服務時跳過協議檢測。
在命名空間上設置它會將此行為應用於該命名空間中的所有服務和工作負載。

由於此 annotation 通知被 mesh 的 clients 的行為,
因此它可以應用於使用服務器優先(server-speaks-first)協議的服務,即使服務本身沒有被網格。

可以在運行 linkerd inject 時使用 --opaque-ports 標志來
設置 opaque-ports annotation。
例如,對於運行在集群上的 MySQL 數據庫使用
非標准端口 4406,您可以使用以下命令:

linkerd inject mysql-deployment.yml --opaque-ports=4406 \
  | kubectl apply -f -
 linkerd inject mysql-service.yml --opaque-ports=4406 \
  | kubectl apply -f -

可以以逗號分隔的字符串形式提供多個端口。
您提供的值將替換而不是增加不透明端口的默認列表。

跳過代理

有時需要完全繞過代理。例如,當連接到集群外的 server-speaks-first 目的地時,
沒有可以設置 config.linkerd.io/opaque-ports annotation 的服務資源。

在這種情況下,您可以在運行 linkerd inject
使用 --skip-outbound-ports 標志來配置資源以在
發送到這些端口時完全繞過代理。(類似地,--skip-inbound-ports 標志將
配置資源以繞過代理以連接到這些端口的傳入連接。)

跳過代理對於這些情況以及診斷問題很有用,但除此之外幾乎沒有必要。

與不透明端口一樣,可以以逗號分隔的字符串形式提供多個跳過端口。

重試和超時

自動重試是服務網格用於優雅地處理部分或瞬時應用程序故障的最強大和最有用的機制之一。
如果實施不當,重試可能會將小錯誤放大為系統范圍的中斷。
出於這個原因,我們確保它們的實施方式可以提高系統的可靠性,同時限制風險。

超時與重試密切相關。一旦請求被重試一定次數,
限制客戶端在完全放棄之前等待的總時間就變得很重要。
想象多次重試迫使客戶端等待 10 秒。

服務配置文件可以將某些路由定義為可重試或指定路由超時。
這將導致 Linkerd 代理在調用該服務時執行適當的重試或超時。
重試和超時總是在 outbound (client) 端執行。

如果使用無頭服務(headless services),則無法檢索服務配置文件(service profiles)。
Linkerd 根據目標 IP 地址讀取服務發現信息,
如果這恰好是 pod IP 地址,則它無法判斷 pod 屬於哪個服務。

重試如何出錯

傳統上,在執行重試時,您必須在放棄之前指定最大重試次數。
不幸的是,以這種方式配置重試有兩個主要問題。

選擇最大重試次數是一個猜謎游戲

你需要選擇一個足夠高的數字來產生影響;
允許多次重試通常是謹慎的,如果您的服務不太可靠,您可能希望允許多次重試。
另一方面,允許過多的重試嘗試會在系統上產生大量額外的請求和額外的負載。
執行大量重試也會嚴重增加需要重試的請求的延遲。
在實踐中,您通常會從一頂帽子中選擇一個最大的重試次數(3?),
然后通過反復試驗來調整它,直到系統大致按照您希望的方式運行。

以這種方式配置的系統容易受到重試風暴的攻擊

當一項服務啟動(出於任何原因)遇到比正常故障率更高的故障率時,
retry storm 就開始了。
這會導致其客戶端重試那些失敗的請求。
重試帶來的額外負載會導致服務進一步減慢速度並導致更多請求失敗,
從而觸發更多重試。如果將每個客戶端配置為最多重試 3 次,
則發送的請求數量可能會增加四倍!更糟糕的是,
如果任何客戶端的客戶端配置了重試,重試次數就會成倍增加,
並且可以將少量錯誤變成自我造成的拒絕服務攻擊。

重試預算來救援

為了避免重試風暴和任意重試次數的問題,使用重試預算配置重試。
Linkerd 不是為每個請求指定固定的最大重試次數,
而是跟蹤常規請求和重試之間的比率,並將此數量保持在可配置的限制以下。
例如,您可以指定您希望重試最多增加 20% 的請求。
Linkerd 將在保持該比率的同時盡可能多地重試。

配置重試總是在提高成功率和不給系統增加太多額外負載之間進行權衡。
重試預算通過讓您指定系統願意從重試中接受多少額外負載來明確權衡。

自動 mTLS

默認情況下,Linkerd 通過在 Linkerd 代理之間建立和驗證安全的私有 TLS 連接,
為網狀 Pod 之間的大多數 TCP 流量自動啟用相互傳輸層安全性 (mTLS)。
這意味着 Linkerd 可以向您的應用程序添加經過身份驗證的加密通信,
而您只需做很少的工作。由於 Linkerd 控制平面也在數據平面上運行,
這意味着 Linkerd 控制平面組件之間的通信也通過 mTLS 自動保護。

它是如何工作的?

簡而言之,Linkerd 的控制平面向代理頒發 TLS 證書,
這些證書的范圍限定為包含 Pod 的
Kubernetes ServiceAccount
並每 24 小時自動輪換一次。代理使用這些證書來加密和驗證到其他代理的 TCP 流量。

為此,Linkerd 在集群中維護了一組憑據:信任錨(trust anchor)、
頒發者證書(issuer certificate)和私鑰(private key)。
這些憑據在安裝時由 Linkerd 本身生成,或者由外部源
(例如 Vault
cert-manager
頒發者證書和私鑰放置在
Kubernetes Secret 中。
默認情況下,Secret 放置在 linkerd 命名空間中,
並且只能由 Linkerd 控制平面 的 identity 組件使用的服務帳戶讀取。

在數據平面方面,每個代理都在環境變量中傳遞信任錨(trust anchor)。
在啟動時,代理會生成一個私鑰,
存儲在
tmpfs emptyDir
中,該私鑰留在內存中並且永遠不會離開 pod。
代理連接到控制平面的身份(identity)組件,驗證與信任錨的身份(identity)連接,
並發出證書簽名請求 (CSR)
CSR 包含一個初始證書,其身份設置為 pod 的
Kubernetes ServiceAccount
以及實際的服務帳戶令牌,以便該身份可以驗證 CSR 是否有效。
驗證后,簽名的信任包將返回給代理,代理可以將其用作客戶端和服務器證書。
這些證書的范圍為 24 小時,並使用相同的機制動態刷新。

當注入 Pod 的代理從應用程序容器接收到出站連接時,
它會通過使用 Linkerd 控制平面查找該 IP 地址來執行服務發現。
當目的地在 Kubernetes 集群中時,控制平面為代理提供目的地的端點地址以及元數據。
當身份名稱包含在此元數據中時,這向代理表明它可以啟動雙向 TLS。
當代理連接到目標時,它會發起 TLS 握手,驗證目標代理的證書是否已針對預期的身份名稱進行簽名。

維護

linkerd install 生成的信任錨在 365 天后過期,
必須手動輪換
或者,您可以自己提供信任錨並控制到期日期。

默認情況下,頒發者證書和密鑰不會自動輪換。
您可以使用 cert-manager 設置自動輪換

注意事項和未來工作

Linkeder 自動加密和驗證集群中所有通信的能力存在一些已知的缺陷。
這些缺口將在以后的版本中修復:

  • Linkerd 目前不強制執行 mTLS。網格內的任何未加密請求都將隨機升級到 mTLS。
    Linkerd 不會自動對來自網格內部或外部的任何請求進行 mTLS。
    這將在未來的 Linkerd 版本中解決,可能作為選擇加入行為,
    因為它可能會破壞一些現有的應用程序。

  • 理想情況下,Linkerd 使用的 ServiceAccount 令牌不會
    與該令牌的其他潛在用途共享。
    在未來的 Kubernetes 版本中,Kubernetes 將
    支持 audience/time-bound 的 ServiceAccount 令牌,
    Linkerd 將使用這些令牌。

Ingress

為簡單起見,Linkerd 沒有提供自己的 ingress controller。
相反,Linkerd 旨在與您選擇的 ingress controller 一起工作。

遙測和監控

Linkerd 最強大的功能之一是其圍繞可觀察性(observability)的廣泛工具集—
在網格應用程序中測量和報告觀察到的行為。
雖然 Linkerd 沒有直接洞察服務代碼的內部結構,
但它對服務代碼的外部行為有着巨大的洞察力。

要訪問 Linkerd 的可觀察性功能,您只需要安裝 Viz 擴展:

linkerd viz install | kubectl apply -f -

Linkerd 的遙測和監控功能會自動運行,無需開發人員進行任何工作。這些功能包括:

  • 記錄 HTTP、HTTP/2 和 gRPC 流量的頂級(“黃金”)指標(請求量、成功率和延遲分布)。
  • 記錄其他 TCP 流量的 TCP 級別指標(輸入/輸出字節等)。
  • 報告每個服務、每個調用方(caller)/被調用方(callee)對或每個路由/路徑(使用服務配置文件)的指標。
  • 生成拓撲圖,顯示服務之間的運行時關系。
  • 實時、按需請求采樣。

可以通過多種方式使用這些數據:

  • 通過 Linkerd CLI,
    例如:使用 linkerd viz statlinkerd viz routes
  • 通過 Linkerd dashboard 和 pre-built Grafana dashboards。
  • 直接來自 Linkerd 的內置 Prometheus 實例

黃金指標

成功率

這是一個時間窗口(默認為 1 分鍾)內成功請求的百分比。

在命令 linkerd viz routes -o wide 的輸出中,
此度量分為 EFFECTIVE_SUCCESS 和 ACTUAL_SUCCESS。
對於配置了重試的路由,前者計算重試后的成功百分比(客戶端感知),
后者計算重試前的成功率(可能暴露服務的潛在問題)。

流量(每秒請求數)

這概述了對 service/route 的需求量。
與成功率一樣,linkerd viz routes --o wide 將此指標
拆分為 EFFECTIVE_RPS 和 ACTUAL_RPS,分別對應於重試前后的比率。

延遲

每個 service/route 的服務請求所花費的時間分為第 50、95 和 99 個百分位數。
較低的百分位數可讓您大致了解系統的平均性能,而尾部百分位數有助於捕捉異常行為。

Linkerd 指標的生命周期

Linkerd 並非設計為長期歷史指標存儲。
雖然 Linkerd 的 Viz 擴展確實包含一個 Prometheus 實例,
但該實例會在很短的固定時間間隔(目前為 6 小時)內使指標過期。

相反,Linkerd 旨在補充(supplement)您現有的指標存儲。
如果 Linkerd 的指標有價值,您應該將它們導出到您現有的歷史指標存儲中。

負載均衡

對於 HTTP、HTTP/2 和 gRPC 連接,
Linkerd 會自動在所有目標端點之間對請求進行負載平衡,無需任何配置。
(對於 TCP 連接,Linkerd 會平衡連接。)

Linkerd 使用一種稱為 EWMA 或
指數加權移動平均(exponentially weighted moving average)的算法來自動將請求發送到最快的端點。
這種負載平衡可以改善端到端(end-to-end)延遲。

服務發現

對於不在 Kubernetes 中的目的地,Linkerd 將在 DNS 提供的端點之間進行平衡。

對於 Kubernetes 中的目的地,Linkerd 將在 Kubernetes API 中查找 IP 地址。
如果 IP 地址對應於一個服務,Linkerd 將在該服務的端點之間進行負載平衡,
並應用該服務的服務配置文件中的任何策略。
另一方面,如果 IP 地址對應一個 Pod,
Linkerd 將不會執行任何負載均衡或應用任何服務配置文件。

如果使用無頭服務(headless services),則無法檢索服務的端點。
因此,Linkerd 不會執行負載均衡,而是只路由到目標 IP 地址。

負載均衡 gRPC

Linkerd 的負載均衡對於 Kubernetes 中的 gRPC(或 HTTP/2)服務特別有用,
對於這些服務,Kubernetes 的默認負載均衡是無效的

自動代理注入

當命名空間或任何工作負載(例如部署或 Pod)上存在
linkerd.io/inject: enabled annotation 時,
Linkerd 會自動將數據平面代理添加到 Pod。這稱為“代理注入(proxy injection)”。

代理注入也是代理配置發生的地方。
雖然很少需要,但您可以通過在注入之前在資源級別
設置額外的 Kubernetes annotations 來配置代理設置。

細節

代理注入是作為 Kubernetes admission
webhook
實現的。
這意味着代理會添加到 Kubernetes 集群本身內的 pod 中,
而不管 pod 是由 kubectl、CI/CD 系統還是任何其他系統創建的。

對於每個 pod,注入兩個容器:

  1. linkerd-init,一個 Kubernetes Init
    Container
    ,它配置 iptables 以通過代理自動轉發所有傳入和傳出的 TCP 流量。
    (請注意,如果 Linkerd CNI Plugin 已啟用,則此容器不存在。)
  2. linkerd-proxy,Linkerd 數據平面代理本身。

請注意,簡單地將 annotation 添加到具有預先存在的 pod 的資源不會自動注入這些 pod。
您將需要更新 pod(例如使用 kubectl rollout restart 等)以便注入它們。
這是因為 Kubernetes 在需要更新底層資源之前不會調用 webhook。

覆蓋注入

通過添加 linkerd.io/inject: disabled annotation,
可以為 pod 或部署禁用自動注入,否則將為其啟用。

手動注入

linkerd inject CLI 命令是一個文本轉換,
默認情況下,它只是將 inject annotation 添加到給定的 Kubernetes 清單。

或者,這個命令也可以使用 --manual 標志在客戶端執行完全注入。
這是 Linked2.4 之前的默認行為;
但是,向集群側注入數據可以更容易地確保
數據平面始終存在並正確配置,而不管 pod 是如何部署的。

容器網絡接口插件

Linkerd installs 可以配置去運行一個
CNI plugin
該插件自動重寫每個 pod 的 iptables 規則。
通過 pod 的 linkerd-proxy 容器路由網絡流量需要重寫 iptables。
啟用 CNI 插件后,單個 Pod 不再需要包含需要 NET_ADMIN 功能來執行重寫的 init 容器。
這在集群管理員限制該功能的集群中很有用。

安裝

使用 Linkerd CNI 插件需要先在集群上成功安裝 linkerd-cni DaemonSet,
然后再安裝 Linkerd 控制平面。

使用 CLI

要安裝 linkerd-cni DaemonSet,請運行:

linkerd install-cni | kubectl apply -f -

一旦 DaemonSet 啟動並運行,所有包含 linkerd-proxy 容器(包括 Linkerd 控制平面)
的后續安裝都不再需要包含 linkerd-init 容器。
init 容器的省略由控制平面安裝時的 --linkerd-cni-enabled 標志控制。

安裝 Linkerd 控制平面,使用:

linkerd install --linkerd-cni-enabled | kubectl apply -f -

這將在 linkerd-config ConfigMap 中設置 cniEnabled 標志。
所有后續代理注入都將讀取此字段並省略 init 容器。

使用 Helm

首先確保您的 Helm 本地緩存已更新:

helm repo update

helm search linkerd2-cni
NAME                      CHART VERSION  APP VERSION    DESCRIPTION
linkerd-edge/linkerd2-cni   20.1.1       edge-20.1.1    A helm chart containing the resources needed by the Linke...
linkerd-stable/linkerd2-cni  2.7.0       stable-2.7.0   A helm chart containing the resources needed by the Linke...

運行以下命令安裝 CNI DaemonSet:

# install the CNI plugin first
helm install linkerd2-cni linkerd2/linkerd2-cni

# ensure the plugin is installed and ready
linkerd check --pre --linkerd-cni-enabled

對於低於 v3 的 Helm 版本,必須專門傳遞 --name 標志。
在 Helm v3 中,它已被棄用,並且是上面指定的第一個參數。

此時,您已准備好在啟用 CNI 的情況下安裝 Linkerd。
您可以按照使用 Helm 安裝 Linkerd 來執行此操作。

附加配置

linkerd install-cni 命令包括可用於自定義安裝的附加標志。
有關更多信息,請參閱 linkerd install-cni --help
請注意,許多標志類似於運行 linkerd 注入時可用於配置代理的標志。
如果在運行 linkerd install-cni 時更改了默認值,
則需要確保在運行 linkerd inject 時進行相應的更改。

最重要的標志是:

  1. --dest-cni-net-dir: 這是 CNI 配置所在節點上的目錄。 默認為: /etc/cni/net.d
  2. --dest-cni-bin-dir: 這是 CNI 插件二進制文件所在的節點上的目錄。默認為:/opt/cni/bin
  3. --cni-log-level: 將此設置為 debug 將允許更詳細的日志記錄。
    要查看 CNI 插件日志,您必須能夠查看 kubelet 日志。
    一種方法是登錄節點並使用 journalctl -t kubelet
    字符串 linkerd-cni: 可用作查找插件日志輸出的搜索。

升級 CNI 插件

由於 CNI 插件基本上是無狀態的,因此不需要單獨的 upgrade 命令。
如果您使用 CLI 升級 CNI 插件,您可以執行以下操作:

linkerd install-cni   | kubectl apply --prune -l  linkerd.io/cni-resource=true -f -

請記住,如果您是從實驗版本(experimental version)升級插件,則需要卸載並重新安裝。

儀表板和 Grafana

除了命令行界面,
Linkerd 還提供了一個 Web 儀表板和預配置的 Grafana 儀表板。

要訪問此功能,您需要安裝 Viz 擴展:

linkerd viz install | kubectl apply -f -

Linkerd 儀表板

Linkerd 儀表板提供實時服務發生情況的高級視圖。
它可用於查看“黃金”指標(成功率、請求/秒和延遲)、
可視化服務依賴關系並了解特定服務路由的健康狀況。
拉起它的一種方法是從命令行運行 linkerd viz dashboard

Grafana

作為控制平面的一個組件,Grafana 為您的服務提供開箱即用的可操作儀表板。
可以查看高級指標並深入了解細節,甚至是 pod。

開箱即用的儀表板包括:

Top Line Metrics

Deployment Detail

Pod Detail

Linkerd Health

分布式追蹤

跟蹤可以成為調試分布式系統性能的寶貴工具,
尤其是用於識別瓶頸和了解系統中每個組件的延遲成本。
Linkerd 可以配置為從代理發出跟蹤跨度,
允許您准確查看請求和響應在內部花費的時間。

與 Linkerd 的大多數功能不同,分布式跟蹤需要更改代碼和配置。

此外,Linkerd 提供了許多通常與分布式跟蹤相關的功能,無需配置或應用程序更改,包括:

  • 實時服務拓撲和依賴關系圖
  • 聚合服務運行狀況、延遲和請求量
  • 聚合 path / route 運行狀況、延遲和請求量

例如,Linkerd 可以顯示服務的所有傳入和傳出依賴項的實時拓撲,
而無需分布式跟蹤或任何其他此類應用程序修改:

Linkerd 儀表板顯示自動生成的拓撲圖

同樣,Linkerd 可以為每個服務和每個 route 提供黃金指標,
同樣不需要分布式跟蹤或任何其他此類應用程序修改:

Linkerd 儀表板顯示自動生成的路由指標

使用分布式跟蹤

也就是說,分布式跟蹤肯定有其用途,Linkerd 使這盡可能簡單。
Linkerd 在分布式跟蹤中的作用實際上非常簡單:
當 Linkerd 數據平面代理(data plane proxy)在代理的 HTTP 請求中
看到跟蹤頭(tracing header)時,
Linkerd 將為該請求發出跟蹤范圍(trace span)。
此跨度將包括有關在 Linkerd 代理中花費的確切時間量的信息。
當與軟件配合使用來收集、存儲和分析這些信息時,
這可以提供對 mesh 行為的重要洞察。

要使用此功能,您還需要引入幾個額外的系統中的組件,
包括啟動特定請求跟蹤的入口層(ingress layer)、
應用程序的客戶端庫(或傳播跟蹤頭的機制)、
收集跨度數據並將其轉換為跟蹤的跟蹤收集器,
以及跟蹤后端存儲跟蹤數據並允許用戶查看/查詢它。

故障注入

故障注入是混沌工程的一種形式,通過人為地增加服務的錯誤率來觀察對整個系統的影響。
傳統上,這需要修改服務的代碼,以添加一個執行實際工作的錯誤注入庫。
Linkeder 可以做到這一點,而不需要任何服務代碼更改,只需要一點配置。

高可用性

對於生產工作負載,Linkerd 的控制平面可以在高可用性 (HA) 模式下運行。 這種模式:

  • 運行關鍵控制平面組件的三個副本。
  • 在控制平面組件上設置生產就緒(production-ready) CPU 和內存資源請求。
  • 在數據平面代理上設置生產就緒的 CPU 和內存資源請求
  • 要求 proxy auto-injector 可用於任何要調度的 pod。
  • 在關鍵控制平面組件上設置反關聯性策略(anti-affinity
    policies)

    以確保在可能的情況下,默認情況下將它們安排在單獨的節點和單獨的區域中。

啟用 HA

您可以在控制平面安裝時使用 --ha 標志啟用 HA 模式:

linkerd install --ha | kubectl apply -f -

另請注意,可視化擴展還支持具有類似特征的 --ha 標志:

linkerd viz install --ha | kubectl apply -f -

您可以在安裝時通過將其他標志傳遞給 install 命令來覆蓋 HA 行為的某些方面。
例如,您可以使用 --controller-replicas 標志覆蓋關鍵組件的副本數:

linkerd install --ha --controller-replicas=2 | kubectl apply -f -

請參閱完整的 install CLI 文檔以供參考。

linkerd upgrade 命令可用於在現有控制平面上啟用 HA 模式:

linkerd upgrade --ha | kubectl apply -f -

代理注入器故障策略

HA 代理注入器(proxy injector)部署了更嚴格的故障策略(failure policy),
以強制執行 automatic proxy injection。
此設置可確保在沒有 Linkerd 代理的情況下,
不會意外安排帶注解的工作負載在您的集群上運行。(當代理注入器關閉時可能會發生這種情況。)

如果在准入階段由於無法識別或超時錯誤導致代理注入過程失敗,
則工作負載准入將被 Kubernetes API 服務器拒絕,部署將失敗。

因此,始終至少有一個運行在集群上的代理注入器的健康副本非常重要。

如果您不能保證集群上健康的代理注入器的數量,
您可以通過將其值設置為 Ignore 來放松 webhook 故障策略,如 Linkerd
Helm chart
所示。

有關准入 webhook 失敗策略的更多信息,請參閱 Kubernetes
documentation

排除 kube-system 命名空間

根據 Kubernetes documentation

的建議,應該為 kube-system 命名空間禁用代理注入器。

這可以通過使用以下標簽標記 kube-system 命名空間來完成:

kubectl label namespace kube-system config.linkerd.io/admission-webhooks=disabled

在具有此標簽的命名空間中工作負載的准入階段,Kubernetes API 服務器不會調用代理注入器。

Pod 反關聯規則

所有關鍵控制平面組件都部署了 pod 反關聯性(anti-affinity)規則以確保冗余。

Linkerd 使用 requiredDuringSchedulingIgnoredDuringExecution pod anti-affinity 規則
來確保 Kubernetes 調度程序不會將關鍵組件的副本並置在同一節點上。
還添加了一個 preferredDuringSchedulingIgnoredDuringExecution pod anti-affinity 規則,
以嘗試在可能的情況下在不同區域中安排副本。

為了滿足這些反關聯(anti-affinity)規則,HA 模式假設 Kubernetes 集群中始終至少有三個節點。
如果違反此假設(例如,集群縮小到兩個或更少的節點),則系統可能會處於非功能(non-functional)狀態。

請注意,這些反關聯性規則不適用於 Prometheus 和 Grafana 等附加組件。

縮放 Prometheus

Linkerd Viz 擴展提供了一個預配置的 Prometheus pod,但對於生產工作負載,
我們建議設置您自己的 Prometheus 實例。

在規划存儲 Linkerd 時間序列數據的內存容量時,通常的指導是每個網格 pod 5MB。

如果您的 Prometheus 由於來自數據平面的數據量而遇到定期 OOMKilled 事件,
則可以調整的兩個關鍵參數是:

  • storage.tsdb.retention.time 定義將采樣保留多長時間。
    更高的值意味着需要更多的內存來將數據保存更長時間。
    降低此值將減少 OOMKilled 事件的數量,因為數據保留的時間較短
  • storage.tsdb.retention.size 定義可以為塊存儲的最大字節數。
    較低的值也將有助於減少 OOMKilled 事件的數量

使用 Cluster AutoScaler

Linkerd 代理將其 mTLS 私鑰存儲在
tmpfs emptyDir 卷中,
以確保此信息永遠不會離開 pod。
這會導致 Cluster AutoScaler 的默認設置無法縮小具有注入工作負載副本的節點。

解決方法是使用 cluster-autoscaler.kubernetes.io/safe-to-evict: "true" annotation 來注入工作負載。
如果您可以完全控制 Cluster AutoScaler 配置,
則可以使用 --skip-nodes-with-local-storage=false 選項啟動 Cluster AutoScaler。

多集群通信

Linkerd 可以以安全、對應用程序完全透明且獨立於網絡拓撲的方式
跨集群邊界連接 Kubernetes 服務。這種多集群功能旨在提供:

  1. 統一的信任域。 在集群邊界內和跨集群邊界的每一步都驗證源和目標工作負載的身份。
  2. 單獨的故障域。 一個集群的故障允許剩余的集群運行。
  3. 支持異構網絡。 由於集群可以跨越雲、VPC、本地數據中心及其組合,
    Linkerd 不會引入除網關連接(gateway connectivity)之外的任何 L3/L4 要求。
  4. 集群通信中的統一模型。 Linkerd 為集群內通信提供的可觀測性(observability)、可靠性(reliability)
    和安全特性(security)也擴展到了跨集群通信。

就像集群內連接一樣,Linkerd 的跨集群連接對應用程序代碼是透明的。
無論通信發生在集群內、數據中心或 VPC 內的集群之間,
還是通過公共互聯網,Linkerd 都會在集群之間建立連接,
該連接在雙方都使用 mTLS 進行加密和身份驗證。

工作原理

Linkerd 的多集群支持通過在集群之間“鏡像(mirroring)”服務信息來工作。
由於遠程服務被表示為 Kubernetes 服務,
Linkerd 的完整可觀察性、安全性和路由功能統一
適用於集群內和集群調用,應用程序不需要區分這些情況。

Linkerd 的多集群功能由兩個組件實現:服務鏡像(service mirror)和網關(gateway)。
服務鏡像(service mirror)組件監視目標集群中的服務更新,並在源集群上本地鏡像這些服務更新。
這提供了對目標集群的服務名稱的可見性,以便應用程序可以直接尋址它們。
多集群網關組件為目標集群提供了一種從源集群接收請求的方式。(這允許 Linkerd 支持分層網絡)

安裝這些組件后,可以將與標簽選擇器(label selector)匹配的 Kubernetes Service 資源導出到其他集群。

服務配置文件

服務配置文件是一種自定義 Kubernetes 資源 (CRD),
可以提供有關服務的 Linkerd 附加信息。
特別是,它允許您定義服務的路由列表。
每個路由都使用一個正則表達式來定義哪些路徑應該與該路由匹配。
定義服務配置文件使 Linkerd 能夠報告每個路由的指標,
還允許您啟用每個路由的功能,例如重試和超時。

如果使用無頭服務,則無法檢索服務配置文件。
Linkerd 根據目標 IP 地址讀取服務發現信息,
如果這恰好是 pod IP 地址,則它無法判斷 pod 屬於哪個服務。

流量拆分(金絲雀、藍/綠部署)

Linkerd 的流量拆分功能允許您將目的地為 Kubernetes 服務的流量的任意部分動態轉移到不同的目的地服務。
此功能可用於實施復雜的部署策略,例如
金絲雀部署
藍/綠部署
例如,通過緩慢地將流量從舊版本的服務轉移到新版本。

如果使用無頭服務,則無法檢索流量拆分。
Linkerd 根據目標 IP 地址讀取服務發現信息,
如果這恰好是 pod IP 地址,則它無法判斷 pod 屬於哪個服務。

Linkerd 通過 Service Mesh Interface (SMI)
TrafficSplit API 公開此功能。
要使用此功能,您需要按照 TrafficSplit 規范中的描述創建一個 Kubernetes 資源,Linkerd 負責其余的工作。

通過將流量拆分與 Linkerd 的指標相結合,可以實現更強大的部署技術,
自動考慮新舊版本的成功率和延遲。
有關此示例的一個示例,請參閱 Flagger 項目。

我是為少
微信:uuhells123
公眾號:黑客下午茶
加我微信(互相學習交流),關注公眾號(獲取更多學習資料~)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM