天天看點

開源雲原生存儲rook:塊存儲快速入門實戰

作者:不背鍋運維

Block Devices(塊存儲)

開源雲原生存儲rook:塊存儲快速入門實戰

在 Rook 中,塊存儲有兩種存儲類型:副本存儲和糾删碼存儲。這兩種存儲類型都可以在 Kubernetes 叢集中使用,可以通過在 CephBlockPool 中指定不同的存儲類别來實作。

  • 「副本存儲:」 是一種基于副本的存儲方式,其中資料被複制到多個節點上,以提高資料的可靠性和可用性。在副本存儲中,資料被複制到指定數量的節點,當其中任何一個節點出現故障時,系統仍然可以從其它節點讀取資料,進而保證了資料的可靠性和可用性。
  • 「糾删碼存儲:」 是一種基于糾删碼的存儲方式,其中資料被編碼為多個資料塊,并在不同的節點上存儲這些資料塊的編碼片段。在糾删碼存儲中,資料被編碼為多個資料塊,并根據指定的參數對這些資料塊進行編碼。編碼後的資料塊被分散存儲到不同的節點上,當某個節點出現故障時,系統可以使用存儲在其它節點上的資料塊編碼片段來恢複資料。糾删碼存儲在資料可靠性和存儲效率方面具有優勢,但它通常需要更多的 CPU 和網絡資源來執行編碼和解碼操作。

如何選擇

在生産環境中選擇 Rook 中的副本存儲或糾删碼存儲需要考慮多個因素,包括資料的重要性、可用性要求、存儲成本和系統性能等。

  • 副本存儲提供了簡單、易于管理的資料備援解決方案,通過複制多個資料副本到不同的節點上來提高資料的可靠性和可用性。在副本存儲中,資料的每個副本都可以直接讀取和寫入,是以可以提供較低的讀寫延遲和較高的吞吐量。
  • 糾删碼存儲通過對資料進行編碼和分片,将資料的備援資訊分布到不同的節點上,以提高資料的可靠性和可用性。糾删碼存儲通常需要更少的存儲空間和更低的存儲成本,因為它隻需要存儲資料的備援分片而不是完整的副本。但是,在讀取和寫入資料時,需要對多個節點進行通信和協調,是以可能會帶來更高的讀寫延遲和較低的吞吐量,而且在發生節點故障時,恢複資料的時間也可能會更長
在選擇 Rook 中的副本存儲或糾删碼存儲時,需要考慮資料的重要性和可用性要求,以及存儲成本和系統性能等因素。如果資料的重要性較高,可用性要求較高,并且存儲成本較高,可以選擇副本存儲;如果資料的可用性要求較高,存儲成本較低,并且可以容忍較高的讀寫延遲和較低的吞吐量,可以選擇糾删碼存儲。在選擇存儲方案時,還需要考慮硬體資源和網絡帶寬等因素,以確定所選方案可以滿足系統性能和可用性要求。

實戰

  1. 建立CephBlockPool和StorageClass資源對象
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: replicapool
spec:
  failureDomain: host
  replicated:
    size: 3
    requireSafeReplicaSize: true
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rook-ceph-block
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
  pool: replicapool
  imageFormat: "2"
  imageFeatures: layering
  csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
  csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
  csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
  csi.storage.k8s.io/fstype: ext4
allowVolumeExpansion: true
reclaimPolicy: Delete
           

這是一個用于配置Rook與Ceph叢集互動的 Kubernetes StorageClass 的 YAML 檔案。 StorageClass 提供了一種抽象方式,允許應用程式請求動态卷(PVC),而不需要事先了解存儲資源的底層細節。

在這個 YAML 檔案中,有兩個 Kubernetes 對象:CephBlockPool 和 StorageClass。

CephBlockPool 是 Rook 中用于管理 Ceph 存儲叢集的塊存儲池的 Kubernetes 對象。這個特定的塊存儲池名為 replicapool,它使用主機故障域進行故障域分離,使用副本存儲政策,并将每個對象的副本數量設定為 3,要求所有副本都必須是安全的。每個 CephBlockPool 都對應一個特定的存儲後端,用于提供塊存儲服務。通過建立不同的 CephBlockPool,可以為不同的應用程式提供不同的存儲配置和性能要求。

