深刻淺出聊聊Kubernetes存儲(一):詳解Kubernetes存儲關鍵概念

Kubernetes存儲全解!你知道PV和PVC的區別嗎?storage class和provisioner是什麼關係?VolumeClaimTemplates是什麼?何時用statefulset?數據庫


近年來一直關注雲計算領域的人,一定知道Docker和Kubernetes的崛起。現在,世界範圍內的公有云巨頭(谷歌、亞馬遜、微軟、華爲雲、阿里雲等等)都在其傳統的公共雲服務之上提供託管的Kubernetes服務。Kubernetes功能強大、擴展性高,在許多人看來,它正在成爲雲計算的終極解決方案。框架

但不得不說的是,儘管Kubernetes創建在谷歌在生產環境運行工做負載的超過15年的經驗之上,它很是複雜,一些設計決策老是讓用戶難以理解。即便對於經驗最豐富的工程師來講,Kubernetes的學習曲線也很陡峭。性能

就以存儲來舉例。你知道PV和PVC的區別嗎?storage class和provisioner的關係是什麼?VolumeClaimTemplates是什麼?何時該用statefulset?學習

在本文中,我將嘗試解釋Kubernetes中的一些關鍵概念,以及我對它們的見解。我但願這也會幫助你們更多地瞭解Kubernetes。使用Kubernetes時,有許多設計選擇和警告讓我意想不到。今天我將講講PV、PVC、Storage Class和Provisioner。阿里雲

Docker中的Volume(卷)雲計算

在深刻了解Kubernetes以前,讓咱們先聊聊Docker——畢竟Kubernetes是構建在Docker之上。spa

Docker因其簡單易用聞名,這也是Docker能如此受歡迎,併成爲Kubernetes基礎的緣由。Docker容器是無狀態、快速的,它能夠被破壞、重建,而不須要付出太多的代價。可是,就像是患了健忘症的人,想要記住有意義的事情是很困難的同樣。不管是數據庫、鍵值存儲、仍是一些原始數據,每個都須要持久化存儲。插件

在Docker中建立持久化存儲很是簡單。早期版本中,用戶可使用-v來建立一個新的未定義大小的匿名空卷或者在主機上的目錄中建立綁定掛載。那個時候,雖然能夠很容易地經過掛載那些已經被存儲供應商掛載在主機上的目錄,但沒有第三方接口幫助你直接掛載到Docker上。2015年8月,Docker發佈了v1.8版本,正式引入了卷插件,容許第三方鏈接它們的存儲解決方案。Docker會調用已安裝的卷插件來建立/刪除/掛載/卸載/get/list那些相關卷,並且每一個卷都有一個名字,直到今天,卷插件的框架基本仍保持不變。設計

持久卷和持久卷聲明對象

當你想弄清楚如何在Kubernetes中建立持久存儲時,可能會遇到兩個概念:持久卷(Persistent Volume,PV)和持久卷聲明(Persistent Volume Claim,PVC)

它們是什麼?它們中哪一個更接近Docker中的卷?

實際上,它們都不像Docker中的卷。除了PV和PVC以外,Kubernetes還有一個Volume的概念,但它與Docker中的概念不一樣,稍後咱們會討論它。

若是你瞭解一些關於PV和PVC信息,可能會意識到PV就是分配的存儲,而PVC是使用該存儲的請求。若是之前你有云計算或存儲的經驗,那麼你可能會認爲PV就是一個存儲池,而PVC是一個從存儲池中分割出來的卷。

不過這都不是PV和PVC真正的意義,在Kubernetes中,一個PV映射到一個PVC,反之亦然,它是一對一的映射。

我已經屢次給具備豐富存儲和雲計算經驗的人解釋過這些問題,他們幾乎都是抓耳撓腮,不明白這是怎麼回事。

而在我第一次遇到這兩個概念的時候,我也無法理解。

咱們在這裏列出PV和PVC的定義

