塊存儲是將裸磁盤空間通過劃邏輯盤,做Raid,或者LVM(邏輯卷)等方式邏輯劃分出N個邏輯的硬盤,然后采用映射的方式將這些邏輯盤掛載到主機。主機的操作系統(tǒng)認為這些磁盤均為物理硬盤,跟直接拿一塊物理硬盤掛載到操作系統(tǒng)沒有區(qū)別。
塊存儲的優(yōu)點不言而喻:
- 使用了Raid與LVM等手段,可以多數(shù)據(jù)做冗余保護;
- 可以使用磁盤陣列,組成大容量的邏輯盤對外提供服務,提高容量;
- 對邏輯盤寫數(shù)據(jù)可轉(zhuǎn)化為對幾塊物理磁盤的并行寫入,提升了讀寫效率。
需求
在IaaS中,塊存儲被廣泛應用于為虛擬機提供持久卷。虛擬機故障后依然能夠通過在其他虛擬機上掛載舊數(shù)據(jù)卷的方式來訪問磁盤數(shù)據(jù),因此被普遍認可。受此影響,睿云智合(Wise2C)的一些企業(yè)客戶在設計PaaS時,自然而然的聯(lián)想到共享存儲的這一優(yōu)勢,提出在PaaS中為容器掛載塊存儲的需求。
但是,憑借在IaaS中的卓越表現(xiàn),塊存儲也能夠躋身PaaS業(yè)務中嗎?
分析
假設已有一套可提供RBD塊存儲的Ceph集群的前提下,我們先來分析幾個場景:
場景一
“我使用容器技術,但還不是深度用戶,只使用docker run之類的命令來手工啟動單個容器,這些容器中運行的服務都比較消耗磁盤空間?!?/p>
這類用戶局限于將容器作為一個臨時工具,并沒有將其與業(yè)務緊密結(jié)合。
- 如果對磁盤沒有持久化的需求,那么在主機磁盤空間空余足夠的情況下可以考慮直接映射宿主機文件系統(tǒng)。
- 若想讓磁盤獨占共享磁盤,或希望在不同宿主機上啟用容器時,均能重復使用之前訪問過的數(shù)據(jù)卷;此時可以在啟動docker時,指定volume-driver為ceph-rbd的方式來使用由Ceph集群提供的塊存儲。
塊存儲驅(qū)動框架圖如下所示:
場景二
“我使用容器編排工具來管理應用,比如docker-compose、Rancher或Kubernetes。但我在每一個service下只需要啟用一個container,且對service沒有擴容的需求;這些service都比較消耗磁盤,我希望在容器被重啟或重新調(diào)度后,仍可使用舊的數(shù)據(jù)盤?!?/p>
該場景比較特殊,每一個service只對應一個container。因此,不會有多個container同時讀寫一塊數(shù)據(jù)盤的需求,只需保障container之前所掛載的存儲卷在container故障恢復或正常遷移后依然能夠被container訪問即可;即存儲卷對容器的自動跟隨。
遷移場景如下圖所示:
但是,值得注意的是:
- 假設之前的container運行在host-1上,對應的,塊存儲就掛載在host-1上。
- 當原有container因故被調(diào)度到新的host-2上時,編排框架檢測到該變化,將host-1上的原有塊設備卸載,然后掛載到host-2。
- 按照該流程,塊存儲的每一次遷移都需要從一臺主機上卸載,再到另外一臺主機上掛載;新container的啟動依賴于volume,因此容器或者業(yè)務的恢復速度依賴于塊存儲的遷移速度。
- 假設平臺未能及時檢測到host-1上的container故障、舊有的container卡死無法快速銷毀,或者host-1突然斷電時,Ceph Server必須等待超時后,才允許host-2重新掛載之前被使用的RBD塊。此時,container啟動時間就會變得難以忍受,顯然這是與容器的秒起秒停的優(yōu)勢相互違背的。
場景三
我使用Rancher或者Kubernetes之類的容器編排軟件來管理應用,每一個應用有多個微服務;每一個微服務又對應多個容器來并行對外提供服務。
Rancher
在Rancher里面,應用被稱之為Stack,每一個stack包含一到多個service;?service即微服務,微服務之間按照單一職責劃分,只做一件事情。service屬于邏輯的概念,真正做事的是各service對應的containers。如果希望通過為service擴容,就增加service對應的container數(shù)量;這些container無狀態(tài),可被調(diào)度到多臺宿主機上,它們必須使用共享存儲來保障業(yè)務的持續(xù)性。
Kubernetes
在Kubernetes中,業(yè)務也是由一到多個service來共同完成的,這里的service與Rancher中service的概覽類似。Kubernetes的service是一個外部訪問點(endpoint),通過selector指定labels的方式可以選定一組pods,service為這組pods提供訪問代理和負載均衡。外部的客戶端只需知道service所暴露的端口和IP就能夠訪問到業(yè)務。由于pod是無狀態(tài)的,因此同Rancher一樣,也需要將業(yè)務數(shù)據(jù)存儲到共享存儲上,還必須保障同一個service對應的多個pods均能共享該業(yè)務數(shù)據(jù)。
限于塊存儲只能同時被一個客戶端(主機)所掛載,當service的多個containers或pods調(diào)度到多臺主機上時,塊存儲就難以應付了。此時,原始共享文件系統(tǒng)的方法又體現(xiàn)出了它的優(yōu)勢,NAS會是一個最好的選擇!