1. 程式人生 > >kubernetes的應用數據持久化

kubernetes的應用數據持久化

基於 資源池 SQ 網絡文件系統 操作符 理解 dock 它的 分布式文件系統

1.無狀態應用與有狀態應用 應用的有狀態和無狀態是根據應用是否有持久化保存數據的需求而言的,即持久化保存數據的應用為有狀態的應用,反之則為無狀態的應用。常見的系統往往是有狀態的應用,比如對於微博和微信這類應用,所有用戶發布的內容和留言都是要保存記錄的。但是一個系統往往是由眾多微服務或更小的應用模塊構成的。有的微服務或模塊其實並沒有數據持久化的需求。例如,搭建一個Wordpress博客系統需要部署一個前端的PHP應用,以及一個後端的MySQL數據庫。雖然整個博客系統有持久化的需求,是一個有狀態的系統,但是其子模塊前端PHP應用並沒有將數據保存在本地,而是存放到MySQL數據庫中。所以一個Wordpress系統可以拆解成一個無狀態的前端以及一個有狀態的後端。有狀態和無狀態的應用在現實當中比比皆是。從實例數量上來說,無狀態的應用應該會更多一些,因為對大多數的系統而言,讀請求的數量往往遠遠高於寫請求的數量。 非持久化的容器 容器的一個特點是當容器退出後,其內部所有的數據和狀態就會丟失。同樣的鏡像再次啟動一個新的容器實例,該實例默認不會繼承之前實例的狀態。這對無狀態應用來說不是問題,相反是一個很好的特性,可以很好地保證無狀態應用的一致性。但是對於有狀態的應用來說則是很大的障礙。試想一下,如果你的MySQL容器每次重啟後,之前所有的數據都丟失了,那將會是怎樣一種災難! 容器數據持久化 不可避免地用戶會在容器中運行有狀態的應用,因此,在容器引擎的層面必須滿足數據持久化的需求。Docker在容器引擎的層面提供了卷(Volume)的概念。用戶可以建立數據卷容器來為容器提供持久化的支持。容器實例需要將持久化的數據寫入數據卷容器中保存。當應用容器退出時,數據仍然安然地在儲存於數據卷容器當中。此外Docker以插件的形式支持多種存儲方式。通過卷插件(VolumePlugin),目前Docker容器可以對接主機的目錄、軟件定義存儲(如GlusterFS及Ceph)、雲存儲(如AWS及GCE等公有雲提供的雲儲存)及儲存管理解決方案(如Flocker等)。 持久化卷與持久化卷請求 Docker在容器引擎的層面提供了卷的機制來滿足容器數據持久化的需求。在多主機的環境下,容器雲的場景中需要考慮的細節會更多。比如一個有狀態應用的容器實例從一個主機漂移到另一臺主機上時,如何保證其所掛載的卷仍然可以被正確對接。此外,在雲平臺上,用戶需要以一種簡單方式獲取和消費存儲這一資源,而無須過度關心底層的實現細節。比如用戶有一個應用,需要一個100GB的高速存儲空間儲存大量的零碎文件。用戶需要做的是向雲平臺提交資源申請,然後獲取並消費這個儲存資源,而不需要操心底層這個存儲究竟是具體來自哪一臺儲存服務器的哪一塊磁盤。 為了滿足容器用戶在雲環境儲存的需求。Kubernetes在容器編排的層面提供了持久化卷(PersistentVolume,PV)及持久化卷請求(PersistentVolumeClaim,PVC)的概念。持久化卷定義了具體的儲存的連接信息,如NFS服務器的地址和端口、卷的位置、卷的大小及訪問方式。在OpenShift中,集群管理員會定義一系列的持久化卷,形成一個持久化卷的資源池。當用戶部署有持久化需求的容器應用時,用戶需要創建一個持久化卷請求。在這個請求中,用戶申明所需儲存的大小及訪問方式。Kubernetes將負責根據用戶的持久化卷請求找到匹配需求的持久化卷進行對接。最終的結果是容器啟動後,持久化卷定義的後端儲存將會被掛載到容器的指定目錄。OpenShift在架構上基於Kubernetes,因此用戶可以在OpenShift中使用Kubernetes的持久化卷與持久化卷請求的儲存供給模型,以滿足數據持久化的需求。 技術分享圖片

技術分享圖片 2.持久化卷的生命周期 持久化卷的生命周期一共分為“供給”“綁定”“使用”“回收”及“釋放”五個階段。

