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