StorageClass 對象指定了使用 Rook Ceph 提供的 CSI 驅動程式建立的存儲卷的預設設定。其中 provisioner 指定使用的 CSI 驅動程式名稱,pool 指定使用的 Ceph 塊存儲池名稱,imageFormat 指定建立塊裝置時要使用的映像格式,imageFeatures 指定要啟用的塊裝置特性,例如階層化,csi.storage.k8s.io/provisioner-secret-name,csi.storage.k8s.io/controller-expand-secret-name 和 csi.storage.k8s.io/node-stage-secret-name 分别指定用于身份驗證和授權的 Kubernetes 密鑰名稱,而 allowVolumeExpansion 和 reclaimPolicy 分别定義了動态卷是否允許擴容以及何時删除。

當使用rook搭建好叢集後,它已經将用于身份驗證和授權所需的 Kubernetes Secret 對象建立好了,使用下面指令可以檢視:

[root@k8s-a-master rbd]# kubectl get secret -n rook-ceph
NAME                                TYPE                 DATA   AGE
cluster-peer-token-rook-ceph        kubernetes.io/rook   2      22h
rook-ceph-admin-keyring             kubernetes.io/rook   1      22h
rook-ceph-config                    kubernetes.io/rook   2      22h
rook-ceph-crash-collector-keyring   kubernetes.io/rook   1      22h
rook-ceph-dashboard-password        kubernetes.io/rook   1      22h
rook-ceph-mgr-a-keyring             kubernetes.io/rook   1      22h
rook-ceph-mgr-b-keyring             kubernetes.io/rook   1      22h
rook-ceph-mon                       kubernetes.io/rook   4      22h
rook-ceph-mons-keyring              kubernetes.io/rook   1      22h
rook-csi-cephfs-node                kubernetes.io/rook   2      22h
rook-csi-cephfs-provisioner         kubernetes.io/rook   2      22h
rook-csi-rbd-node                   kubernetes.io/rook   2      22h
rook-csi-rbd-provisioner            kubernetes.io/rook   2      22h
           
  • provisioner-secret-name 用于 CSI 驅動程式和存儲卷建立器之間的身份驗證和授權。
  • controller-expand-secret-name 用于 CSI 驅動程式和存儲卷擴充控制器之間的身份驗證和授權。
  • node-stage-secret-name 用于 CSI 驅動程式和節點挂載器之間的身份驗證和授權。
  1. 開始建立
kubectl create -f storageclass.yaml 
           
  1. 建立後驗證
# 檢視 Rook CephBlockPool 的資源定義
[root@k8s-a-master rbd]# kubectl get crd | grep cephblockpools.ceph.rook.io
cephblockpools.ceph.rook.io                           2023-04-03T08:28:30Z

# 檢視存儲類
[root@k8s-a-master rbd]# kubectl get storageclass 
NAME              PROVISIONER                  RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
rook-ceph-block   rook-ceph.rbd.csi.ceph.com   Delete          Immediate           true                   18h
[root@k8s-a-master rbd]# 

# 檢視 Rook CephBlockPool 的清單
[root@k8s-a-master rbd]# kubectl get cephblockpool -n rook-ceph
NAME          PHASE
replicapool   Ready

# 檢視詳細資訊
kubectl describe cephblockpool replicapool -n rook-ceph
           

我們已經将Kubernetes使用了Rook Ceph作為存儲後端,并建立好了CephBlockPool和StorageClass,接着我們還需要建立一個PersistentVolumeClaim(PVC)對象來請求持久化存儲資源。PV将在PVC建立後自動建立。

在建立PVC時,Kubernetes将檢查可用的PV清單,尋找一個比對請求的存儲大小、通路模式和StorageClass的PV。如果找到一個可用的PV,則該PV将被綁定到PVC上,并成為PVC的一部分。如果沒有可用的PV,則Kubernetes将等待,直到有足夠的存儲資源可用為止。

