PaaS中OpenShift持久化存储的管理实践
在 OpenShift 中,Pod 會被經(jīng)常性的創(chuàng)建和銷毀,也會在不同的主機(jī)之間快速的遷移。為了保證容器在重啟或者遷移以后能夠使用原來的數(shù)據(jù),就必須使用持久化存儲。所以,持久化存儲的管理對于 PaaS 平臺來說就顯得非常重要。
1
? ?
OpenShift 存儲 PV 和 PVC
OpenShift 利用 Kubernetes Persistent Volume 概念來管理存儲。管理員可以快速劃分卷提供給容器使用。開發(fā)人員通過命令行和界面申請使用存儲,而不必關(guān)心后端存儲的具體類型和工作機(jī)制。
Persistent Volume(PV)是一個開放的存儲管理框架,提供各種不同類型存儲的支持。OpenShift 默認(rèn)支持 NFS、GlusterFS、Cinder、Ceph、EBS、iSCSI 和 Fibre Channel 等存儲,用戶還可以根據(jù)需求對 PV 框架進(jìn)行擴(kuò)展,從而使其支持更多類型的存儲。
PersistentVolumeClaim (PVC) 是用戶的一個 Volume 請求。用戶通過創(chuàng)建 PVC 消費 PV 的資源。
PV 只有被 PVC 綁定后才能被 Pod 掛載使用,PV 和 PVC 的生命周期如下圖 2-72 所示:
圖2-72 PV和PVC的生命周期
從圖中可以看到,生命周期包含5個階段:
Avaliable:這個階段表示PV創(chuàng)建完成,處于可用狀態(tài)。創(chuàng)建PV可以通過手動創(chuàng)建或動態(tài)創(chuàng)建。
Pending:這個階段表示PV和PVC處于匹配狀態(tài),匹配的策略有訪問模式和卷大小,以及支持通過label匹配。如果無法匹配則PVC會一直處于Pending狀態(tài),如果可以匹配,但是后端存儲置備卷失敗,則會轉(zhuǎn)為Failure狀態(tài)。
Bound:這個階段表示PV和PVC已經(jīng)處于綁定狀態(tài),這個狀態(tài)的PVC才能被Pod掛載使用。
Release:這個階段表示掛載PVC的Pod被刪除,PVC處于釋放狀態(tài),也就是未被任何Pod掛載,但這個狀態(tài)的PV無法被PVC再次綁定。
Retain:這個階段表示刪除PVC,PV轉(zhuǎn)變?yōu)榛厥諣顟B(tài),該狀態(tài)下的PV無法直接被新的PVC綁定?;厥諣顟B(tài)下PV是否保留數(shù)據(jù)取決于PV的回收策略定義,默認(rèn)會保留。如果想要將改狀態(tài)的PV轉(zhuǎn)變?yōu)锳valiable,必須刪除PV然后重新創(chuàng)建。
在PV和PVC的生命周明中,最關(guān)鍵的兩個階段是創(chuàng)建和綁定。PV按創(chuàng)建方式的不同可分為動態(tài)PV和靜態(tài)PV。靜態(tài)PV指通過手動創(chuàng)建的PV,而動態(tài)卷是指由StorageClass(簡稱SC)自動創(chuàng)建PV。
靜態(tài)PV需要手動編輯Yaml文件并應(yīng)用到集群中,不同的存儲后端,PV的配置參數(shù)不同,如NFS后端的PV示例內(nèi)容如下:
apiVersion:?v1 kind:?PersistentVolume metadata:name:?nfs-pv0001 spec:capacity:storage:?5GiaccessModes:-?ReadWriteOncenfs:path:?/data/mydbserver:?xxx.xxx.xxx.xxxpersistentVolumeReclaimPolicy:?Retain其中訪問模式和PV容量對能否和PVC綁定至關(guān)重要。PV支持的訪問模式共有三種,如下表2-8所示:
表2-8 PV訪問模式
訪問模式 | 簡寫 | 描述 |
ReadWriteOnce | RWO | PV可以由單個Pod以讀寫方式掛載。 |
ReadOnlyMany | ROX | PV可以由多個Pod以只讀方式掛載。 |
ReadWriteMany | RWX | PV可以由多個Pod以讀寫方式掛載。 |
對于不同后端存儲對訪問模式的支持是不同的。接下來我們看一下常見后端存儲支持的PV訪問模式,如下表2-9所示:
表2-9 不同存儲后端支持的訪問模式
AWS EBS | Yes | No | No |
Azure File | Yes | Yes | Yes |
Azure Disk | Yes | No | No |
Cinder | Yes | No | No |
Fibre Channel | Yes | Yes | No |
GCE Persistent Disk | Yes | No | No |
HostPath | Yes | No | No |
iSCSI | Yes | Yes | No |
LocalVolume | Yes | No | No |
NFS | Yes | Yes | Yes |
VMware vSphere | Yes | No | No |
從上表中,我們可以看到,Azure File和NFS支持的讀寫類型是最全的。我們可以使用NAS或者配置NFS Server。當(dāng)然,企業(yè)級NAS的性能要比NFS Server好得多。在OpenShift中,除了上表列出常見存儲類型之外,還可以選擇軟件定義存儲,如Ceph,Ceph可以同時提供塊存儲RBD、對象存儲、文件系統(tǒng)存儲CephFS。
除了靜態(tài)PV之外,OpenShift還可以使用StorageClass來管理動態(tài)PV。每個StorageClass都定義一個Provisioner屬性,也就是后端存儲類型。OpenShift安裝后,會內(nèi)嵌一些Provisioner,它們的StorageClass會被自動創(chuàng)建,如下表所示:
AWS EBS | Yes | kubernetes.io/aws-ebs |
Azure File | Yes | kubernetes.io/azure-file |
Azure Disk | Yes | kubernetes.io/azure-disk |
Cinder | Yes | kubernetes.io/cinder |
Fibre Channel | No | |
GCE Persistent Disk | Yes | kubernetes.io/gce-pd |
HostPath | No | |
iSCSI | No | |
LocalVolume | No | |
NFS | No | |
VMware vSphere | Yes | kubernetes.io/vsphere-volume |
如果要創(chuàng)建一個沒有對應(yīng) Provisioner的StorageClass,也稱為靜態(tài)StorageClass,可以使用kubernetes.io/no-provisioner,示例如下:
apiVersion:?storage.k8s.io/v1 kind:?StorageClass metadata: name:?static-provisioner provisioner:?kubernetes.io/no-provisioner volumeBindingMode:?WaitForFirstConsumerStorageClass創(chuàng)建之后,就可以通過創(chuàng)建PVC觸發(fā)StorageClass完成PV的創(chuàng)建。但是,靜態(tài)StorageClass除外,因為靜態(tài)StorageClass沒有真實的后端存儲,依然需要手動創(chuàng)建PV并明確指定storageClassName為靜態(tài)StorageClass的名稱,詳細(xì)的使用案例參見第三章3.2.4-2小節(jié)。
無論是通過靜態(tài)還是動態(tài)創(chuàng)建PV,只有PVC和PV綁定之后才能被Pod使用。尤其在集群中有多個不同的后端的PV,PVC如何能綁定到滿足預(yù)期的PV將成為關(guān)鍵,下面我們就進(jìn)行詳細(xì)說明。
2
? ?
PV 和 PVC 綁定邏輯
在上一小節(jié)中,我們介紹了 PV 的創(chuàng)建方式和支持的類型,那么如果一個集群中,既有多種類型的 StorageClass,又有多種不同后端的靜態(tài) PV,PVC 與 PV 的匹配遵循一定的邏輯,如下圖 2-73 所示:
圖2-73 PV和PVC匹配邏輯
從圖中可以看出動態(tài)卷優(yōu)先,如果動態(tài)卷無法滿足PVC需求,才會匹配靜態(tài)PV。而且能否匹配成功是根據(jù)PV、PVC、集群中StorageClass的配置等多方面決定的,匹配大致邏輯如下:
1. 創(chuàng)建PVC后,首先會判定PVC中是否指定了storageClassName字段,例如下面PVC定義會觸發(fā)StorageClass gp2創(chuàng)建的PV并綁定(靜態(tài)StorageClass需要手動創(chuàng)建PV,后文不再重復(fù)強(qiáng)調(diào)),如果無法找到指定的StorageClass,則PVC處于Pending狀態(tài):
kind:?PersistentVolumeClaim apiVersion:?v1 metadata: name:?pvc-claim spec: storageClassName:?gp2 accessModes: -?ReadWriteOnce resources: requests: storage:?3Gi2. 如果PVC中沒有指定storageClassName參數(shù),則會判定集群中是否有默認(rèn)StorageClass,如果存在,則會直接使用默認(rèn)StorageClass創(chuàng)建PV。一個集群最多只能有一個默認(rèn)StorageClass,表示如果PVC中未指定明確的storageClassName,則使用默認(rèn)StorageClass創(chuàng)建PV。使用如下命令將集群中一個SC設(shè)置為默認(rèn)StorageClass:
# oc annotate storageclass <SC_NAME> "storageclass.kubernetes.io/is-default-class=true"
建議不要設(shè)置靜態(tài)StorageClass為默認(rèn)StorageClass,因為靜態(tài)StorageClass不會自動創(chuàng)建PV,即使設(shè)定為默認(rèn)StorageClass,還是要手動創(chuàng)建設(shè)定storageClassName的PV,導(dǎo)致設(shè)定為默認(rèn)StorageClass沒有價值。
3. 如果集群未定義默認(rèn)StorageClass,則會進(jìn)入靜態(tài)PV匹配。首先會判定在PVC是否定義了selector用于匹配特定標(biāo)簽的PV。通常在PV上設(shè)定標(biāo)簽主要用于對PV分級,比如根據(jù)存儲性能,存儲地理位置等。例如下面的PVC就只能匹配包含storage-tier=gold且volume-type=ssd的PV,如果無法找到符合標(biāo)簽的PV則PVC處于Pending狀態(tài)。
apiVersion:?v1 kind:?PersistentVolumeClaim metadata: name:?high-performance-volume spec: accessModes: -?ReadWriteOnce resources: requests: storage:?2Gi selector: matchLabels: storage-tier:?gold volume-type:?ssd4. 如果PVC中未定義selector,或者有滿足selector的PV,則根據(jù)PVC和PV兩者中定義的訪問模式和容量大小匹配。其中訪問模式必須完全相同,而容量是只要PV定義的容量大小大于等于PVC定義的容量大小就可以匹配成功。如果訪問模式或者容量大小無法滿足需要,則PVC處于Pending狀態(tài)。
可以發(fā)現(xiàn),在動態(tài)卷綁定時只判斷storageClassName,而在靜態(tài)PV綁定時才會判斷selector、訪問模式、容量大小。
另外,需要注意的是,訪問模式和容量大小的匹配只是邏輯上的,并不會校驗后端存儲是否支持這種訪問模式或后端存儲的真實空間大小。例如我們完全可以通過多讀寫訪問模式掛載iSCSI卷,只不過由于鎖機(jī)制,無法同時啟動多個實例。
3
? ?
容器云原生存儲
OpenShift 目前主推 OpenShift Container Storage(簡稱 OCS)實現(xiàn)存儲層。OCS 主要是通過 Rook+Ceph 實現(xiàn)的。
Rook(https://rook.io/)使 Ceph 部署、引導(dǎo)、配置、供應(yīng)、擴(kuò)展、升級、遷移、災(zāi)難恢復(fù)、監(jiān)視和資源管理自動化。Operator 將啟動和監(jiān)視 Ceph ( https://rook.io/)使 Ceph 部署、引導(dǎo)、配置、供應(yīng)、擴(kuò)展、升級、遷移、災(zāi)難恢復(fù)、監(jiān)視和資源管理自動化。Operator 將啟動和監(jiān)視 Ceph ) Monitor 容器,提供 RADOS 存儲的 Ceph OSD 守護(hù)程序,以及啟動和管理其他 Ceph 守護(hù)程序。通過初始化 Pod 和運行服務(wù)所需的其他工件來管理存儲池,對象存儲(S3 / Swift)和文件系統(tǒng)的 CRD。
Rook的功能如下:
高可用性和彈性-Ceph沒有單點故障(SPOF),并且其所有組件都以高可用性的方式本地工作
數(shù)據(jù)保護(hù)-Ceph會定期清理不一致的對象,并在必要時進(jìn)行修復(fù),以確保副本始終保持一致
跨混合云的一致存儲平臺-Ceph可以部署在任何位置(內(nèi)部部署或裸機(jī)),因此無論用戶身在何處,都能提供類似的體驗
塊,文件和對象存儲服務(wù)-Ceph可以通過多個存儲接口公開您的數(shù)據(jù),從而解決所有應(yīng)用程序用例
放大/縮小-Operator完全負(fù)責(zé)添加和刪除存儲。
儀表板-Operator部署了一個儀表板,用于監(jiān)視和自檢群集。
OCS的架構(gòu)圖如下圖2-74所示:
圖2-74 OCS存儲架構(gòu)
OCS通過Operator方式進(jìn)行安裝。目前支持在OpenShift物理節(jié)點上離線安裝。
OCS的安裝很簡單,大致步驟如下圖2-75所示,安裝OCS的Operator:
圖2-75安裝OCS的Operator
接下來,利用OCS Operator部署的API創(chuàng)建Ceph集群,選擇加入到OCS的節(jié)點。此處我們選擇新添加的三個節(jié)點:如下圖2-76所示:
圖2-76 選擇OCS節(jié)點
當(dāng)OCS相關(guān)所有Pod都創(chuàng)建成功并處于Running狀態(tài),代表OCS部署成功。OCS部署成功后,我們查看OpenShift中的StorageClass,增加了Ceph相關(guān)的內(nèi)容:
# oc get sc
NAME??????????????????????????PROVISIONER?????????????????????????????AGE localblock????????????????????kubernetes.io/no-provisioner????????????51m ocs-storagecluster-ceph-rbd???openshift-storage.rbd.csi.ceph.com??????51m ocs-storagecluster-cephfs?????openshift-storage.cephfs.csi.ceph.com???51m openshift-storage.noobaa.io???openshift-storage.noobaa.io/obc?????????45m部署成功后,就可以在OpenShift中通過CSI的方式調(diào)用OCS了。
我們使用配置文件創(chuàng)建一個PVC(調(diào)用storageClassName: ocs-storagecluster-ceph-rbd):
# cat create_ns_ocs_pvc.yaml
--- kind:?Namespace apiVersion:?v1 metadata: name:?"e-library" labels: name:?"e-library" --- apiVersion:?v1 kind:?PersistentVolumeClaim metadata: name:?ocs-pv-claim labels: name:?"e-library" namespace:?"e-library" spec: accessModes: -?ReadWriteOnce resources: requests: storage:?10Gi storageClassName:?ocs-storagecluster-ceph-rbd查看PVC創(chuàng)建成功,并且OCS自動創(chuàng)建PV與之綁定。
# oc get pvc
NAME???????????STATUS???VOLUME?????????????????????????????????????CAPACITY???ACCESS?MODES???STORAGECLASS??AGE ocs-pv-claim???Bound????pvc-f06484c8-abd7-11ea-b311-0242ac110022???10Gi???????RWO????????????ocs-storagecluster-ceph-rbd??3m52s接下來,我們就可以創(chuàng)建Pod來消費這個PVC了。
在OCS早期版本,只支持內(nèi)置模式,也是就說,必須把OCS裝在OpenShift上,利用OpenShift的Worker Node的本地存儲空間做存儲空間。這種模式部署、使用都很方便。唯一的問題是:存儲服務(wù)器無法與OpenShift集群解耦。
OCS 從v4.5版本開始支持外部的存儲模式。也就是說,通過OpenShift上安裝的OCS Operator,可以對接在外部物理機(jī)上安裝的Ceph。然后以O(shè)penShift中Rook的方式管理外部物理機(jī)上的Ceph,實現(xiàn)存儲服務(wù)器與OpenShift集群解耦。
我們在OpenShift上部署OCS Operator后,可以選擇連接外部的Cluster:然后提示下載Python腳本。將這個腳本在外置的Ceph集群的任意一個Monitor節(jié)點上執(zhí)行,獲取到Ceph集群信息,輸入到OCS對接外部存儲的位置,如下圖2-77所示:
圖2-77 OCS對接外置存儲
我們將這個腳本在外置的ceph的mon的節(jié)點上執(zhí)行:
首先查看腳本的使用幫助:
#python?ceph-external-cluster-details-exporter.py?--help在下面的命令中,rbd-data-pool-name指定要創(chuàng)建的pool的名稱;rgw-endpoint指定Ceph集群對象網(wǎng)關(guān)地址:
#python?ceph-external-cluster-details-exporter.py?--rbd-data-pool-name?abc?--rgw-endpoint?192.168.18.203:8080命令執(zhí)行后,會以json的方式返回一大串輸出結(jié)果,我們將結(jié)果粘貼到如到上圖2-77的所示的空白處,即可完成添加。由于后續(xù)的操作步驟與內(nèi)置模式類似,因此不再展開說明。
OCS對接外置Ceph存儲的后續(xù)步驟,請參考repo中“ocs外置存儲方式”。
4
? ?
OpenShift/kubernetes 存儲趨勢
在 OpenShift 的網(wǎng)絡(luò)部分,我們提到了一個開源項目 CNI。它定義網(wǎng)絡(luò)插件和容器之間的通用接口,實現(xiàn)了容器運行時與 SDN 的松耦合。那么,在容器存儲方面,有沒有類似的開源項目呢?
開源項目 Container Storage Interface(CSI)正是這個目的。CSI旨在提供一種標(biāo)準(zhǔn),將任意塊存儲和文件存儲在符合這種標(biāo)準(zhǔn)的情況下,可以為Kubernetes上的容器化提供持久存儲。隨著CSI的采用,Kubernetes存儲層變得真正可擴(kuò)展。使用CSI,第三方存儲提供商可以編寫和部署插件,在Kubernetes中公開新的存儲系統(tǒng),而無需觸及核心Kubernetes代碼。CSI為Kubernetes用戶提供了更多存儲選項,使系統(tǒng)更加安全可靠。目前在OpenShift中的CSI正式GA。
CSI是通過External CSI Controllers實現(xiàn)的,它是一個運行在Infra節(jié)點包含三個容器的Pod。如下圖2-78所示:
external CSI attacher container:它將從OpenShift發(fā)過來的attach 和detach調(diào)用轉(zhuǎn)換為對CSI driver的ControllerPublish和ControllerUnpublish調(diào)用。
external CSI provisioner container,它將從OpenShift發(fā)過來的provision 和 delete的調(diào)用轉(zhuǎn)化為對CSI Driver的CreateVolume 和 DeleteVolume ?的調(diào)用。
CSI driver container
圖2-78 OpenShift CSI邏輯圖
通過一個CSI Driver DaemonSet,在每個OpenShift節(jié)點上啟動一個Driver容器。它允許OpenShift將CSI driver提供的存儲掛載到OpenShift節(jié)點,并將其映射掛載到Pod中。
需要指出的是,從Ceph 社區(qū)版本v14開始,OpenShift訪問Ceph必須要有CSI Driver,無法繞開CSI直接訪問Ceph存儲。
本文選自《OpenShift在企業(yè)中的實踐》(第2版),經(jīng)出版社授權(quán)發(fā)布。
掃碼京東購買
推薦語:經(jīng)典暢銷書再次升級!紅帽首席解決方案架構(gòu)師聯(lián)合撰寫,20位全球知名企業(yè)IT負(fù)責(zé)人推薦,基于OpenShift v4,詳述PaaS、DevOps、云原生、微服務(wù)治理。完整描繪企業(yè)數(shù)字化轉(zhuǎn)型路線,為企業(yè)通過OpenShift實現(xiàn)IT轉(zhuǎn)型給出具體建議和參考架構(gòu)。
微信淘寶等平臺要互通!?騰訊阿里字節(jié)回應(yīng)
2021-09-14
一文詳解 API 設(shè)計最佳實踐
2021-09-12
12 種經(jīng)典億級流量架構(gòu)之資源隔離思想與方法論
2021-09-09
拼夕夕訂單超時未支付自動關(guān)閉實現(xiàn)方案!
2021-09-08
在騰訊,我們?nèi)绾巫?Code Review
2021-09-24
紫色飛豬:基于K8s的集群穩(wěn)定架構(gòu)
2021-09-23
2W 字詳解設(shè)計模式!
2021-09-22
巨人大哥聊聊電商微服務(wù)體系中分層設(shè)計和領(lǐng)域的劃分
2021-09-20
億級流量架構(gòu)怎么做資源隔離?口琴這篇寫得太好了!
2021-09-17
螞蟻集團(tuán)于雨:萬級規(guī)模 K8S 集群 Etcd 高可用建設(shè)之路
2021-09-16
干貨丨千萬流量大型分布式系統(tǒng)架構(gòu)設(shè)計實戰(zhàn)
2021-09-15
京東面試官:你是怎么理解 MySQL 的優(yōu)化原理的?
2021-09-26
在騰訊,我們?nèi)绾巫?Code Review
2021-09-24
紫色飛豬:基于K8s的集群穩(wěn)定架構(gòu)
2021-09-23
2W 字詳解設(shè)計模式!
2021-09-22
巨人大哥聊聊電商微服務(wù)體系中分層設(shè)計和領(lǐng)域的劃分
2021-09-20
億級流量架構(gòu)怎么做資源隔離?口琴這篇寫得太好了!
2021-09-17
螞蟻集團(tuán)于雨:萬級規(guī)模 K8S 集群 Etcd 高可用建設(shè)之路
2021-09-16
干貨丨千萬流量大型分布式系統(tǒng)架構(gòu)設(shè)計實戰(zhàn)
2021-09-15
微信淘寶等平臺要互通!?騰訊阿里字節(jié)回應(yīng)
2021-09-14
一文詳解 API 設(shè)計最佳實踐
2021-09-12
12 種經(jīng)典億級流量架構(gòu)之資源隔離思想與方法論
2021-09-09
美團(tuán)技術(shù):到店結(jié)算平臺實踐(膠片)
2021-09-06
Serverless實戰(zhàn)之路
2021-09-03
柴華:DDD在哈啰交易中臺的實踐
2021-09-02
建設(shè)微服務(wù)API網(wǎng)關(guān)的一些實踐
2021-10-13
新公司要上監(jiān)控,我決定用Prometheus
2021-10-12
RabbitMQ 七戰(zhàn) Kafka,差異立現(xiàn)!
2021-09-30
分布領(lǐng)域驅(qū)動設(shè)計(DDD):領(lǐng)域接口化設(shè)計式緩存的選擇
2021-09-27
新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎!定制產(chǎn)品紅包拿不停!總結(jié)
以上是生活随笔為你收集整理的PaaS中OpenShift持久化存储的管理实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 全链路灰度发布
- 下一篇: Golang之空结构体和零长数组的实践