做者簡介git
Darren Shepherd,Rancher Labs聯合創始人及首席架構師。在加入Rancher以前,Darren是Citrix的高級首席工程師,他在那裏從事CloudStack、OpenStack、Docker的工做,並構建下一代基礎設施編排技術。在加入Citrix以前,Darren曾在GoDaddy工做,他設計並領導一個團隊實施公有和私有IaaS雲。github
本文轉自Rancher Labs
2020年年初,Rancher開源了海量集羣管理項目Fleet,爲大量的Kubernetes集羣提供集中的GitOps式管理。Fleet最重要的目標是可以管理100萬個分佈於不一樣地理位置的集羣。當咱們設計Fleet架構時,咱們但願使用標準的Kubernetes controller架構。這意味着咱們能夠擴展Kubernetes的數量比以前要多不少。在本文中,我將介紹Fleet的架構、咱們用於測試擴展規模的方法和咱們的發現。
數據庫
隨着K3s用戶量爆發式增加(目前Github Star已經超過15,000),邊緣Kubernetes也開始迅猛發展。一些企業已經採用了邊緣部署模型,其中每一個設備都是單節點集羣。或者你可能會看到使用3個節點的集羣來提供高可用性(HA)。關鍵點在於咱們須要處理的是大量小型集羣,而不是一個有不少節點的大型集羣。現現在,幾乎任何地方的工程師都在使用Linux,他們都但願使用Kubernetes來管理工做負載。雖然大多數K3s的邊緣部署少於10,000個節點,但達到100萬個節點並不是不可能。而Fleet將知足你的規模擴展要求。
api
Fleet架構的關鍵部分以下:緩存
Fleet使用兩階段pull方法架構
Fleet是一組由標準K8S API交互驅動的K8S Controlleride
Fleet agent不須要一直保持鏈接測試
要從git中進行部署,Fleet Manager首先要複製並存儲git中的內容,而後Fleet manager決定須要使用git中的內容更新哪一個集羣,並建立部署記錄供agent讀取。當agent能夠讀取時,agent將check in以讀取部署集羣,部署新的資源並報告狀態。
設計
咱們使用兩種方法來模擬100萬個集羣。首先,咱們部署了一組大型VM(m5ad.24xlarge - 384 GiB RAM)。每一個VM使用k3d運行10個K3s集羣。而後這10個集羣每一個都運行750個agent,每一個agent都表明着一個下游的集羣。總的來講,每一個VM模擬7500個集羣。平均來看,部署一個VM、在Fleet註冊全部集羣並達到穩定狀態大約須要花費40分鐘。在兩天的時間裏,咱們以這種方式啓動虛擬機,直到達到10萬個集羣。在最初的10萬個集羣中,咱們發現了大部分的擴展問題。在解決了這些問題以後,擴展變得至關可預測。以這一速度,模擬剩下的90萬個集羣將會花費很長的時間以及至關可觀的資金。
3d
而後,咱們採用第二種方法:運行一個模擬器,它能夠執行100萬個集羣會進行的全部API調用,而不須要下游的Kubernetes集羣或部署Kubernetes資源。取而代之的是,模擬器進行API調用以註冊新集羣、發現新部署並報告它們的成功狀態。使用這種方法,咱們在一天內實現了從0到100萬個模擬集羣。
Fleet manager是一個運行在Kubernetes集羣上的controller,運行在3個大型虛擬機(m5ad.24xlarge - 384 GiB RAM)和一個RDS(db.m5.24xlarge)實例上。實際上,咱們使用K3s來運行Fleet Manager集羣。咱們這樣作是由於Kine已經在其中集成了。我將在後面解釋什麼是Kine以及爲何使用它。儘管K3s針對的是小規模的集羣,但它多是最容易大規模運行的Kubernetes發行版,咱們使用它是由於其簡單易用。值得注意的是,在EKS這樣的託管提供商上,咱們沒法大規模運行Fleet,稍後我會解釋這一點。
咱們遇到的第一個問題徹底出乎意料。當一個Fleet agent註冊到Fleet Manager時,它會使用一個臨時的集羣註冊令牌(token)。而後,該令牌被用來爲該集羣/agent建立新的身份和憑證。集羣註冊令牌和該agent的憑證都是服務帳戶。咱們註冊集羣的速度受到controller-manager爲服務帳戶建立令牌的速度的限制。通過研究,咱們發現咱們能夠修改controller-manager的默認設置來提升咱們建立服務帳戶的速度(-concurrent-serviceaccount-token-syncs=100)和每秒API請求的整體數量(-kube-api-qps=10000)。
Fleet是做爲Kubernetes Controller編寫的。所以,將Fleet擴展到100萬個集羣意味着要在Kubernetes中管理數千萬個對象。正如咱們所瞭解的,etcd並無能力管理這麼大的數據量。Etcd的主要空間有8GB的限制,默認設置爲2GB。關鍵空間包括當前的值和它們以前還沒有被垃圾收集的值。在Fleet中,一個簡單的集羣對象大約須要6KB。對於100萬個集羣,咱們至少須要6GB。可是一個集羣通常包含10個左右的Kubernetes對象,加上每一個部署一個對象。因此在實際操做中,咱們更有可能須要超過100萬個集羣10倍的內存空間。
爲了繞過etcd的限制,咱們使用了Kine,這使得使用傳統的RDBMS運行任何Kubernetes發行版成爲可能。在這個規模測試中,咱們運行了RDS db.m5.24xlarge實例。咱們沒有嘗試對數據庫進行適當的大小調整,而是從最大的m5實例開始。在測試結束時,咱們在Kine中擁有大約2000萬個對象。這意味着以這種規模運行Fleet不能在EKS這樣的託管提供商上進行,由於它是基於etcd的,也不會爲咱們的需求提供足夠可擴展的數據存儲。
這個測試彷佛並無把數據庫push得很厲害。誠然,咱們使用了一個很是大的數據庫,但很明顯咱們還有不少垂直擴展的空間。單條記錄的插入和查找繼續以可接受的速度進行。咱們注意到,隨機列出大量對象(最多一萬個)將會花費30秒到一分鐘的時間。但通常來講,這些查詢會在不到1秒的時間內完成,或者在很是粗暴的測試下5秒也能夠完成。由於這些耗時很長的查詢發生在緩存重載期間,因此對系統總體影響不大,咱們將在後面討論。儘管這些緩慢的查詢並無對Fleet形成明顯的影響,但咱們仍是須要進一步調查爲何會出現這種狀況。
當controller加載緩存時,首先會列出全部對象,而後從列表的修訂版開始監控。若是有很是高的變化率而且列出對象花費了很長的時間,那麼你很容易陷入這樣的狀況:你完成了列表但沒法啓動監控,由於API Server的監控緩存中沒有這個修訂版,或者已經在etcd中被壓縮了。做爲一個變通辦法,咱們將監控緩存設置爲一個很是高的值(–default-watch-cache-size=10000000)。理論上,咱們認爲咱們會遇到Kine的壓實問題(compact),但咱們沒有,這須要進一步調查。通常來講,Kine在壓實(compact)的頻率上要低不少。但在這種狀況下,咱們懷疑咱們添加記錄的速度超過了Kine壓實的速度。這並不糟糕。咱們並不但願堅持要保持一致的變化率,這只是由於咱們正在快速註冊集羣。
Kubernetes controller的標準實現是將你正在處理的全部對象緩存在內存中。對於Fleet,這意味着咱們須要加載數百萬個對象來創建緩存。對象列表的默認分頁大小爲500。加載100萬個對象須要2000個API請求。若是你假設咱們能夠每秒鐘進行一次列表調用、處理對象並開啓下一頁,這意味着加載緩存須要30分鐘左右。不幸的是,若是這2000個API請求中的任何一個失敗,這個過程就會從新開始。咱們嘗試將頁面大小增長到10,000個對象,但看到總體加載時間並無明顯加快。咱們開始一次列出1萬個對象以後,咱們就遇到了一個問題,Kine會隨機花費超過1分鐘的時間來返回全部對象。而後Kubernetes API Server會取消請求,致使整個加載操做失敗,不得不從新啓動。咱們經過增長API請求超時(-request-timeout=30m)來解決這個問題,但這不是一個可接受的解決方案。保持較小的頁面大小能夠確保請求的速度更快,但請求的數量增長了失敗概率,並致使整個操做重啓。
重啓Fleet controller將須要花費45分鐘的時間。這一重啓時間一樣適用於kube-apiserver和kube-controller-manager。這意味着你須要很是當心。這也是咱們發現運行K3s不如運行RKE等傳統發行版的一點。K3s將api-server和controller-manager結合到同一個進程中,這使得重啓api-server或controller-manager的速度比本來應有的速度慢,並且更容易出錯。模擬一場災難性的故障,須要徹底重啓全部服務,包括Kubernetes,這一切花了幾個小時才恢復上線。
加載緩存所需的時間和失敗的概率是迄今爲止咱們發現的擴展Fleet的最大問題。從此,這是咱們要解決的首要問題。
經過測試,咱們證實了Fleet的架構能夠擴展到100萬個集羣,更重要的是,Kubernetes能夠做爲一個平臺來管理更多的數據。Fleet自己與容器沒有任何直接的關係,能夠當作只是一個簡單的應用,在Kubernetes中管理數據。這些發現爲咱們開啓了一個可能性,即把Kubernetes更多的看成一個通用的編排平臺來寫代碼。當考慮到你能夠很容易地將一套controller與K3s捆綁在一塊兒,Kubernetes就變成了一個很好的自成一體的應用server。
在擴展規模方面,從新加載緩存所需的時間使人擔心,但絕對是可控的。咱們將繼續在這方面進行改進,使運行100萬個集羣不只是可行的,並且是簡單的。由於在Rancher Labs,咱們喜歡簡單。