- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) > web開(kāi)發(fā) >
- Kubernetes的持久化存儲解決方法
本篇內容介紹了“Kubernetes的持久化存儲解決方法”的有關(guān)知識,在實(shí)際案例的操作過(guò)程中,不少人都會(huì )遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學(xué)有所成!
Kubernetes(下稱(chēng)k8s)作為目前行業(yè)內使用最廣泛的容器編排工具,已經(jīng)深入到各個(gè)技術(shù)領(lǐng)域,正在徹底改變應用程序的開(kāi)發(fā)和部署方式;但從另一個(gè)方面講,k8s的架構是不斷變化的。容器的創(chuàng )建和銷(xiāo)毀,從本質(zhì)上講,它們的生命周期是短暫的。因而,K8s的發(fā)展歷程勢必無(wú)法繞開(kāi)持久化的問(wèn)題,本文就將從這一點(diǎn)出發(fā),為大家講解k8s在持久化存儲方面所提供的解決方案,幫助大家更好的理解k8s的整體技術(shù)生態(tài)。
本文的章節內容分配如下:
概述
K8s有哪些持久化方案
Docker存儲
K8s原生存儲
開(kāi)源存儲項目Ceph&Rook
總結
先拋一張CNCF(云原生計算基金會(huì ))公布的云原生存儲解決方案一覽圖,這里只截取了存儲的部分。
圖中列舉的存儲方案,目前都可以集成到Kubernetes平臺,
當使用Docker作為K8s的容器方案時(shí),Docker自身所支持的存儲卷也就成為了可選方案之一。Docker存儲卷是容器服務(wù)在單節點(diǎn)的存儲組織形式,作為解決數據存儲、容器運行時(shí)的技術(shù)方案;
K8s自己的持久化存儲方案更關(guān)注于應用和集群層面,主要用于容器集群的存儲編排,從應用使用存儲的角度提供存儲服務(wù)。另一方面,K8s的持久化存儲方案能夠完全兼容自身的對象,如Pod對象等,即插即用,無(wú)需二次開(kāi)發(fā)。
下面,我們就對這幾種存儲方案一一進(jìn)行解釋。
為了提高節點(diǎn)存儲的使用效率,容器不光在不同運行的容器之間共享鏡像資源,而且還實(shí)現了在不同鏡像之間共享數據。共享鏡像數據的實(shí)現原理:鏡像是分層組合而成的,即一個(gè)完整的鏡像會(huì )包含多個(gè)數據層,每層數據相互疊加、覆蓋組成了最終的完整鏡像。
為了實(shí)現多個(gè)容器間共享鏡像數據,容器鏡像每一層都是只讀的。而容器使用鏡像時(shí),在多個(gè)鏡像分層的最上面還添加了一個(gè)讀寫(xiě)層。每一個(gè)容器在運行時(shí),都會(huì )基于當前鏡像在其最上層掛載一個(gè)讀寫(xiě)層,用戶(hù)針對容器的所有操作都在讀寫(xiě)層中完成。一旦容器銷(xiāo)毀,這個(gè)讀寫(xiě)層也隨之銷(xiāo)毀。
容器中的應用讀寫(xiě)數據都是發(fā)生在容器的讀寫(xiě)層,鏡像層+讀寫(xiě)層映射為容器內部文件系統、負責容器內部存儲的底層架構。當我們需要容器內部應用和外部存儲進(jìn)行交互時(shí),還需要一個(gè)外置存儲,容器數據卷即提供了這樣的功能。
另一方面,容器本身的存儲數據都是臨時(shí)存儲,在容器銷(xiāo)毀的時(shí)候數據會(huì )一起刪除。而通過(guò)數據卷將外部存儲掛載到容器文件系統,應用可以引用外部數據,也可以將自己產(chǎn)出的數據持久化到數據卷中,因此容器數據卷是容器實(shí)現數據持久化的主要實(shí)現方式。
容器存儲組成:只讀層(容器鏡像) + 讀寫(xiě)層 + 外置存儲(數據卷)
容器數據卷從作用范圍可以分為:?jiǎn)螜C數據卷 和 集群數據卷。其中單機數據卷即為容器服務(wù)在一個(gè)節點(diǎn)上的數據卷掛載能力,docker volume 是單機數據卷的代表實(shí)現;
Docker Volume 是一個(gè)可供多個(gè)容器使用的目錄,它繞過(guò) UFS,包含以下特性:
數據卷可以在容器之間共享和重用;
相比通過(guò)存儲驅動(dòng)實(shí)現的可寫(xiě)層,數據卷讀寫(xiě)是直接對外置存儲進(jìn)行讀寫(xiě),效率更高;
對數據卷的更新是對外置存儲讀寫(xiě),不會(huì )影響鏡像和容器讀寫(xiě)層;
數據卷可以一直存在,直到?jīng)]有容器使用。
Bind:將主機目錄/文件直接掛載到容器內部。
需要使用主機的上的絕對路徑,且可以自動(dòng)創(chuàng )建主機目錄;
容器可以修改掛載目錄下的任何文件,是應用更具有便捷性,但也帶來(lái)了安全隱患。
Volume:使用第三方數據卷的時(shí)候使用這種方式。
Volume命令行指令:docker volume (create/rm);
是Docker提供的功能,所以在非 docker 環(huán)境下無(wú)法使用;
分為命名數據卷和匿名數據卷,其實(shí)現是一致的,區別是匿名數據卷的名字為隨機碼;
支持數據卷驅動(dòng)擴展,實(shí)現更多外部存儲類(lèi)型的接入。
Tmpfs:非持久化的卷類(lèi)型,存儲在內存中。
數據易丟失。
Bind掛載語(yǔ)法
-v: src:dst:opts 只支持單機版。
Src:表示卷映射源,主機目錄或文件,需要是絕對地址;
Dst:容器內目標掛載地址;
Opts:可選,掛載屬性:ro, consistent, delegated, cached, z, Z;
Consistent, delegated, cached:為mac系統配置共享傳播屬性;
Z、z:配置主機目錄的selinux label。
示例:
$ docker run -d --name devtest -v /home:/data:ro,rslave nginx $ docker run -d --name devtest --mount type=bind,source=/home,target=/data,readonly,bind-propagation=rslave nginx $ docker run -d --name devtest -v /home:/data:z nginx
-v: src:dst:opts 只支持單機版。
Src:表示卷映射源,數據卷名、空;
Dst:容器內目標目錄;
Opts:可選,掛載屬性:ro(只讀)。
示例:
$ docker run -d --name devtest -v myvol:/app:ro nginx $ docker run -d --name devtest --mount source=myvol2,target=/app,readonly nginx
Docker 數據卷實(shí)現了將容器外部存儲掛載到容器文件系統的方式。為了擴展容器對外部存儲類(lèi)型的需求,docker 提出了通過(guò)存儲插件的方式掛載不同類(lèi)型的存儲服務(wù)。擴展插件統稱(chēng)為 Volume Driver,可以為每種存儲類(lèi)型開(kāi)發(fā)一種存儲插件。
可以查看官方文檔鏈接:
https://docs.docker.com/engine/extend/legacy_plugins/#volume-plugins
其特性簡(jiǎn)單來(lái)說(shuō)可以總結為2點(diǎn):
單個(gè)節點(diǎn)上可以部署多個(gè)存儲插件;
一個(gè)存儲插件負責一種存儲類(lèi)型的掛載服務(wù)。
關(guān)于Volume plugin的代碼實(shí)現,可以參考這篇小文章:Docker 17.03-CE create plugin源碼解析
Docker Plugin 是以Web Service的服務(wù)運行在每一臺Docker Host上的,通過(guò)HTTP協(xié)議傳輸RPC風(fēng)格的JSON數據完成通信。Plugin的啟動(dòng)和停止,并不歸Docker管理,Docker Daemon依靠在缺省路徑下查找Unix Socket文件,自動(dòng)發(fā)現可用的插件。
當客戶(hù)端與Daemon交互,使用插件創(chuàng )建數據卷時(shí),Daemon會(huì )在后端找到插件對應的 socket 文件,建立連接并發(fā)起相應的API請求,最終結合Daemon自身的處理完成客戶(hù)端的請求。
Docker Daemon 與 Volume driver 通信方式有:
Sock文件:linux 下放在/run/docker/plugins 目錄下
Spec文件:/etc/docker/plugins/convoy.spec 定義
Json文件:/usr/lib/docker/plugins/infinit.json 定義
實(shí)現接口:
Create, Remove, Mount, Path, Umount, Get, List, Capabilities;
使用示例:
$ docker volume create --driver nas -o diskid="" -o host="10.46.225.247" -o path=”/nas1" -o mode="" --name nas1
Docker Volume Driver 適用在單機容器環(huán)境或者 swarm 平臺進(jìn)行數據卷管理,隨著(zhù) K8s 的流行其使用場(chǎng)景已經(jīng)越來(lái)越少,這里不做贅述。
如果說(shuō)Docker注重的是單節點(diǎn)的存儲能力,那K8s 數據卷關(guān)注的則是集群級別的數據卷編排能力。
Kubernetes 提供是卷存儲類(lèi)型,從存在的生命周期可分為臨時(shí)和持久卷。 從卷的類(lèi)型分,又可以分為本地存儲、網(wǎng)絡(luò )存儲、Secret/ConfigMap、CSI/Flexvolume、PVC;有興趣的小伙伴可以參考一下官方文檔:
【Kubernetes文檔-卷】
https://kubernetes.io/zh/docs/concepts/storage/volumes/
這里就以一幅圖來(lái)展示各個(gè)存儲的存在形式。
如上圖所示:
最上層的pod和PVC由用戶(hù)管理,pod創(chuàng )建volume卷,并指定存儲方式。
中間部分由集群管理者創(chuàng )建StorageClass對象,StorageClass只需確定PV屬性(存儲類(lèi)型,大小等)及創(chuàng )建PV所需要用的的存儲插件;K8s會(huì )自動(dòng)根據用戶(hù)提交的PVC來(lái)找到對應的StorageClass,之后根據其定義的存儲插件,創(chuàng )建出PV。
最下層指代各個(gè)實(shí)際的存儲資源。
這里單獨來(lái)聊聊PV和PVC,也是實(shí)際應用場(chǎng)景中最常用的一組概念,其中:
PV 是 PersistentVolume 的縮寫(xiě),譯為持久化存儲卷;PV 在 K8s 中代表一個(gè)具體存儲類(lèi)型的卷,其對象中定義了具體存儲類(lèi)型和卷參數。即目標存儲服務(wù)所有相關(guān)的信息都保存在 PV 中,K8s 引用 PV 中的存儲信息執行掛載操作。
PVC的存在,是從應用角度對存儲卷進(jìn)行二次抽象;由于 PV 描述的是對具體存儲類(lèi)型,需要定義詳細的存儲信息,而應用層用戶(hù)在消費存儲服務(wù)的時(shí)候往往不希望對底層細節知道的太多,讓?xiě)镁幣艑用鎭?lái)定義具體的存儲服務(wù)不夠友好。這時(shí)對存儲服務(wù)再次進(jìn)行抽象,只把用戶(hù)關(guān)系的參數提煉出來(lái),用 PVC 來(lái)抽象更底層的 PV。所以 PVC、PV 關(guān)注的對象不一樣,PVC 關(guān)注用戶(hù)對存儲需求,給用戶(hù)提供統一的存儲定義方式;而 PV 關(guān)注的是存儲細節,可以定義具體存儲類(lèi)型、存儲掛載使用的詳細參數等。其具體的對應關(guān)系如下圖所示:
PVC 只有綁定了 PV 之后才能被 Pod 使用,而 PVC 綁定 PV 的過(guò)程即是消費 PV 的過(guò)程,這個(gè)過(guò)程是有一定規則的,下面規則都滿(mǎn)足的 PV 才能被 PVC 綁定:
VolumeMode:被消費 PV 的 VolumeMode 需要和 PVC 一致;
AccessMode:被消費 PV 的 AccessMode 需要和 PVC 一致;
StorageClassName:如果 PVC 定義了此參數,PV 必須有相關(guān)的參數定義才能進(jìn)行綁定;
LabelSelector:通過(guò) label 匹配的方式從 PV 列表中選擇合適的 PV 綁定;
storage:被消費 PV 的 capacity 必須大于或者等于 PVC 的存儲容量需求才能被綁定。
PVC模板:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: disk-1 spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi storageClassName: test-disk volumeMode: Filesystem
PV模板:
apiVersion: v1 kind: PersistentVolume metadata: labels: failure-domain.beta.kubernetes.io/region: cn-zn failure-domain.beta.kubernetes.io/zone: cn-zn name: d-wz9g2j5qbo37r2lamkg4 spec: accessModes: - ReadWriteOnce capacity: storage: 30Gi flexVolume: driver: alicloud/disk fsType: ext4 options: VolumeId: d-wz9g2j5qbo37r2lamkg4 persistentVolumeReclaimPolicy: Delete storageClassName: test-disk volumeMode: Filesystem
圍繞云原生技術(shù)的工具和項目正在大量涌現。作為生產(chǎn)中最突出的問(wèn)題之一,有相當一部分開(kāi)源項目致力于解決“在云原生架構上處理存儲”這個(gè)問(wèn)題。
目前最受歡迎的存儲項目是Ceph和Rook。
Ceph是一個(gè)動(dòng)態(tài)管理的、水平可伸縮的分布式存儲集群。Ceph提供了對存儲資源的邏輯抽象。它被設計成不存在單點(diǎn)故障、可自我管理和基于軟件的。Ceph同時(shí)為相同的存儲集群提供塊、對象或文件系統接口。它能夠提供非常穩定的塊存儲系統,并且K8S對Ceph放出了完整的生態(tài),幾乎可以說(shuō)是全面兼容。
Ceph的架構非常復雜,有許多底層技術(shù),如RADOS、librados、RADOSGW、RDB,它的CRUSH 算法和監視器、OSD和MDS等組件。這里不深入解讀其架構,關(guān)鍵在于,Ceph是一個(gè)分布式存儲集群,它可提供更高的可伸縮性,在不犧牲性能的情況下消除了單點(diǎn)故障,并提供了對對象、塊和文件的訪(fǎng)問(wèn)的統一存儲。
對于Rook,我們可以從以下幾點(diǎn)來(lái)了解這個(gè)有趣的項目。它旨在聚合Kubernetes和Ceph的工具——將計算和存儲放在一個(gè)集群中。
Rook 是一個(gè)開(kāi)源的cloud-native storage編排, 提供平臺和框架;為各種存儲解決方案提供平臺、框架和支持,以便與云原生環(huán)境本地集成。
Rook 將存儲軟件轉變?yōu)樽晕夜芾?、自我擴展和自我修復的存儲服務(wù),它通過(guò)自動(dòng)化部署、引導、配置、置備、擴展、升級、遷移、災難恢復、監控和資源管理來(lái)實(shí)現此目的。
Rook 使用底層云本機容器管理、調度和編排平臺提供的工具來(lái)實(shí)現它自身的功能。
Rook 目前支持Ceph、NFS、Minio Object Store和CockroachDB。
Rook使用Kubernetes原語(yǔ)使Ceph存儲系統能夠在Kubernetes上運行。
所以在ROOK的幫助之下我們甚至可以做到一鍵編排部署Ceph,同時(shí)部署結束之后的運維工作ROOK也會(huì )介入自動(dòng)進(jìn)行實(shí)現對存儲拓展,即便是集群出現了問(wèn)題ROOK也能在一定程度上保證存儲的高可用性,絕大多數情況之下甚至不需要Ceph的運維知識都可以正常使用。
https://github.com/rook/rook.git
rook倉庫中,
cluster/examples/kubernetes/ceph/common.yaml 文件。
#運行common.yaml文件 kubectl create -f common.yaml
編排文件為
/cluster/examples/kubernetes/ceph/operator.yaml
#運行operator.yaml文件 kubectl create -f operator.yaml
#獲取命名空間下運行的pod,等待所以的pod都是running狀態(tài)之后繼續下一步
kubectl -n rook-ceph get pod
編排文件為
/cluster/examples/kubernetes/ceph/cluster.yaml
這里也需要進(jìn)行一定的基礎配置與修改才能繼續,cluster.yaml文件內容如下:
apiVersion: ceph.rook.io/v1 kind: CephCluster metadata: name: rook-ceph namespace: rook-ceph spec: cephVersion: image: ceph/ceph:v14.2.6 allowUnsupported: false dataDirHostPath: /var/lib/rook skipUpgradeChecks: false continueUpgradeAfterChecksEvenIfNotHealthy: false mon: #這里是最重要的,mon是存儲集群的監控器,我們K8S里面有多少主機這里的就必須使用多少個(gè)mon count: 3 allowMultiplePerNode: false dashboard: #這里是是否啟用監控面板,基本上都會(huì )使用 enabled: true #監控面板是否使用SSL,如果是使用8443端口,不是則使用7000端口,由于這是運維人員使用建議不啟用 ssl: true monitoring: enabled: false rulesNamespace: rook-ceph network: hostNetwork: false rbdMirroring: workers: 0 crashCollector: disable: false annotations: resources: removeOSDsIfOutAndSafeToRemove: false storage: useAllNodes: true useAllDevices: true config: disruptionManagement: managePodBudgets: false osdMaintenanceTimeout: 30 manageMachineDisruptionBudgets: false machineDisruptionBudgetNamespace: openshift-machine-api
#運行cluster.yaml文件 kubectl create -f cluster.yaml
如果上面部署時(shí),啟用了SSL則需要使用
/cluster/examples/kubernetes/ceph/dashboard-external-https.yaml,否則使用同目錄下的dashboard-external-http.yaml文件:
#dashboard沒(méi)有啟用SSL kubectl create -f dashboard-external-http.yaml #dashboard啟用SSL kubectl create -f dashboard-external-https.yaml
運維人員可以直接通過(guò)對這個(gè)容器的shell進(jìn)行Ceph集群的控制(后面有實(shí)例),編排文件是toolbox.yaml
#安裝Ceph工具 kubectl create -f toolbox.yaml
集群搭建完畢之后便是存儲的創(chuàng )建,目前Ceph支持塊存儲、文件系統存儲、對象存儲三種方案,K8S官方對接的存儲方案是塊存儲,他也是比較穩定的方案,但是塊存儲目前不支持多主機讀寫(xiě);文件系統存儲是支持多主機存儲的性能也不錯;對象存儲系統IO性能太差不考慮,所以可以根據要求自行決定。
存儲系統創(chuàng )建完成之后對這個(gè)系統添加一個(gè)存儲類(lèi)之后整個(gè)集群才能通過(guò)K8S的存儲類(lèi)直接使用Ceph存儲。
塊存儲系統+塊存儲類(lèi)yaml文件:
apiVersion: ceph.rook.io/v1 kind: CephBlockPool metadata: name: replicapool namespace: rook-ceph spec: failureDomain: host replicated: size: 3 #這里的數字分部署數量,一樣有幾臺主機便寫(xiě)入對應的值 --- apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: rook-ceph-block provisioner: rook-ceph.rbd.csi.ceph.com parameters: clusterID: rook-ceph pool: replicapool imageFormat: "2" imageFeatures: layering csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph csi.storage.k8s.io/fstype: xfs reclaimPolicy: Delete
文件系統存儲yaml文件:
apiVersion: ceph.rook.io/v1 kind: CephFilesystem metadata: name: myfs namespace: rook-ceph spec: metadataPool: replicated: size: 3 #這里的數字分部署數量,一樣有幾臺主機便寫(xiě)入對應的值 dataPools: - replicated: size: 3 #這里的數字分部署數量,一樣有幾臺主機便寫(xiě)入對應的值 preservePoolsOnDelete: true metadataServer: activeCount: 1 activeStandby: true
文件系統存儲類(lèi)yaml文件:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: csi-cephfs provisioner: rook-ceph.cephfs.csi.ceph.com parameters: clusterID: rook-ceph fsName: myfs pool: myfs-data0 csi.storage.k8s.io/provisioner-secret-name: rook-csi-cephfs-provisioner csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph csi.storage.k8s.io/node-stage-secret-name: rook-csi-cephfs-node csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph reclaimPolicy: Delete
本文通過(guò)介紹并圖解K8s中各個(gè)存儲方案實(shí)現方式以及可選擇的開(kāi)源項目,為讀者呈現更全面的K8s存儲方案選擇。在我們實(shí)際的使用場(chǎng)景中,亦需要根據特定的需求來(lái)制定符合項目要求的存儲方案,從而達到最好的實(shí)現效果。也希望有更多的朋友能夠加入到kubernetes的隊伍中來(lái),讓kubernetes真正深入到眾多的用戶(hù)和企業(yè)中去。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系站長(cháng)郵箱:ts@56dr.com進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2 建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站