首頁/ 情感/ 正文

「“星”技術」如何將100個Pod掛載卷的時間縮短10倍?

01

CSI 發展和現狀

XSKY早在2018年底就實現了容器儲存介面(CSI) driver,而CSI也在2018年底釋出的Kubernetes(K8s) v1。13版本中正式GA,現在已經成為了容器和儲存的標準介面。

作為國內率先擁抱CSI的儲存廠商,XSKY開始CSI driver是使用塊(iSCSI)對接的,後來又支援檔案(NFS)對接,經過一年多的驗證,目前已經十分穩定併為各大客戶提供了穩定的容器化場景支援。

Kubernetes CSI後來推出了越來越多的新特性,XSKY緊隨社群步伐,不斷更新迭代,先後支援了各種實用的新特性,包括擴容,裸卷,快照等。但是,僅僅是“多”還不夠,正所謂“天下武功,唯快不破”,我們在“快”上也花了一點功夫。

「“星”技術」如何將100個Pod掛載卷的時間縮短10倍?

圖一:圖片來源網路

眾所周知,容器相比虛擬機器要更加輕量,在K8s叢集中,執行著眾多的Pod,由於容器是應用級的隔離環境,相比虛擬機器而言,一個K8s集群裡面Pod的數量從幾十個到幾萬個的場景都會存在,因此,在大規模排程的時候對持久卷的管理可以說是很關鍵的操作。

但是在使用過程中,如果發生大規模的排程時候難免有些不理想的情況,舉個例子,在最初正式支援CSI的K8s 1。13版本,一個常見的問題是掛載的時候經常看到Pod排程完成後出現Attach timeout的警告,這就是一個最常見的掛載超時場景。

02

原因分析

首先明確問題之前我們回顧下之前分享過的文章有提到K8s和儲存是如何互動的。

「“星”技術」如何將100個Pod掛載卷的時間縮短10倍?

圖二

早前的文章《詳解支援 kubernetes CSI的持久化容器儲存》有具體介紹一個PV的產生和掛載的具體流程, 這裡不妨再溫習一次,為簡化模型,我們把整個流程分成兩部分。

從使用者提交一個pvc。yaml檔案開始,上圖1,2,3,4步驟我們稱之為provisioning過程,它的作用是從API server開始建立一個卷的流程。從PV掛載到實際使用的容器或者說業務Pod的過程稱之為Publish Volume。相對應的是上圖5,6,7,8。

不難看出,一個儲存卷的使用過程是經過多階段的處理,呼叫方式也是包括且不限RESTful介面,RPC呼叫,以及其他各程序間狀態同步,因此整套流程下來需要考慮的問題比較多。

其中provision過程即建立PV的過程實測還是比較快的,100個卷的建立僅需幾十秒,所以暫時也不需要最佳化。

而對於掛載卷的流程可以看到external attacher和kubelet這兩個元件都會呼叫XSKY CSI driver來對捲進行掛載處理。由於這兩步都是透過gRPC實現遠端呼叫,在比較早的K8s版本中,它們是硬編碼,超時時間為15秒,此外對於未完成的或失敗請求有指數退避演算法重試。

也就是說,在一次重試後暫時掛載不上它會在30秒後再重試,再失敗就60秒,如果請求數比較少的情況沒有太大問題,但如果是在大批次容器同時排程的過程中這種場景就出現較多重試的情況,因為掛載請求下發到儲存集群后並不能馬上就處理完成,而K8s對這些請求只等待15秒,所以有相當一部分的請求並未正確處理,再加上指數退避重試機制,如果儲存底層有較多卷請求堆積未處理完成,那K8s的重試間隔將越拉越長,甚至拉到10幾分鐘之後。

掛載卷的操作我們簡化為三步動作,即向儲存叢集發起添加捲到訪問路徑,在K8s Node節點上掃描裝置,以及格式化和掛載,對於併發的請求而言,有很多是在阻塞著,如果同時排程Pod發起掛載操作的話,就有可能出現K8s的重試間隔越拉越長。對於使用者而言就是過了很久還沒有把所有Pod啟動成功。

「“星”技術」如何將100個Pod掛載卷的時間縮短10倍?

圖三

上圖展示了併發掛載的過程,由於阻塞式掛載導致PublishVolume請求被越拖越長,因此一部分的掛載操作很容易就到達15秒的超時上限,然後等待下一次重試。

03

最佳化

回顧“圖二”的掛載流程,我們把整套流程自上而下進行分層分析,分別是K8s平臺層, CSI driver中間層,xmsd控制層以及XDC儲存管理層。針對每個層面都做了一些最佳化和調整。

1、K8s頂層最佳化

「“星”技術」如何將100個Pod掛載卷的時間縮短10倍?

圖四

K8s Pod掛載卷時候主要是external attacher和kubelet兩個元件來呼叫CSI driver,因此可以從這兩者著手:external attacher是一個sidecar容器,負責監聽K8s叢集中的volumeattachment物件,每當controller manager生成一個volumeattachment物件時就代表K8s內要進行一次卷掛載操作,external attacher監聽到此物件的產生時候就開始向XSKY 的CSI driver發起一個RPC請求,完成第一階段處理。

