如何除錯 Kubernetes 中的微服務 ——proxy、sidecar 還是 service mesh?

語言: CN / TW / HK

Kubernetes 可以說是目前為止用來執行微服務的最佳載體,但是在除錯 Kubernetes 環境中的微服務時的體驗可能就沒那麼友好了。本文將帶你瞭解如何除錯 Kubernetes 中的微服務,介紹常用的工具,以及 Istio 的引入為微服務的除錯帶來的變革。

除錯微服務與傳統單體應用有巨大的不同

微服務的除錯是一直長期困擾軟體開發人員的問題,這在傳統的單體應用中不存在,因為開發者可以利用 IDE 中的偵錯程式,為應用程式增加斷點、修改環境變數,單步執行等,這些都為軟體除錯提供了巨大幫助。隨著 Kubernetes 的流行,微服務的除錯就成了一個棘手的問題,其中相比傳統單體應用的除錯多了以下問題:

多依賴

一個微服務往往依賴多個其他微服務,在除錯某個微服務時,如何部署其他依賴服務以快速搭建一套最新的 stagging 環境?

從本地機器訪問

微服務在開發者的本地電腦上執行時,通常無法直接訪問到 Kubernetes 叢集中的服務,如何像除錯本地服務一樣除錯部署在 Kubernetes 叢集中的微服務?

開發效率低下

通常情況下,程式碼從更新到構建成映象再推送到叢集中需要一個漫長的過程,如何加快開發速度?

我們一起來看下哪些工具能夠解決以上問題。

工具

除錯 Kubernetes 中的微服務的主要解決方案有:

  • Proxy:在 Kubernetes 叢集和本地除錯終端中部署一個代理,通過構建一個 VPN,使得本地應用可以直接訪問到 Kubernetes 中的服務;
  • Sidecar:替換原來應用容器的映象為開發映象,可以在這個容器中中對該服務進行除錯,同時在要除錯的微服務 pod 中注入一個 sidecar 作為輔助工具來同步程式碼;
  • 服務網格:要想了解應用的整體情況,就需要在所有微服務中注入 sidecar,這樣你就可以獲得一個監控全域性狀態的儀表板;

下面是實現以上解決方案的三個典型的開源專案,它們分別從不同的角度可以幫助你除錯微服務。

Proxy 模式:Telepresence

Telesprence 本質上是一個本地代理,該代理將 Kubernetes 叢集中的資料卷、環境變數、網路都代理到了本地。下圖展示的是 Teleprence 的主要使用場景。

使用者需要在本地自主地執行 telepresence 命令,它會自動將代理部署到 Kubernetes 中,有了該代理之後:

  • 本地的服務就可以完整的訪問到 Kubernetes 叢集中的其他服務、環境變數、Secret、ConfigMap 等;
  • 叢集中的服務還能直接訪問到本地暴露出來的端點;

但是這種方式仍然不夠連貫,還需要使用者在本地除錯時執行多次命令,而且在某些網路環境下可能無法與 Kubernetes 叢集建立 VPN 連線。

Sidecar 模式:Nocalhost

Nocalhost 是一個基於 Kubernetes 的雲端開發環境。要想使用它,你只需要在你的 IDE——VS Code 中安裝一個外掛即可擴充套件 Kubernetes,並縮短開發反饋週期。通過為不同的使用者建立不同的 namespace,並使用 ServiceAccount 繫結到不同使用者角身上時,就可以實現開發環境隔離。同時,Nocalhost 還提供了 Web 控制檯和 API,方便管理員來管理不同的開發環境。

測試

參考 Nocalhost 文件 ,我們在 macOS 上安裝 Nocalhost,並使用 Minikube 來演示如何除錯。

執行下面的命令安裝 Nocalhost 客戶端並檢視 nhctl 命令列工具的版本。

brew install nocalhost/repo/nocalhost

nhctl version

我們假設你機的 kubeconfig 檔案位於 ~/.kube/config (若不在此位置需要在下面的命令中使用 --kubeconfig 手動指定) 並擁有 Kubernetes 叢集的 admin 角色,執行下面的命令使用 Helm3 在 Kubernetes 上安裝 Nocalhost 服務端。

nhctl init demo -n nocalhost

執行下面的命令啟動 Minikube 隧道並檢視 Nocalhost web 端地址。

minikube tunnel
kubectl get service nocalhost-web

在瀏覽器中訪問 http://<EXTERNAL-IP> 即可,使用者名稱/密碼為: [email protected]/123456

要想在 VS Code 中使用,你還想需要建立一個 ServiceAccount 並繫結 admin 角色,然後將該 ServiceAccount 作為 Kubeconfig 檔案匯出。

kubectl create serviceaccount my-service-account
kubectl create rolebinding admin --clusterrole=admin --serviceaccount=default:my-service-account

只要你有一個 Kubernetes 叢集,並有叢集的 admin 許可權,就可以參考 Nocalhost 的文件快速開始試用。在 VS Code 中使用 Nocalhost 外掛時需要先為外掛中配置 Kubernetes 叢集。選擇你剛匯出的 Kubeconfig 檔案或者直接複製檔案中的內容貼上到配置裡。然後選擇你需要測試的服務,並選擇對應的 Dev Container,VS Code 會自動開啟一個新的程式碼視窗。

下面是以 Istio 官方提供的 bookinfo 示例 為例,你可以在本地 IDE 中開啟克隆下來的程式碼,然後點選程式碼檔案旁邊的錘子即可進入開發模式。選擇對應的 DevContainer,nocalhost 會自動向 pod 中注入一個開發容器 sidecar,並在終端中自動進入該容器,如下圖所示。

在開發模式中,本地修改程式碼,無需重新構建映象,遠端開發環境實時生效,這樣可以極大的加快開發速度。同時,Nocalhost 還提供了服務端,可用於開發環境和使用者許可權進行管理,如下圖所示。

Service Mesh 模式:Istio

以上使用 proxy 和 sidecar 的方式,一次只能對一個服務進行除錯,如果想要掌握服務的全域性狀況,比如獲取的服務的指標,以及通過分散式追蹤瞭解服務的依賴和呼叫流程,對服務的效能進行除錯。這些 可觀察性 的功能,需要為所有服務統一注入 sidecar 來實現。

而且,當你的服務正處於從虛擬機器遷移到 Kubernetes 的過程中時,使用 Istio 可以將虛擬機器與 Kubernetes 納入一個網路平面中(如下圖所示),方便開發者除錯和做漸進式的遷移。

當然要獲得這些好處也不是一點“代價”也不沒有的,引入 Istio 後,你的 Kubernetes service 需要遵守 Istio 的 命名規範 ,學習使用 Istioctl 命令列和日誌的方式來除錯微服務。

istioctl analyze
istioctl proxy-config secret

Istio 的配置資訊在大型的叢集部署中傳播將會耗時更長並且可能有幾秒鐘的延遲時間,sidecar 的引入會給服務間呼叫帶來一定延遲。

總結

在應用微服務化和從虛擬機器遷移到 Kubernetes 的過程中,開發者需要很多觀念和習慣上的轉變。通過 proxy 在本地跟 Kubernetes 間構建 VPN,可以方便開發者像除錯本地服務一樣除錯 Kubernetes 中的服務。通過向 pod 中注入 sidecar,可以實現實時除錯,加快開發進度。最後,Istio service mesh 真正實現了全域性的可觀察性,你還可以使用像 Tetrate Service Bridge 這樣的工具來管理異構平臺,幫助你漸漸地從單體應用過度到微服務。