從 lite-apiserver 看 SuperEdge 邊緣節點自治

騰訊雲原生發表於2021-04-07

引言

在 SuperEdge 0.2.0版本中,lite-apiserver 進行了重大的架構升級和功能增強。本文將從 lite-apiserver 實現及其與其它 SuperEdge 元件協同的角度,分析 SuperEdge 的邊緣自治能力,給大家的研究和選型提供參考。

邊緣節點自治

在雲邊協同的邊緣計算場景中,邊緣節點通過公網與雲端連線。邊緣節點眾多,網路環境複雜,網路質量參差不齊。邊緣節點需要與雲端弱網或斷網情況下,繼續正常工作,已執行的業務不受影響,達到邊緣節點自治的目的。
為了實現邊緣節點自治,需要處理以下場景:

  1. 邊緣節點與雲端斷連,但是它本身正常,上面執行的業務容器應該不被驅逐,也沒有新的業務容器排程到該節點上
  2. 邊緣節點與雲端斷連時,邊緣節點上的 Kubernetes 元件和業務容器可繼續執行
  3. 邊緣節點與雲端斷連時,邊緣節點重啟後,節點上的 Kubernetes 元件和業務容器可執行
  4. 邊緣節點與雲端恢復後,邊緣節點上的資料與雲端保持一致

SuperEdge 使用分散式節點健康檢查元件 edge-health 來處理場景1,使用 lite-apiserver 來應對場景2、3、4。

lite-apiserver 是執行在邊緣節點上的輕量級 apiserver,它代理節點上所有元件和業務容器訪問雲端 kube-apiserver 的請求,並對請求結果做高效快取。在雲邊斷連的情況下,利用這些快取提供服務,實現邊緣自治的能力。

lite-apiserver 設計特性

lite-apiserver除了滿足邊緣節點自治的功能需求外,還需要滿足以下設計特性:

支援所有 Client 型別

作為邊緣節點上訪問雲端 kube-apiserver 的唯一“出口”,lite-apiserver 需要支援所有型別的 Client ,包括以 bin (如 kubelet 等)或 pod (如 flannel\kube-proxy 等)形式執行的 Kubernetes 元件,以及以 InCluster 方式訪問 kube-apiserver 的業務容器。
更進一步,如果邊緣節點網路環境特殊,需要以代理等方式才能訪問雲端 kube-apiserver時,只用給 lite-apiserver 設定代理,所有元件即可正常訪問雲端 kube-apiserver,不需要每個元件做單獨的配置。

支援快取所有型別資源

支援快取所有型別資源,Kubernetes 內建資源和 Custom Resources。
邊緣節點上執行的 Kubernetes 元件和業務容器的請求 kube-apiserver 的資源多樣,如果只快取部分資源型別或僅支援 Kubernetes 內建資源型別,在雲邊斷連時,可能因為讀取不到對應的快取導致元件或業務失敗,達不到邊緣節點自治的效果。當然,支援所有型別資源的快取(尤其是 Custom Resources ),也給資料的解析和處理帶來了不小挑戰。

安全

邊緣節點分佈廣泛,環境複雜,更容易造成安全風險。安全問題也在邊緣計算和 Kubernetes 管理中越來越受重視。
給 lite-apiserver賦予一個訪問許可權,其代理的所有請求扔掉自身的許可權方式,都使用 lite-apiserver 的許可權訪問雲端的 kube-apiserver,是一種常見的訪問控制方案。由於 lite-apiserver 需要訪問和處理所有型別的資源,則該許可權必然是一個“超級”許可權。在這種情形下,某一個邊緣節點上的惡意程式就可以通過 lite-apiserver 對叢集的所有資源進行操作,可能對整個叢集進行惡意破壞。
因此,從安全形度,lite-apiserver 從設計上不應擁有一個“超級”許可權,可以使用 Kubernetes 元件和業務容器原有的認證和鑑權方式,訪問雲端 kube-apiserver。

支援多種快取儲存

根據 IDC 對邊緣計算分層的定義,邊緣分為 Heavy Edge(邊緣資料中心)和 Light Edge(低功耗計算平臺)。針對不同的場景,lite-apiserver 可以採用不同的快取儲存策略來達到更優的效果。在 Light Edge 中,lite-apiserver 使用檔案儲存快取以降低其本身的系統開銷,提升通用性。在 Heavy Edge 中,lite-apiserver 可採用 KV 儲存等提升讀寫效能。

下面我們將從 lite-apiserver 的架構和關鍵技術方面,介紹其如何實現以上的功能需求和設計特性。

lite-apiserver 架構與關鍵技術

架構

lite-apiserver架構如圖

