摘要:這與不同,因?yàn)閷⒗^續(xù)存在于系統(tǒng)中,直到用戶刪除它。和持久卷聲明之間很容易弄混淆。該在直接和使用前必須已經(jīng)存在。這對(duì)于需要持久化儲(chǔ)存但只有本地卷可用的工作負(fù)載,這非常有用。此外,由于缺少,會(huì)失去使用自動(dòng)伸縮的能力。
回 顧
在本系列文章的上一篇中,我們講到了PV,PVC,Storage Class以及Provisioner
簡(jiǎn)單回顧一下:
PV在最一開(kāi)始是設(shè)計(jì)成了一個(gè)需要管理員預(yù)先分配的存儲(chǔ)塊。引入Storage Class和Provisioner之后,用戶可以動(dòng)態(tài)地供應(yīng)PV。
PVC是對(duì)PV的請(qǐng)求,當(dāng)和Storage Class一起使用時(shí),它將觸發(fā)與相匹配PV的動(dòng)態(tài)供應(yīng)。
PV和PVC總是一一對(duì)應(yīng)的。
Provisioner是給用戶提供PV的插件。它可以把管理員從為持久化創(chuàng)建工作負(fù)載的繁重角色中解脫出來(lái)。
Storage Class是PV的分類器。相同的Storage Class中的PV可以共享一些屬性。在大多數(shù)情況下,Storage Class和Provisioner一起使用時(shí),可以把它當(dāng)作具有預(yù)定義屬性的Provisioner。因此,當(dāng)用戶請(qǐng)求它時(shí),它能夠用這些預(yù)定義的屬性動(dòng)態(tài)地提供PV。
不過(guò)上述這些只是在Kubernetes中使用持久化存儲(chǔ)的其中一種方法而已
Volume
在前一篇文章中,我們提到Kubernetes中還有一個(gè)卷(Volume)的概念。為了把Volume和持久卷(Persistent Volume)區(qū)分開(kāi),大家有時(shí)會(huì)稱它為In-line Volume或者Ephemeral Volume。
這里我們引用Volume的定義:
Kubernetes Volume…有一個(gè)顯式的生命周期——這和包含它的pod的生命周期相同。因此,Volume的生命周期比在pod中運(yùn)行的任何容器都長(zhǎng),并且在容器重啟的時(shí)候會(huì)保存數(shù)據(jù)。當(dāng)然,當(dāng)Pod終止時(shí),Volume也將終止。更重要的是,Kubernetes支持多種類型的Volume,一個(gè)pod中也可以同時(shí)使用任何數(shù)量的Volume。
在其核心部分,Volume只是一個(gè)目錄,可能其中包含了一些數(shù)據(jù),這些數(shù)據(jù)可由pod中的容器訪問(wèn)。這些目錄是如何產(chǎn)生的、支持它的介質(zhì)、以及它的內(nèi)容都是由所使用的特定volume的類型決定的。在其核心部分,Volume只是一個(gè)目錄,可能其中包含了一些數(shù)據(jù),這些數(shù)據(jù)可由pod中的容器訪問(wèn)。這些目錄是如何產(chǎn)生的、支持它的介質(zhì)、以及它的內(nèi)容都是由所使用的特定volume的類型決定的。
Volume一個(gè)重要屬性是,它與所屬的pod具有相同的生命周期。如果pod消失了,它也會(huì)消失。這與Persistent Volume不同,因?yàn)镻ersistent Volume將繼續(xù)存在于系統(tǒng)中,直到用戶刪除它。Volume還可以在同一個(gè)pod中的容器間共享數(shù)據(jù),不過(guò)這不是主要的用例,因?yàn)橥ǔG闆r下用戶只會(huì)在每個(gè)pod中使用一個(gè)容器。
因此,這更可以把Volume看作是pod的屬性而不是一個(gè)獨(dú)立的對(duì)象。正如它的定義所說(shuō),Volume表示pod中的目錄,而Volume的類型定義了目錄中的內(nèi)容。例如,Config Map Volume類型將會(huì)在Volume目錄中從API服務(wù)器創(chuàng)建配置文件;PVC Volume類型將從目錄中相應(yīng)的PV里掛在文件系統(tǒng)等等。實(shí)際上,Volume幾乎是在pod中本地使用存儲(chǔ)的唯一方法。
Volume、Persistent Volume和持久卷聲明(Persistent Volume Claim)之間很容易弄混淆。假設(shè)有一個(gè)數(shù)據(jù)流,它是這樣PV->PVC->Volume。PV包含了真實(shí)數(shù)據(jù),綁定到PVC上,最終變成pod中的Volume。
然而,除了PVC,Volume還可以由Kubernetes直接支持的各種類型的存儲(chǔ)庫(kù)支持,從這個(gè)意義上來(lái)說(shuō),Volume的定義也挺令人困惑的。
我們需要知道的事,我們已經(jīng)有了Persistent Volume,它支持不同類型的存儲(chǔ)解決方案。我們還有Provisioner,它支持類似(并不完全相同)的解決方案。而且我們還有不同類型的Volume。
那么,它們到底有什么不同呢?如何在它們之間選擇?
持久化數(shù)據(jù)的多種方式
以AWS EBS為例。讓我們來(lái)細(xì)數(shù)Kubernetes中的持久化數(shù)據(jù)方式吧。
Volume方式
awsElasticBlockStore是一個(gè)Volume類型。
你可以創(chuàng)建一個(gè)Pod,定義一個(gè)awsElasticBlockStore類型的volume,設(shè)置好volumeID,接著使用pod中存在的EBS volume。
該EBS volume在直接和Volume使用前必須已經(jīng)存在。
PV方式
AWSElasticBlockStore還是一個(gè)PV類型。
所以你可以創(chuàng)建一個(gè)PV,用它來(lái)表示EBS volume(假設(shè)你有這樣的權(quán)限),然后創(chuàng)建一個(gè)和它綁定的PVC卷。最后,令PVC作為volume,然后就可以在pod中使用它了。
和Volume方法類似,EBS volume在創(chuàng)建PV之前就必須存在。
Provisioner方式
kubernetes.io/aws-ebs是一個(gè)Kubernetes中用于EBS的內(nèi)置Provisioner。
你可以用Provisioner kubernetes.io/aws-ebs來(lái)創(chuàng)建一個(gè)Storage Class,通過(guò)Storage Class創(chuàng)建PVC。Kubernetes會(huì)自動(dòng)為你創(chuàng)建相對(duì)應(yīng)的PV。接下來(lái)指定PVC為volume就可以在pod中使用了。
在本用例中,你不需要在使用使用之前創(chuàng)建EBS,EBS Provisioner會(huì)為你創(chuàng)建的。
第三方方式
上面列出的都是Kubernetes內(nèi)置選項(xiàng),如果你不太滿意的話,其實(shí)還有一些使用Flexvolume driver格式的第三方EBS實(shí)現(xiàn),它們可以幫助你和Kubernetes連接起來(lái)。
如果Flexvolume不適合你,還可以使用具備同樣功能的CSI drivers(為什么這么說(shuō)?稍后會(huì)對(duì)此進(jìn)行詳細(xì)介紹)
VolumeClaimTemplate方式
如果你在使用StatefulSet,那么恭喜你!你現(xiàn)在有額外多了一種使用工作負(fù)載中EBS的方式——VolumeClaimTemple。
VolumeClaimTemple是StatefulSet規(guī)范屬性,它為StatefulSet所創(chuàng)建的Pod提供了創(chuàng)建匹配PV和PVC的方式。這些PVC將通過(guò)Storage Class創(chuàng)建,這樣當(dāng)StatefulSet擴(kuò)展時(shí)就可以自動(dòng)創(chuàng)建它們。當(dāng)StatefulSet縮小時(shí),多余的PV/PVCs會(huì)保留在系統(tǒng)中。因此,當(dāng)StatefulSet再一次擴(kuò)展時(shí),它們會(huì)再次作用于Kubernetes創(chuàng)建的新pods中。稍后我們會(huì)詳細(xì)講StatefulSet。
舉個(gè)例子說(shuō)明,假設(shè)你用replica 3創(chuàng)建了一個(gè)名為www的StatefulSet,并用它創(chuàng)建了名為data的VolumeClaimTemplate。Kubernetes會(huì)創(chuàng)建3個(gè)pods,分別起名www-0、www-1、www-2。Kubernetes還會(huì)創(chuàng)建PVC,其中www-data-0用于pod www-0,www-data-1給www-1,www-data-2給www-2。如果你把StatefulSet擴(kuò)展到5,Kubernetes就會(huì)分別創(chuàng)建www-3、www-data-3、www-4、www-data-4。如果接著將StatefulSet降為1,www-1到www-4全都會(huì)刪除,而www-data-1到www-data-4會(huì)保留在系統(tǒng)中。因此當(dāng)你決定再次擴(kuò)展到5的時(shí)候,pod www-1到www-4又回被創(chuàng)建出來(lái),而PVC www-data-1仍然會(huì)服務(wù)于Pod www-1,www-data-2對(duì)應(yīng)www-2,以此類推。這是因?yàn)镾tatefulSet中pod的身份在是stable的。使用StatefulSet時(shí),名稱和關(guān)系都是可以預(yù)測(cè)的。
VolumeClaimTemple對(duì)于像EBS和Longhorn這樣的塊存儲(chǔ)解決方案非常重要。因?yàn)檫@些解決方案本質(zhì)上是ReadWriteOnce,你不能在Pod之間共享它們。如果你有不止一個(gè)運(yùn)行了持久化數(shù)據(jù)的pod,那么就無(wú)法順利地進(jìn)行部署。因此,VolumeClaimTemplate的出現(xiàn)為塊存儲(chǔ)解決方案提供了一種水平擴(kuò)展Kubernetes工作負(fù)載的方式。
如何在Volume、Persistent Volume和Provisioner之間做出選擇
正如你所看到的,現(xiàn)在有了內(nèi)置的Volume類型、PV類型、Provisioner類型、以及使用Flexvolume和/或CSI的外部插件。讓人比較頭大的是,它們之間提供的功能基本相同,不過(guò)也有略微的區(qū)別。
我認(rèn)為,至少應(yīng)該有一個(gè)準(zhǔn)則來(lái)確定如何在它們之間選擇。
但是我并沒(méi)有找到。
所以我翻遍了代碼和文檔,畫(huà)出了下面的比較表格,以及對(duì)我來(lái)說(shuō)最有意義的準(zhǔn)則,從Volume、Persistent Volume和Provisioner幾個(gè)方面進(jìn)行對(duì)比。
這里我只涉及到Kubernetes中in-tree所支持的,除此之外一些官方的out-of-tree的Provisioners:
https://github.com/kubernetes...
可以看到,Volume、Persistent Volume以及Provisioner在一些細(xì)微的地方還是不一樣的。
Volume支持大部分的volume插件。
A.它是連接PVC和pod的唯一方法
B.它也是唯一一個(gè)支持Config Map、Secret、Downward API以及Projected的。這些所有都與Kubernetes API服務(wù)器密切相關(guān)。
C.它還是唯一一個(gè)支持EmptyDir的,EmptyDir可以自動(dòng)給pod分配和清理臨時(shí)volume。(注:早在2015年,Clayton Coleman就提出了一個(gè)關(guān)于支持EmptyDir的問(wèn)題。這對(duì)于需要持久化儲(chǔ)存但只有本地卷可用的工作負(fù)載,這非常有用??墒沁@一觀點(diǎn)并沒(méi)有得到太多的關(guān)注。沒(méi)有scheduler的支持,這一目標(biāo)在當(dāng)時(shí)很難做到。而現(xiàn)在,在2018年,Kubernetes v1.11版本的Local Volume已經(jīng)加入scheduler和PV的節(jié)點(diǎn)親和支持(node affinity support),但是仍然沒(méi)有EmptyDir PV。而且Local Volume特性并不是我所期望的那樣,因?yàn)樗⒉痪邆湓诠?jié)點(diǎn)上使用新目錄創(chuàng)建新卷的能力。因此,我編寫(xiě)了Local Path Provisioner,它利用scheduler和PV節(jié)點(diǎn)親和更改,為工作負(fù)載提供動(dòng)態(tài)的Host Path type PV。)
PV支持的插件是Provisioner支持的超集,因?yàn)镻rovisioner需要在工作負(fù)載使用它之前創(chuàng)建PV。但是,還有一些PV支持而Provisioner不支持的插件,比如Local Volume(正在進(jìn)行修改中)。
還有兩種類型Volume是不支持的。他們是兩個(gè)最新的特性:CSI和Local Volume,現(xiàn)在還有一些正在進(jìn)行的工作,會(huì)在之后把它們用于Volume。
在Volume、Persistent Volume和Provisioner之間選擇的準(zhǔn)則
那么用戶到底應(yīng)該選擇哪種方式呢?
在我看來(lái),用戶們應(yīng)該堅(jiān)持一個(gè)原則:
在條件允許的情況下,選擇Provisioner而不是Persistent Volume,接著再是Volume。
詳細(xì)來(lái)說(shuō):
對(duì)于Config Map、Downward API、Secret或者Projected,請(qǐng)使用Volume,因?yàn)镻V不支持它們。
對(duì)于EmptyDir,直接使用Volume,或者使用Host Path來(lái)代替。
對(duì)于Host Path,通常是直接使用Volume,因?yàn)樗壎ǖ揭粋€(gè)特定的節(jié)點(diǎn),并且節(jié)點(diǎn)之間它是同構(gòu)的。
a. 如果你想用異構(gòu)的Host Path Volume,它在Kubernetes v1.11版之后才能使用,因?yàn)橹叭鄙賹?duì)PV的節(jié)點(diǎn)親和知識(shí),使用v1.11+版本,你可以使用我的Local Path Provisioner創(chuàng)建帶有節(jié)點(diǎn)親和的Host Path PV:
https://github.com/rancher/lo...。
對(duì)于其他的情況,除非你需要和現(xiàn)有的卷掛鉤(這種情況下你應(yīng)該使用PV),否則就使用Provisioner代替。有些Provisioner并不是內(nèi)置的選項(xiàng),但是你應(yīng)該能在此鏈接(https://github.com/kubernetes...)或者供應(yīng)商的官方倉(cāng)庫(kù)中找到它們。
這個(gè)準(zhǔn)則背后的原理很簡(jiǎn)單。在Kubernetes內(nèi)部進(jìn)行操作時(shí),對(duì)象(PV)比屬性(Volume)更容易管理,而且和手動(dòng)創(chuàng)建PV相比,自動(dòng)創(chuàng)建PV容易得多(Provisioner)。
不過(guò)這里有一個(gè)例外:如果你喜歡在Kubernetes外面進(jìn)行存儲(chǔ),那么最好使用Volume,盡管使用這種方式需要用到另一組API進(jìn)行創(chuàng)建/刪除。此外,由于缺少VolumeClaimTemplate,會(huì)失去使用StatefulSet自動(dòng)伸縮的能力。我不認(rèn)為這是多數(shù)Kubernetes用戶會(huì)選擇的方式。
為什么做同樣的事會(huì)有這么多選項(xiàng)?
當(dāng)我開(kāi)始研究Kubernetes存儲(chǔ)時(shí),首先想到的就是這個(gè)問(wèn)題。由于缺乏一致性和直觀性,Kubernetes存儲(chǔ)看起來(lái)就像是事后才想到的。于是我試圖研究這些設(shè)計(jì)決策背后的歷史緣由,可是在2016之前都毫無(wú)收獲。
最后,我傾向于相信這些是由于一些早期的設(shè)計(jì)造成的,這可能是為獲取供應(yīng)商支持的迫切需求,導(dǎo)致安排給Volume比原本更多的責(zé)任。在我看來(lái),所有復(fù)制了PV的內(nèi)置volume插件都不應(yīng)該存在。
在研究歷史的過(guò)程中,我發(fā)現(xiàn)在2016初發(fā)布的Kubernetes v1.2中,dynamic provisioning就已經(jīng)成為了alpha特性。它需要兩個(gè)發(fā)布版周期變成beta,在兩個(gè)周期實(shí)現(xiàn)穩(wěn)定,這都是非常合理的。
SIG Storage(它推動(dòng)了Kubernetes存儲(chǔ)開(kāi)發(fā))還進(jìn)行了大量的工作,使用Provisioner和CSI將Volume插件從tree中移出來(lái)。我認(rèn)為這是朝著更加一致、更加精簡(jiǎn)的系統(tǒng)邁出了一大步。
可另一方面,我也不認(rèn)為這一大堆Volume類型會(huì)消失。這像是和硅谷非官方的格言唱反調(diào):快速行動(dòng),打破常規(guī)。有時(shí)候,快速迭代的項(xiàng)目所遺留下來(lái)的設(shè)計(jì),修改它們實(shí)在是太難了。我們只能和它們共處,在它們身邊小心工作,不要用錯(cuò)誤的方式調(diào)用它們。
下一步
本系列的下一節(jié)中,我們將討論擴(kuò)展Kubernetes存儲(chǔ)系統(tǒng)的機(jī)制,即Flexvolume和CSI。一個(gè)小小的提示:你可能注意到了,我并不是Flexvolume的粉絲,而且這不是存儲(chǔ)子系統(tǒng)的問(wèn)題。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/32760.html
摘要:功能強(qiáng)大擴(kuò)展性高,在許多人看來(lái),它正在成為云計(jì)算的終極解決方案。我已經(jīng)多次給具有豐富存儲(chǔ)和云計(jì)算經(jīng)驗(yàn)的人解釋過(guò)這些問(wèn)題,他們幾乎都是抓耳撓腮,不明白這是怎么回事。和可能因?yàn)楹褪褂闷饋?lái)太麻煩了,在年月,隨著版本的發(fā)布,引入了動(dòng)態(tài)納管和的概念。 Kubernetes存儲(chǔ)全解!你知道PV和PVC的區(qū)別嗎?storage class和provisioner是什么關(guān)系?VolumeClaimTe...
摘要:在這三種調(diào)度框架做出選擇需要進(jìn)行驗(yàn)證根據(jù)應(yīng)用的工作方式,數(shù)量以及如何管理數(shù)據(jù)等基礎(chǔ),可以幫助縮小選擇范圍。容器安裝和運(yùn)行時(shí)對(duì)存儲(chǔ)服務(wù)進(jìn)行特定的請(qǐng)求,以實(shí)現(xiàn)如創(chuàng)建刪除檢查列表連接分離掛載卸載等功能。和一樣,它也有相同的功能和限制。 Swarm、Mesos、和Kubernetes都為各種規(guī)模的企業(yè)提供了全面的支持,如何選擇是好? API ▼ 目前找到符合企業(yè)自身需求的調(diào)度框架比較困難,Do...
摘要:如果我們的容器使用,文件如下在這個(gè)例子中,我們可以重復(fù)創(chuàng)建和銷毀,同一個(gè)持久存儲(chǔ)會(huì)被提供給新的,無(wú)論容器位于哪個(gè)節(jié)點(diǎn)上。 前言 臨時(shí)性存儲(chǔ)是容器的一個(gè)很大的買點(diǎn)。根據(jù)一個(gè)鏡像啟動(dòng)容器,隨意變更,然后停止變更重啟一個(gè)容器。你看,一個(gè)全新的文件系統(tǒng)又誕生了。 在docker的語(yǔ)境下: # docker run -it centos [root@d42876f95c6a /]# echo H...
摘要:如果我們的容器使用,文件如下在這個(gè)例子中,我們可以重復(fù)創(chuàng)建和銷毀,同一個(gè)持久存儲(chǔ)會(huì)被提供給新的,無(wú)論容器位于哪個(gè)節(jié)點(diǎn)上。 前言 臨時(shí)性存儲(chǔ)是容器的一個(gè)很大的買點(diǎn)。根據(jù)一個(gè)鏡像啟動(dòng)容器,隨意變更,然后停止變更重啟一個(gè)容器。你看,一個(gè)全新的文件系統(tǒng)又誕生了。 在docker的語(yǔ)境下: # docker run -it centos [root@d42876f95c6a /]# echo H...
閱讀 3156·2021-11-24 10:24
閱讀 2966·2021-11-11 16:54
閱讀 3086·2021-09-22 15:55
閱讀 2040·2019-08-30 15:44
閱讀 1910·2019-08-29 18:41
閱讀 2773·2019-08-29 13:43
閱讀 3063·2019-08-29 12:51
閱讀 1200·2019-08-26 12:19