天天看点

开源云原生存储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

继续阅读