1.供給 在Kubernetes中,儲存資源的供給分為兩種類型:靜態供給和動態供給。對於靜態供給,集群管理員會創建一些列的持久化卷,形成一個持久化卷的資源池。動態供給是集群所在的基礎設施雲根據需求動態地創建出持久化卷,如OpenStack、AmazonWebService。 訪問方式是描述持久化卷的訪問特性,比如是只讀還是可讀可寫。是只能被一個Node節點掛載,還是可以被多個Node節點使用。 目前有三種訪問方式可供選擇。 ·ReadWriteOnce:可讀可寫,只能被一個Node節點掛載。 ·ReadWriteMany:可讀可寫,可以被多個Node節點掛載。 ·ReadOnlyMany:只讀,能被多個Node節點掛載。 這裏要註意的是,訪問方式和後端使用的儲存有很大的關系,並不是將一個持久化卷設置為ReadWriteMany,這個持久化卷就可以被多個Node節點掛載。比如OpenStack的Cinder和CephRDB這些塊設備就不支持ReadWriteMany這種模式。在Kubernetes的官方文檔中對各種後端存儲的訪問方式有詳細的描述。 2.綁定 用戶在部署容器應用時會定義持久化卷請求持久化卷請求。用戶在持久化卷請求中聲明需要的儲存資源的特性,如大小和訪問方式。Kubernetes負責在持久化卷的資源池中尋找配的持久化卷對象,並將持久化卷請求與目標持久化卷進行對接。這時持久化卷和持久化卷請求的狀態都將變成Bound,即綁定狀態。 3.使用 在用戶部署容器時會在DeploymentConfig的容器定義中指定Volume的掛載點,並將這個掛載點和持久化卷請求關聯。當容器啟動時,持久化卷指定的後端儲存被掛載到容器定義的掛載點上。應用在容器內部運行,數據通過掛載點最終寫入後端儲存中,從而實現持久化。 4.釋放 當應用下線不再使用儲存時,可以刪除相關的持久化卷請求,這樣持久化卷的狀態就會變成released,即釋放。 5.回收 當持久化卷的狀態變為released後,Kubernetes將根據持久化卷定義的回收策略回收持久化卷。 當前支持的回收策略有三種: ·Retian:保留數據,人工回收持久化卷。 ·Recycle:通過執行rm-rf刪除卷上的所有數據。目前只有NFS及HostPath支持這種方式。 ·Delete:動態地刪除後端儲存。該模式需要下層IaaS的支持,目前AWSEBS、GCEPD及OpenStackCinder支持這種模式。 Kubernetes通過持久化卷及持久化卷請求這一供給模型為用戶提供容器雲上的儲存消費的途徑。在這個模型下,用戶可以簡單快速地構建出滿足應用需要的容器雲上的儲存解決方案。在Kubernetes1.3中,持久化卷和持久化卷請求引入了標簽的概念,這了給用戶更大的靈活性。例如,我們可以為不同類型的持久化卷貼上不同的標簽,如“SSD”“RAID0”“Ceph”“深圳機房”或“美國機房”等。用戶在持久化卷請求中可以定義相應的標簽選擇器,從而獲取更精確匹配應用需求的後端持久化卷。 3.持久化卷與儲存 Kubernetes的持久化卷支持的後端儲存的類型很多,包括宿主機的本地目錄(HostPath)、網絡文件系統(NFS)、OpenStackCinder分布式儲存(如GlusterFS、CephRBD及CephFS)及雲儲存(如AWSElasticBlockStore或GCEPersistentDisk)等。一個常見的困惑是“我應該選擇哪一種儲存?”不同的儲存後端有不同特性,並不存在一種滿足所有場景的儲存。用戶應該根據當前容器應用的需求,選擇滿足需求的儲存。 1.HostPath HostPath類型的儲存是指容器掛載所在的計算機點主機上的目錄。這種方式只適合用於以測試為目的的場景中。允許容器掛載主機目錄引入了安全風險。依賴於某一節點上的數據也使得容器和某一計算節點產生了較強的綁定關系性,引入了單點失效的風險。 2.NFS NFS是一種常用的儲存類型。NFS已經存在了很長一段時間,在UNIX和Linux上被廣泛應用,所有的Linux系統管理員對它都不會感到陌生。因為系統支持比較廣泛,NFS目前是較為常見的持久化卷的儲存後端。 3.GlusterFS GlusterFS是一個開源的分布式文件系統。GlusterFS具有很強的彈性擴展能力,用戶可以在通用的計算機硬件上使用GlusterFS構建出PB級別的儲存集群用於儲存如視頻、圖片及資料等多種類型的數據。GlusterFS的主要特點是: ·完全基於軟件實現。完全不依賴於特定的主機、儲存、網絡硬件。 ·高度彈性擴展。用戶可以構建儲存的容量從GB到PB級的儲存。 ·高可用。數據可以在儲存集成中保留多個副本,防止單點失效。 ·兼容POSIX文件系統標準。基於標準,因此對上層應用進行改造。 ·支持多種不同種類的卷。如復制卷、分布式卷及條帶卷,滿足不同場景的需求。 4.Ceph Ceph是當前非常流行的開源分布式儲存解決方案。和GlusterFS類似,Ceph也是一個完全基於軟件實現的分布式儲存。Ceph的一個特點是,其原生提供了多種接口方式,如基於RESTful的對象、塊(Block)和文件系統。GlusterFS和Ceph都是非常優秀的分布式儲存,很多人喜歡將它們進行比較。應該說GlusterFS和Ceph各有優劣,在伯仲之間,青菜蘿蔔各有所愛。 Kubernetes的持久化卷支持兩種方式掛載Ceph儲存:塊設備(RBD)及文件系統(CephFS)。目前,由於Ceph官方認為CephFS尚未完全成熟以達到企業生產使用的標準,因此雖然Kubernetes和OpenShift的代碼中已經存在CephFS的支持,但是並不推薦在生產中使用。 5.OpenStack Cinder Cinder是OpenStack塊儲存服務,負責為OpenStack上的主機實例提供靈活的儲存支持。對於運行在OpenStack上的OpenShift集群,用戶可以定義基於OpenStack Cinder的持久化卷。Cinder持久化卷的定義示例如下。volumeID屬性指向了管理員在Cinder創建的數據卷的唯一標識。 4.存儲資源定向匹配 不同用戶對儲存的需求不盡相同,除了大小和訪問方式外,可能還有對磁盤的速度、儲存所在的數據中心等有特殊的要求。為了靈活滿足儲存需求和儲存資源的對接,Kubernetes支持為持久化卷打上不同的標簽(Label),在持久化卷請求側則通過定義標簽選擇器來申明該持久化卷請求具體需要與什麽樣的持久化卷匹配。通過標簽和標簽選擇器(Selector),Kubernetes為持久化卷與持久化卷請求實現了定向匹配。 1 創建持久化卷 創建如下例子中的兩個持久化卷pv0001及pv0002。這兩個持久化卷具有相同的大小和訪問方式,且都沒有任何標簽。 2 標記標簽 通過oc label命令為持久化卷pv0002打上標簽disktype=ssd。 3 創建持久化卷請求 創建一個帶標簽選擇器的持久化卷請求。如下面的定義所示,這個持久化卷請求的儲存空間大小為1Gi,訪問方式是只讀共享RWO。標簽選擇器的類型為matchLabels,定義值為"disktype":"ssd",即表示與該持久化卷請求匹配的持久化卷必須要帶有"disktype":"ssd"標簽。 4 請求與資源定向匹配 持久化卷請求創建完後,查看持久化卷的狀態,可以看到雖然pv0001和pv0002在空間大小和訪問方式上都滿足了pvc0001的要求,但是pvc0001最終匹配上的是帶有目標標簽的pv0002。 5 標簽選擇器 目前,持久化卷請求支持兩種標簽選擇器:matchLabels及matchExpressions。 matchLabels選擇器可以精確匹配一個或多個標簽。 matchExpressions選擇器支持標簽的模糊匹配。用戶可以使用操作符In或者NotIn對標簽的值進行模糊匹配。 5.持久化實例 1 檢查掛載點 2 備份數據 在前面章節的示例中已經向Registry推送過不少鏡像,所以當前容器內的/registry目錄下已經有不少鏡像相關的文件。 需要先備份這些文件。通過ocrsync命令,可以將容器中某個目錄的數據同步到宿主機上。 oc rsync是一個很方便實用的命令,它可以雙向同步容器和宿主機上的文件。要使用這個命令,目標容器內部必須有rync或者tar這兩個應用中的一個。 3 創建存儲 為了方便實驗,本例選用NFS作為後端的儲存。在實際的生產中使用GlusterFS、Ceph或其他儲存後端的配置過程和步驟也類似。 執行以下命令創建一個NFS的共享目錄。 4 創建持久化卷 根據上面創建的NFS的信息,創建持久化卷。在實驗主機上將如下JSON保存成文件pv.json。 創建完畢後,通過oc get pv可以查看到剛創建成功的持久化卷,此時它的狀態為Available,即可用。 5 創建持久化卷請求 下面將創建持久化卷請求,聲明應用的儲存需求。在實驗主機上將如下JSON保存成文件pvc.json。這裏聲明了需要3GB的後端儲存,訪問方式為ReadWriteOnce。 查看持久化卷請求和持久化卷的狀態,會發現系統已經將它們連接起來了。持久化卷和持久化卷請求的狀態都已經變成Bound。 6 關聯持久化卷請求 將備份的數據恢復到前文創建的NFS目錄中。 此時,可以測試刪除Registry容器,Replication Controller將重新創建它。 容器啟動後,再次檢查容器/registry目錄,會發現目錄的數據應消失。因為容器默認是不持久化數據的。 為Reigstry的容器定義添加持久化卷請求docker-registry-claim,並與掛載點registry-storage關聯。 Deployment Config的容器定義修改後,OpenShift會創建新的容器實例。檢查容器/registry目錄,會發現目錄的數據恢復了。 至此,我們成功地將Registry組件掛接上了持久化儲存。本例的配置基於NFS持久化卷實現,使用GlusterFS或Ceph持久化卷的過程也類似,只是持久化卷的定義需要稍做修改。

kubernetes的應用數據持久化