PersistentVolume(PV)是集羣中由管理員配置的一塊存儲。它是集羣中的資源,就和節點是集羣資源同樣。PV是卷插件好比Volumes,可是它的生命週期獨立於使用PV的任何pod個體。該API對象捕獲實現存儲的詳細信息,包括NFS、iSCSI或着是雲服務商特定的存儲系統。
PersistentVolumeClaim(PVC)是用戶關於存儲的請求。它相似於一個pod,pod消耗節點資源,而PVC消耗PV資源。Pods能夠請求特定級別的資源(CPU和內容),而Claim能夠請求特定的大小和訪問模式(例如,能夠一次讀/寫或者屢次只讀)。

這裏須要留意的是「管理員」以及「用戶」的區別。

簡而言之,Kubernetes將基本存儲單元分爲兩個概念。PV是一個存儲器,應該由管理員預先分配,而PVC是用戶對存儲的請求。

也就是說,Kubernetes但願管理員來實現分配各類大小的PV。當用戶建立PVC來請求存儲時,Kubernetes將嘗試用該PVC和預先分配的PV匹配。若是能夠找到匹配項,就將PVC綁定到PV,用戶就能夠開始使用這片預分配的存儲區。

這種方式和傳統方法不一樣,傳統方法中管理員並不負責分配每一個存儲空間。他們只須要授予用戶訪問某個存儲池的權限,而且肯定該用戶的配額是多少,而後讓用戶從存儲池中分割出所需的存儲部分便可。

不過在Kubernetes的設計中,PV已經從存儲池中分割了出來,等待和PVC進行匹配,所以用戶只能請求到預先分配的固定大小的存儲空間。這就出現了兩種狀況:

若是用戶只須要1GiB的卷,而可用的最小PV是1TiB,那麼用戶就必須使用這個1TiB的卷。這樣以後其餘用戶就無法使用到這個卷,而這些用戶可能需求的容量超過了1GiB。這不只會形成存儲空間的浪費,還會致使因爲資源限制沒法啓動某些工做負載的狀況,而其餘的工做負載可能正佔有了不須要的資源。

爲了解決第一個問題,管理員要麼須要不斷地和用戶保持通訊,肯定用戶須要的存儲大小/性能,要麼就預測好需求,並相應地預先分配PV。

這樣一來就很難強制執行單獨的分配(PV)和使用(PVC)。在實際使用中,我並無看到你們講PV和PVC做爲他們的設計方式。極可能管理員很快就放棄了建立PV的權限並把它委託給用戶執行。因爲PV和PVC仍然是一對一的綁定,PVC的存在就變得不那麼必要了。

在我看來,至少能夠說,使用PV和PVC的示例是不常見的。

Storage Class和Provisioner

可能由於PV和PVC使用起來太麻煩了,在2017年3月,隨着v1.6版本的發佈,Kubernetes引入了動態納管(dynamic provisioning)、Storage Class和Provisioner的概念。動態納管與傳統存儲方法相似。管理員可使用Storage Class來描述他們提供的存儲「class」。Storage Class能夠有不一樣的容量限制、不一樣的IOPS或其餘Provisioner支持的參數。特定於存儲供應商的Provisioner將與Storage Class一塊兒使用,根據Storage Class對象中設置的參數自動分配PV。此外,Provisioner如今可以強制執行用戶的報價(quotes)和權限要求。在這種設計中,管理員已經從預測和分配PV的繁瑣中擺脫出來,這樣的方式更有意義。

另外,你還可使用Storage Class而無需在Kubernetes中建立Storage Class對象。因爲Storage Class也是用於PVC和PV(沒必要由Provisioner建立)的字段,所以你可使用自定義的Storage Class名稱手動建立PV,而後建立一個請求相同Storage Class名稱的PVC。即便存儲類Storage Class對象不存在,Kubernetes也會將PVC綁定到具備相同存儲類名稱的PV上。

dynamic provisioning、Storage Class以及Provisioner對我來講很是有意義,它解決了最初的PV和PVC設計中最大的可用性問題。但與此同時,這些新概念也加重了Kubernetes存儲的另外一個問題,即處理持久存儲的各類方式形成的混亂。在本系列文章的下一篇中,咱們將分享Kubernetes中的卷與持久化存儲的相關內容,敬請關注!

相關文章
相關標籤/搜索