從整體上看,lite-apiserver 啟動一個 HTTPS Server 接受所有 Client 的請求(https request),並根據 request tls 證書中的 Common Name 選擇對應的 ReverseProxy(如果 request 沒有 mtls 證書,則使用 default),將 request 轉發到 kube-apiserver。當雲邊網路正常時,將對應的返回結果(https response)返回給client,並按需將response非同步儲存到快取中;當雲邊斷連時,訪問kube-apiserver超時,從快取中獲取已快取的資料返回給client,達到邊緣自治的目的。

  • HTTPS Server
    監聽 localhost 的埠(SurperEdge 中為51003)接受 Client 的 Https 請求。
  • Cert Mgr && Transport Mgr
    Cert Mgr 負責管理連線 kube-apiserver 的 TLS 客戶端證書。它週期性載入配置的TLS證書,如果有更新,通知Transport Mgr建立或更新對應的transport。
    Transport Mgr負責管理transport。它接收Cert Mgr的通知,建立新的transport,或者關閉證書已更新的transport的舊連線。
  • Proxy
    根據 request mtls 證書中的 Common Name 選擇對應的 ReverseProxy(如果 request 沒有 mtls 證書,則使用 default),將 request 轉發到 kube-apiserver。如果請求成功,則將結果直接給 Client 返回,並呼叫 Cache Mgr 快取資料;如果請求失敗,則從 Cache Mgr 中讀取資料給 Client。
  • Cache Mgr
    根據 Client 的型別分別快取 Get 和 List 的結果資料,並根據 Watch 的返回值,更新對應的 List 資料。

關鍵技術

1. HTTPS Server

在當前架構下,lite-apiserver 只處理本節點的所有請求,使用 HTTP Server 可以滿足效能和安全要求。然而,大部分元件和業務容器採用 client-go 庫訪問 kube-apiserver,如果使用 HTTP Server,Client 自己的認證和鑑權資訊全部丟失,不符合許可權管理的要求。因此必須採用 HTTPS Server。lite-apiserver 的 TLS Server 證書,需用 kube-apiserver 的 Server 證書相同的CA簽發。

2. 支援 InCluster 方式訪問

一般的 Client 通過指定 kube-apiserver 的 URL 訪問 kube-apiserver,使用 lite-apiserver 時,只需將原來 kube-apiserver 的 URL 替換為 lite-apiserver 的地址即可。
在 Pod 中訪問 kube-apiserver 的推薦方式是通過 kubernetes.default.svc 這個 DNS 名稱,該名稱將會解析為服務 IP,然後服務 IP 將會路由到 kube-apiserver。在這種場景下使用 lite-apiserver 需要一些小小的"魔法"。
在 SuperEdge 中,application-grid-wrapper 以 DaemonSet 的形式部署在每個邊緣節點上,通過給 kube-proxy 只返回本區域內的 endpoints 來達到訪問在區域內閉環的目的。利用這個特性,application-grid-wrapper 把 kubernetes 這個 Service 的 endpoint 改為 lite-apiserver 的地址, 返回給本節點 kube-proxy,即可支援 InCluster 方式訪問。

3. 支援 Client 的 Bootstrap Token 和證書輪換

lite-apiserver 使用 Client 自己的認證和鑑權方式,訪問雲端的 kube-apiserver。對於 static token、bootstrap token、service account 等方式,lite-apiserver 只需透傳 Http Request 的 Header 中包含的認證鑑權資訊即可。對於 TLS 客戶端證書的認證方式,lite-apiserver 通過讀取配置檔案,載入所有 Client 用到的 TLS 客戶端證書,使用這些證書構造對應的 HTTPS 請求 kube-apiserver。
為了支援 Client 的 Bootstrap Token 和證書輪換,lite-apiserver 需要週期性的載入和更新這些證書。kube-controller-manager 簽發的證書預設時間是1年,lite-apiserver 載入 TLS 客戶端證書週期不宜過短。但如果證書載入週期時間過長,kubelet 使用 Bootstrap Token 的場景中會存在證書更新不及時的問題。為了處理這些場景,lite-apiserver 採用一種“優雅”的證書載入策略:當載入證書出現錯誤或證書過期時,進入快速載入模式,週期是1s; 載入證書均成功時,進入普通載入模式,週期是30min。
當證書更新後,lite-apiserver 使用 client-go 提供的closeAll方法,關閉已存在的連線,以防認證鑑權失敗。

4. 快取解析和更新

lite-apiserver 需要支援快取所有型別的資源,快取的解析和更新是 lite-apiserver 實現的關鍵之一。lite-apiserver 分別快取每個 Client 的對資源的 Get 和 List 請求,這樣雖然造成了一定的儲存空間的浪費,但是也避免了複雜的資源版本轉換。對於 Watch 型別的請求結果,lite-apiserver 採用unstructured.UnstructuredJSONScheme 解析出資源的 meta 資訊,進而更新相應的 List 資料。

展望

SuperEdge 正式開源以來,得到了廣泛的關注。SuperEdge 在快速迭代開發中,lite-apiserver 也有不少可擴充套件點,歡迎大家積極參與,共同打造一個優秀的雲原生邊緣容器專案。

  • 記憶體中快取部分高頻更新的資源,提升效能
  • 支援更多種類儲存
  • 效能和記憶體優化,適應更廣泛的邊緣場景

相關文章