在 k8s 世界中,所有資源都是透過控制器創建的。就像有用於 pod、部署、副本集等的內建控制器一樣。所以基本上,控制器只不過是一個控制循環,它持續監視叢集的狀態並採取措施使叢集進入所需的狀態。資源具有提供所需狀態的規格。控制器檢查目前狀態。如果與期望的狀態不匹配,它將進行適當的更改或修改,使其更接近期望的狀態。
ReplicaSet Controller:此控制器負責維護一組穩定的副本 Pod 在任何給定時間運行。它通常與 Deployment 結合使用,以確保指定數量的 pod 副本始終在運行,即使在節點故障或 pod 終止的情況下也是如此。
部署控制器:此控制器為 Pod 和 ReplicaSet 提供聲明性更新。它允許輕鬆擴展、滾動更新和回滾應用程式。 Deployment 控制器管理 ReplicaSet 的建立和刪除,以確保所需數量的 pod 始終運作。
StatefulSet Controller:此控制器用於管理有狀態應用程序,例如資料庫。它為集合中的每個 Pod 提供唯一的識別(穩定的主機名稱),並維護這些 Pod 的順序和唯一性。當您需要穩定的網路標識符、穩定的持久性儲存以及有序、優雅的部署和擴展時,它特別有用。
服務控制器:此控制器負責維護一組 pod 的穩定 IP 位址和 DNS 名稱。它充當負載平衡器,並根據服務的選擇器將流量路由到適當的 Pod。這確保了服務有一個穩定的端點來存取正在運行的 Pod,即使它們在叢集中被建立、銷毀或移動。
因此,在進行測試之前,我們必須先了解標準控制器的基本架構。在 Kubernetes 的客戶端伺服器架構中,控制器作為向 Kubernetes API 伺服器進行 API 呼叫(主要是 HTTP)的客戶端發揮著至關重要的作用。他們的主要目標是協調 Kubernetes API 物件與實際系統資源。這個架構中一個重要的組成部分是 Informers 的使用。舉報者負責監控叢集中的任何變化,這至關重要,因為持續輪詢來檢索資源資訊會顯著降低 API 伺服器的效能。
告密者透過查詢資源資料並將其儲存在本地快取中來工作。一旦資料被存儲,只有當物件(或資源)的狀態發生變化時才會產生事件。這種方法可確保系統不會被不必要的事件淹沒,並且僅在發生相關變更時才通知控制器。
該架構中的另一個重要概念是資源版本。此版本隨每次寫入操作而變化,用於樂觀並發控制。它確保以避免衝突並保持整個系統一致性的方式管理資源更新。透過理解和利用這些機制,Kubernetes 控制器可以有效地管理和協調叢集中資源的狀態。
Kubernetes 允許建立自訂資源定義 (CRD),它是 Kubernetes API 的擴展,使用戶能夠定義自訂資源。這些自訂資源在預設 Kubernetes 安裝中不可用,用於適應特定於網域的用例和複雜的應用程式要求。
要管理這些自訂資源,需要一個自訂控制器。自訂控制器、CRD 和 Kubernetes API 伺服器形成緊密的關係,其中:
CRD 定義自訂資源。
API 伺服器管理這些資源的生命週期。
自訂控制器確保根據所需的配置維護這些資源的狀態。
該架構實現了 Kubernetes 的可擴展性,允許用戶根據自己的特定需求自訂平台。
在將 Kubernetes 控制器部署到生產環境之前,確保 Kubernetes 控制器已準備好向 Kubernetes API 伺服器提供請求至關重要。有多種方法可以測試 Kubernetes 控制器。我提到的一些內容來自文章:
使用 client-go fakes 或更高層級的抽象:這種方法避免執行任何支援 API,使其適合單獨對各個組件進行單元測試。
使用控制器運行時中的envtest 套件:該套件與精簡的API 伺服器配合使用,以驗證與API 的真實交互,包括計時和快取同步,而不會受到其他控制器的干擾。它支援針對精簡實例的本機測試和針對功能齊全的叢集的測試。
運行真正的 API 伺服器:此方法適合臨時環境或實例(例如臨時類型或 microk8s),用於測試真實結果。它允許測試與真實 API 伺服器的交互。
使用外部進程(例如 envtest 或真正的 API 伺服器)的優點是它可以解決分散式系統固有的延遲。像 Gomega 這樣的函式庫可用於操作發生後等待特定條件。上述方法通常聽起來最適合單元測試和整合等級測試,在這些測試中我們單獨測試特定元件。要么通過編寫測試來偽造數據
雖然上述技術對於單元和整合測試有效,但它們可能不涵蓋端到端(e2e)測試,而這對於確保控制器的整體功能至關重要。 e2e 測試的一種方法是執行資源更新和其他操作,以在受控環境中測試控制器的整個流程,並在必要時複製該過程。這有助於驗證控制器在現實場景中的行為,並確保其為生產部署做好準備。
總之,單元、整合和端到端測試的結合對於確保 Kubernetes 控制器在投入生產之前的可靠性和有效性至關重要。
在本地建置和測試 Kubernetes 控制器可能具有挑戰性,尤其是在處理傳出 API 呼叫時。然而,Keploy 作為一種透過 API 呼叫、資料庫查詢等建立測試案例和資料模擬的工具,提供了一種解決方案。 Keploy 讓您可以記錄和重播 Kubernetes 控制器發出的傳出呼叫,這對於測試和確保控制器按預期運行非常有用。
您可能想知道如何在不更改任何程式碼的情況下實現這一點。 Keploy 使用 eBPF 為核心空間新增偵測器並收集網路緩衝區資料。然後,該資料被傳送到 Keploy 的代理,該代理充當使用者空間,其中緩衝區的所有處理均由不同的協定解析器完成。 Keploy 可以擷取控制器的出口流量,並將該特定事件的請求和回應儲存在 YAML 檔案中。在重播模式下,Keploy 不會對真正的 API 伺服器進行 API 調用,而是會從儲存的 YAML 檔案返回針對該特定請求的回應。這使得該過程獨立於叢集或環境,為本地測試 Kubernetes 控制器提供了一種便捷且高效的方法。
因此,要在本地或從任何即時環境捕獲控制器的測試,您必須先啟動 kubernetes 叢集並建立自訂控制器以與伺服器進行一些互動。
要使用 Keploy 錄製您的控制器,請按照以下步驟操作:
將您的 Kubernetes *rest.Config 物件設定為不安全且沒有 CA 檔案:
cfg.Insecure = true cfg.CAFile = ""
建立自訂 RoundTripper 以新增包含資源版本的標頭欄位。此標頭用作追蹤 ID,用於在相同狀態下將請求與記錄的模擬進行比對。這是一個範例實作:
type customRoundTripper struct { rt http.RoundTripper } func (crt *customRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { ctx := req.Context() rsv := ctx.Value("ResourceVersion") if rsv != nil { req.Header.Add("keploy-header", rsv.(string)) } return crt.rt.RoundTrip(req) } cfg.WrapTransport = func(rt http.RoundTripper) http.RoundTripper { return &customRoundTripper{rt: rt} }
確保在同步過程中在 context.Context 中設定資源版本值。這對於將修改後的上下文傳遞給控制器的更新和建立方法至關重要。例如:
func (c *Controller) syncHandler(ctx context.Context, key string) error { // set ResourceVersion in ctx rv := foo.GetResourceVersion() if rv != "" { ctx = context.WithValue(ctx, "ResourceVersion", rv) } }
建置 Kubernetes 控制器的 Go 二進位檔案:
go build -o sample-controller .
要透過 Keploy 記錄去電,請使用 Keploy 的記錄指令包裝您的控制器指令。注意 - keploy 的此功能處於測試版使用狀態,尚未在主版本中發布。這是專門為 Kubernetes 愛好者嘗試並給予評論而創建的實驗。因此,您必須在這個特定分支中簽出並使用 go build 命令建立 keploy 二進位。 https://github.com/keploy/keploy/pull/1342。
到指定分店結帳。
1.
git checkout kube-controller ``` {% endraw %}
為該分支建立 keploy 二進位。
{% 原始 %}
go build -o keploy && sudo mv keploy /usr/local/bin
依照您的 kube 配置新增必要的標誌:
sudo -E env PATH=$PATH keploy record -c "./sample-controller -kubeconfig=$HOME/.kube/config" --mtls-cert-path "$HOME/.minikube/profiles/minikube/client.crt" --mtls-key-path "$HOME/.minikube/profiles/minikube/client.key" --mtls-host-name 192.168.49.2:8443
一旦 Keploy 開始攔截出站調用,您就可以看到建立的 keploy/test-set-0/mocks.yaml。每個資源版本都有一個單獨的模擬文件,用mocks_“
注意 - 我想澄清的一件事是,上述功能對 TDD(測試驅動開發)沒有幫助。但是,您仍然可以在編寫單元測試時利用 keploy 的存根產生功能來進行 keploy。因此,您無需製作任何模擬 api 伺服器或為特定單元測試編寫存根,只需在真實環境中進行該測試即可。 Keploy 會將所有互動儲存在模擬檔案中,並在下次執行測試時使用該資料。
使用錄製的模擬測試您的控制器:
在測試模式下執行 Keploy,並將 mockAssert 標誌設為 true 並提供您的控制器二進位。 Keploy 會自動為您建立一個假的 kube 配置:
cfg.Insecure = true cfg.CAFile = ""
(可選)您可以設定自己的重播時間,這將嘗試在提供的時間內重播您錄製的會話:此處給出了與 keploy 整合的完整範例應用程式。
type customRoundTripper struct { rt http.RoundTripper } func (crt *customRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { ctx := req.Context() rsv := ctx.Value("ResourceVersion") if rsv != nil { req.Header.Add("keploy-header", rsv.(string)) } return crt.rt.RoundTrip(req) } cfg.WrapTransport = func(rt http.RoundTripper) http.RoundTripper { return &customRoundTripper{rt: rt} }
請注意,重播過程會將足夠大的事件時間間隔修剪為舉報者的兩個事件之間的精確平均持續時間。這允許事件在記錄中發生之前發送,從而促進更快的重播。
這可以幫助您重播控制器產生的 api 呼叫的整個會話,但這次您不需要真正的 k8s 伺服器或任何外部來源來獲取回應。所有回應都將由 keploy 本身傳回,就像模擬伺服器或中間人一樣。這可以讓您有信心在 CI-CD 管道中運行它。
例如 - 您在大型雲端運算組織工作,要部署所有內容,需要大量虛擬化,並且是資源密集型操作。因此,在真實環境中對其進行測試幾乎是不可能的。在這裡,類似 Keploy 的工具非常有用,因為它已經提供了您在成功推出該資源時想要獲得的回應。因此,它可以是快速、可靠且節省成本的操作,因為您只需一次擷取控制器服務的正確流程。並且可以在後續版本中重複使用 keploy 重播。
使用 Keploy 等工具可以讓本地測試 Kubernetes 控制器變得更有效率和可靠。透過錄音和重播去電,您可以確保控制器在各種場景下都能正確運行,從而提高 Kubernetes 應用程式的整體品質。由於 keploy 原生支援 gotest 等測試框架,因此還可以獲得任何應用程式的線路覆蓋率,甚至是 kube 控制器的線路覆蓋率。探索 Keploy 並增強您的 Kubernetes 控制器測試工作流程!
記錄和重播傳出 API 呼叫:這消除了測試期間對即時環境的需求。
提高效率:透過使用儲存的模擬,測試變得更快並且獨立於實際的 Kubernetes 叢集。
節省成本和資源:它減少了對資源密集型環境進行驗證的依賴,使其成為大規模運營中 CI/CD 管道的理想選擇。
Keploy 使用 eBPF 探針 攔截傳出呼叫並將請求-回應對儲存在類比檔案中。在重播模式下:
呼叫被攔截並與先前錄製的模擬進行比對。
回應是從這些模擬傳回的,而不是到達實際的 API 伺服器。
這種機制確保測試可以在不需要即時 Kubernetes 叢集的情況下運行。
雖然Keploy的錄音和重播功能並不是專門為TDD設計的,但它仍然可以有效地使用:
存根產生:在真實環境中執行控制器一次以擷取互動。 Keploy 將建立模擬以供後續使用。
單元測試支援:透過利用這些模擬,您可以避免手動編寫存根並專注於測試執行。
Keploy 透過簡化模擬創建和減少開發開銷來補充現有的 TDD 工作流程。
以上是如何使用自訂 Kubernetes 控制器測試流量:逐步指南的詳細內容。更多資訊請關注PHP中文網其他相關文章!