在這個過程中,Kubernetes将使用先前建立的StorageClass中指定的CephBlockPool的名稱來确定要使用的Ceph存儲池。Kubernetes将使用這個資訊來自動建立一個對應的PV,該PV将在背景映射到Ceph存儲池中。在建立PVC時,PV将自動建立并綁定到PVC上,以提供所需的持久化存儲資源。

  1. 提前建立一個PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: rook-ceph-block
           

在這裡,PVC名稱為my-pvc,請求5GB的存儲空間,并将存儲類設定為rook-ceph-block。

  1. 建立一個應用pod
apiVersion: v1
kind: Pod
metadata:
  name: test-nginx-pod
spec:
  containers:
  - name: test-nginx-container
    image: nginx
    volumeMounts:
    - name: storage
      mountPath: /data
  volumes:
  - name: storage
    persistentVolumeClaim:
      claimName: my-pvc
           
  1. 驗證是否挂載成功
# 檢視定義的pvc
[root@k8s-a-master ~]# kubectl get pvc
NAME     STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
my-pvc   Bound    pvc-76d69972-2a95-44bc-953d-1028b4b69435   5Gi        RWO            rook-ceph-block   74s

# 看看pv有沒有自動建立
[root@k8s-a-master ~]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS      REASON   AGE
pvc-76d69972-2a95-44bc-953d-1028b4b69435   5Gi        RWO            Delete           Bound    default/my-pvc   rook-ceph-block            77s

# 進入pod檢視資料目錄
[root@k8s-a-master ~]# kubectl exec -it test-nginx-pod -- bash
root@test-nginx-pod:/# 
root@test-nginx-pod:/# df -h
Filesystem              Size  Used Avail Use% Mounted on
overlay                 250G  4.9G  246G   2% /
tmpfs                    64M     0   64M   0% /dev
tmpfs                   3.9G     0  3.9G   0% /sys/fs/cgroup
/dev/rbd0               4.9G   24K  4.9G   1% /data # 在這裡
/dev/mapper/centos-var  250G  4.9G  246G   2% /etc/hosts
shm                      64M     0   64M   0% /dev/shm
tmpfs                   7.7G   12K  7.7G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs                   3.9G     0  3.9G   0% /proc/acpi
tmpfs                   3.9G     0  3.9G   0% /proc/scsi
tmpfs                   3.9G     0  3.9G   0% /sys/firmware
           
  1. 解除安裝塊存儲
kubectl delete -f pod.yml
kubectl delete -f pvc.yml
kubectl delete -f storageclass.yaml # 這個yaml就是之前我們用于建立的,已經包含了CephBlockPool和StorageClass

# 或者也可以單獨執行删除指定的CephBlockPool和StorageClass,不過還是建議storageclass.yaml的方式
kubectl delete cephblockpools.ceph.rook.io replicapool -n rook-ceph
kubectl delete storageclass rook-ceph-block
           
  • kubectl delete -f pod.yml:這個指令将删除包含 Rook 塊存儲的 Pod。這将停止 Rook 塊存儲的所有執行個體和程序。
  • kubectl delete -f pvc.yml:這個指令将删除 PVC (Persistent Volume Claim) 對象,這個對象定義了要使用的持久化存儲資源。這将釋放 Rook 塊存儲占用的存儲空間。
  • kubectl delete cephblockpools.ceph.rook.io replicapool -n rook-ceph:這個指令将删除名為 replicapool 的 Rook 塊存儲池。塊存儲池是一個邏輯卷,可以在其中建立塊裝置。删除塊存儲池将確定不再建立新的塊裝置。
  • kubectl delete storageclass rook-ceph-block:這個指令将删除名為 rook-ceph-block 的 Rook 存儲類。存儲類指定了用于存儲資料的存儲類型和屬性。删除存儲類将確定不再建立新的 Rook 存儲卷。
需要注意的是,這4個指令需要按照指定的順序執行,以確定完全解除安裝 Rook 塊存儲。否則,可能會導緻未清理的資源或資料遺留在叢集中。

本文轉載于WX公衆号:不背鍋運維(喜歡的盆友關注我們):https://mp.weixin.qq.com/s/6PYW3yQvn1v0CRS7iOUHDA

繼續閱讀