預設這個external attacher只有10個協程去處理這樣的監聽事件,這對於普通場景使用尚且可以,但是對於大規模的叢集就未必是最佳值。考慮到使用者場景的不同,我們向社群提交了一個PR將工作協程數改成可配置,這樣既不會有API breaking change,又能根據使用者所在叢集動態配置,比如在這種存在大批次併發的K8s叢集預設使用的是100個worker,以達到最佳監聽效果。

Kubelet是一個核心元件,它也是直接參與了持久卷掛載的操作,在完成第一階段的請求後,由kubelet向CSI driver發起另一個RPC請求。

前面提到由於kubelet每次請求設定的超時時間只有15秒,顯然對於很多儲存商而言15秒其實還是不夠的,開源社群也有其他成員討論過這一點。經過大家實踐後得出的結論是,建議最佳值為2分鐘。

雖然這是一個小改動,但是對於儲存端而言極大提升了一次掛載成功的機率,一定程度上減少了很多無意義的重試,不至於把重試間隔拉到10分鐘以上,對於使用者體驗的提升也是比較明確的。因此,建議有條件的優先使用更新版本的Kubernetes。

2、CSI driver最佳化

為方便理解,前面描述Kubernetes掛載卷的操作,我們簡化為一個PublishVolume動作,其中包含3步耗時操作,包括AddVolume,ScanDevice 和Format。

其中AddVolume是直接呼叫XMS的介面實現,我們後面會介紹這部分最佳化。現在我們關注在ScanDevice。

ScanDevice的最佳化:向訪問路徑添加捲操作完成之後,CSI driver開始在K8s 的node節點上掃描iSCSI裝置,這裡掃描裝置的操作就基於iscsiadm來完成的,當有大量Pod在掛載卷的準備過程,可以發現存在大量的iscsiadm命令在執行,這對於同一個節點而言很多都是重複的請求,比如說Pod A新增完卷操作後呼叫 iscsiadm 來發現和登陸,同時Pod B新增完成後也呼叫 iscsiadm來登陸和重新整理,假如同一個Node上有100個Pod,那甚至會出現數百個 iscsiadm程序,這對於target端而言反而是增大負載,重新整理程序的數量多並不會使發現裝置的過程加快。

後來經過實踐我們改良了這種實現,合理複用了iscsiadm,將伺服器壓力嚴格控制下來避免這種情況。

鎖的粒度控制:在第一個CSI driver版本,我們曾經對很多資源都做了鎖的控制。那是因為和後端儲存互動的API大多不是為容器場景設計的,會有很多方面的限制,包括資源競爭,狀態衝突等情況,因此需要在頂層自行控制併發,結果就是訪問路徑,客戶端組等資源的操作都加鎖,代價就是我們的併發量很多受限於此設計。我們重新進行了最佳化,現在可以實現併發的操作,將來自K8s的請求快速轉換到xmsd和XDC層面處理。

3、XMS介面最佳化

XMS (XSKY Management Service) : 即XSKY管理服務,作為資料管理平臺來提供分散式儲存叢集的管理功能,並提供API等方式提供儲存的擴充套件能力。

考慮到容器使用的訪問路徑有機率被管理面誤操作,也為了更快建立所需要的資源,把一些XSKY的資源被抽象定義到Kubernetes叢集中,因此可以在K8s叢集使用一個yaml配置檔案,一條kubectl create命令即可完成幾乎所有的初始化工作,極大解放了部署成本。

「“星”技術」如何將100個Pod掛載卷的時間縮短10倍?

圖五

其中訪問路徑,VIP是透過CRD整合到Kubernetes。由於自定義控制器的工作機制,總能保障有指定數量的訪問路徑和閘道器組以及VIP的存在,而不擔心使用者誤操作影響儲存叢集的使用。管理員所需要的操作僅僅是一條kubectl命令,然後就等待部署完成。

另外,XMS設計初衷並不是針對容器場景,很多操作基本是互斥,因此很多API請求都被拒絕,效率比較低,於是在後續的版本已經最佳化這一點。使得在API介面層允許併發新增和移除卷請求,一定程度提高了API的可用性。

Task最佳化:task是XMS的內部執行單元,它負責將API轉換為具體的動作,比如前面提到的添加捲的行為則對應一個task,這個task去調底層XDC來完成mapping操作。在以前由於介面限制只能一個一個往下新增,所以task執行的密度並不高。完成最佳化後則可以實現大量的task同時執行新增對映操作,任務十分密集。

4、XDC最佳化

XDC (XSKY Data Client): 即XSKY資料客戶端,塊儲存閘道器,支援iSCSI、FC、SCSI及RBD等不同型別的訪問路徑閘道器,XDC服務提供資料QoS、流控、流量,卷管理等功能。

「“星”技術」如何將100個Pod掛載卷的時間縮短10倍?

圖六

XDC作為底層最關鍵的對映管理單元,之前的工作模式都是比較直接,任務請求逐個排隊處理,效率非常低,為了應對容器大規模場景,我們已經重新設計成可支援併發的模型。

04

小結

至此,已經從K8s平臺層到CSI driver,以及內部xmsd和XDC每個層面都進行了各種型別的最佳化。對應100個Pod的掛載,以前需要十幾、二十分鐘到現在一、兩分鐘,時間縮短10倍,助力使用者建設高效的容器雲平臺。

—END—

「“星”技術」如何將100個Pod掛載卷的時間縮短10倍?

相關文章

頂部