TopoLVM: 基於LVM的Kubernetes本地持久化方案,容量感知,動態創建PV,輕鬆使用本地磁盤

正文

研發測試場景下,一般追求的是一鍵快速起環境,橫向動態複製,一人一套,隨起隨用,用完即走。作為使用方,其不用關心實際的物理資源是怎樣的,環境起在哪裡,只要聲明自己的使用需求即可。但作為方案構建者以及infrastructure支撐,我們卻深知,要想提供更好的解決方案,個中問題還有很多,且頗為不易。

比如在過去,筆者就曾一度困擾於如何優雅的放開本地物理盤給業務使用這個問題,尤其是本地HDD數據盤。

這裡有個背景,我們的Kubernetes研發測試集群是用線上退下來的過保機器搭建,然後七牛又搞雲存儲,所以我們的機器中很多那種多盤位的存儲密集型機器(比如掛12塊4T的盤)。所以如何更好的利用這些磁盤,就是個問題。

方案之一是把這些盤組成網絡存儲,然後通過七牛自身的雲服務或者ceph等系統提供出去,這當然是可行的。不過有些業務其實就想單純使用物理盤,那該怎麼辦呢?

縱觀Kubernetes目前原生提供的幾種方案,筆者發現都不完美:

  • Emptydir 非持久化方案,Pod刪除,EmptyDir也會被清空。另外Emptydir使用的是rootfs的存儲空間,而這個空間有可能是放在在系統盤上的,所以對它的使用當慎之又慎。
  • HostPath 持久化方案,但安全風險很高,官方不推薦。另外,從使用角度也不方便。比如作為用戶,你首先要清楚知道目標系統的情況,知道具體的盤符和目錄位置然後才能在HostPath里正確引用。但現實是從集群安全角度,用戶不一定有直接登錄機器的權限。另外即使你的Pod佔了某個宿主機的目錄,也不能排除別人二次佔用,或者誤操作。所以HostPath的使用場景實際很受限。
  • Local Persistent Volume 持久化方案,以PVC/PV的形式來使用本地存儲。想法很好,但是不能動態創建PV,對於PV提供者來說,心智負擔較高。當然社區現在也有提供Local Static Provisioner,某種程度上簡化了這塊的心智負擔,但是仍然需要預先規劃目錄或者分區,略顯不足。

筆者以為,理想中的本地磁盤使用方案,應當是按需申請,空間隔離,且自動化生命周期管理。這樣才能既方便終端用戶使用,也能減少運維支撐,提高效率。這裡的關鍵技術點有三個:

  • 按需申請 意味着最好以PVC+StorageClass的模式來提供服務,做到PV動態創建。而要實現這點,容量感知 是關鍵,因為若調度到空間不足的節點上很明顯是不合理的。最好能結合PVC申請的容量+Node上的剩餘容量,綜合選擇最優的節點來做綁定。
  • 空間隔離 要確保用戶申請的空間大小一定是足額的,不被侵佔的。從這裡看,單純的把文件系統的目錄用作PV但容量上彼此不隔離顯然不合適。
  • 自動化生命周期管理 動態Provisioning是強需。

綜合以上三點,我們會發現基於 LVM或分區技術+CSI 的實現,當是比較符合上述用戶體驗的,而TopoLVM就是這樣一個項目。

地址: //github.com/topolvm/topolvm

TopoLVM是基於LVM的Kubernetes本地化磁盤方案,以CSI形式提供給用戶使用。目前主要支持以下功能:

  • 動態Provisioning
  • 支持原生數據塊卷(Raw Block Volume)
  • Volume伸縮

整體架構如下:

值得注意的是,在早期版本,為了能夠動態感知節點上的剩餘存儲容量,TopoLVM設計了個自定義擴展調度器(上圖topolvm-scheduler部分),方便在Scheduling階段為Pod綁定合適的Node。而在Kubernetes 1.21之後,Kubernete已經原生支持了 Storage Capacity Tracking的能力,這塊的實現整體就變的優雅很多,topolvm-Scheduler也就不再需要了。

當然,要想認知到TopoLVM的核心原理,除了了解CSI編寫規範外,最重要的就是需要了解LVM相關技術。而正是因為通過LVM能夠動態創建LV,動態擴縮容,TopoLVM才能支持動態Provisioning相關的能力。

不過,雖然作為開源項目TopoLVM已基本夠用,但豐富度略顯不足。而博雲近期也開源了他們的雲原生本地磁盤管理方案Carina,看起來更完善一些。

項目地址: //github.com/carina-io/carina

Carina除了提供基於LVM的方案外,還支持裸盤分區方式,以及IOPS限制等,功能更加豐富。代碼組織規範也更貼合雲原生社區的方式,整體非常值得一探。

參考鏈接

往期推薦