当前位置:   article > 正文

Kubernetes 使用 ceph-csi 消费 RBD 作为持久化存储_csi-rbdplugin-provisioner

csi-rbdplugin-provisioner

本文详细介绍了如何在 Kubernetes 集群中部署 ceph-csi(v3.1.0),并使用 RBD 作为持久化存储。
需要的环境参考下图:
在这里插入图片描述

本文使用的环境版本信息:

Kubernetes 版本:

  1. $ kubectl get node
  2. NAME STATUS ROLES AGE VERSION
  3. sealos01 Ready master 23d v1.18.8
  4. sealos02 Ready master 23d v1.18.8
  5. sealos03 Ready master 23d v1.18.8

Ceph 版本:

  1. $ ceph version
  2. ceph version 14.2.11 (f7fdb2f52131f54b891a2ec99d8205561242cdaf) nautilus (stable)

以下是详细部署过程:

1. 新建 Ceph Pool

创建一个新的 ceph 存储池(pool) 给 Kubernetes 使用:

  1. $ ceph osd pool create kubernetes
  2. pool ' kubernetes' created

查看所有的 pool:

  1. $ ceph osd lspools
  2. 1 cephfs_data
  3. 2 cephfs_metadata
  4. 3 .rgw.root
  5. 4 default.rgw.control
  6. 5 default.rgw.meta
  7. 6 default.rgw.log
  8. 7 kubernetes

2. 新建用户

为 Kubernetes 和 ceph-csi 单独创建一个新用户:

  1. $ ceph auth get-or-create client.kubernetes mon 'profile rbd' osd 'profile rbd pool=kubernetes' mgr 'profile rbd pool=kubernetes'
  2. [client.kubernetes]
  3. key = AQBnz11fclrxChAAf8TFw8ROzmr8ifftAHQbTw==

后面的配置需要用到这里的 key,如果忘了可以通过以下命令来获取:

  1. $ ceph auth get client.kubernetes
  2. exported keyring for client.kubernetes
  3. [client.kubernetes]
  4. key = AQBnz11fclrxChAAf8TFw8ROzmr8ifftAHQbTw==
  5. caps mgr = "profile rbd pool=kubernetes"
  6. caps mon = "profile rbd"
  7. caps osd = "profile rbd pool=kubernetes"

3. 部署 ceph-csi

拉取 ceph-csi 的最新 release 分支(v3.1.0):

$ git clone --depth 1 --branch v3.1.0 https://gitclone.com/github.com/ceph/ceph-csi
  • 这里使用gitclone来加速拉取。

修改 Configmap

获取 Ceph 集群的信息:

  1. $ ceph mon dump
  2. dumped monmap epoch 1
  3. epoch 1
  4. fsid 154c3d17-a9af-4f52-b83e-0fddd5db6e1b
  5. last_changed 2020-09-12 16:16:53.774567
  6. created 2020-09-12 16:16:53.774567
  7. min_mon_release 14 (nautilus)
  8. 0: [v2:172.16.1.21:3300/0,v1:172.16.1.21:6789/0] mon.sealos01
  9. 1: [v2:172.16.1.22:3300/0,v1:172.16.1.22:6789/0] mon.sealos02
  10. 2: [v2:172.16.1.23:3300/0,v1:172.16.1.23:6789/0] mon.sealos03

这里需要用到两个信息:

  • fsid : 这个是 Ceph 的集群 ID。
  • 监控节点信息。目前 ceph-csi 只支持 v1 版本的协议,所以监控节点那里我们只能用 v1 的那个 IP
    和端口号(例如,172.16.1.21:6789)。

进入 ceph-csi 的 deploy/rbd/kubernetes 目录:

  1. $ cd deploy/rbd/kubernetes
  2. $ ls -l ./
  3. total 36
  4. -rw-r--r-- 1 root root 100 Sep 14 04:49 csi-config-map.yaml
  5. -rw-r--r-- 1 root root 1686 Sep 14 04:49 csi-nodeplugin-psp.yaml
  6. -rw-r--r-- 1 root root 858 Sep 14 04:49 csi-nodeplugin-rbac.yaml
  7. -rw-r--r-- 1 root root 1312 Sep 14 04:49 csi-provisioner-psp.yaml
  8. -rw-r--r-- 1 root root 3105 Sep 14 04:49 csi-provisioner-rbac.yaml
  9. -rw-r--r-- 1 root root 5497 Sep 14 04:49 csi-rbdplugin-provisioner.yaml
  10. -rw-r--r-- 1 root root 5852 Sep 14 04:49 csi-rbdplugin.yaml

将以上获取的信息写入 csi-config-map.yaml:

  1. ---
  2. apiVersion: v1
  3. kind: ConfigMap
  4. data:
  5. config.json: |-
  6. [
  7. {
  8. "clusterID": "154c3d17-a9af-4f52-b83e-0fddd5db6e1b",
  9. "monitors": [
  10. "172.16.1.21:6789",
  11. "172.15.1.22:6789",
  12. "172.16.1.23:6789"
  13. ]
  14. }
  15. ]
  16. metadata:
  17. name: ceph-csi-config

创建一个新的 namespace 专门用来部署 ceph-csi:

$ kubectl create ns ceph-csi

将此 Configmap 存储到 Kubernetes 集群中:

$ kubectl -n ceph-csi apply -f csi-config-map.yaml

新建 Secret

使用创建的 kubernetes 用户 ID 和 cephx 密钥生成 Secret:

  1. cat <<EOF > csi-rbd-secret.yaml
  2. apiVersion: v1
  3. kind: Secret
  4. metadata:
  5. name: csi-rbd-secret
  6. namespace: ceph-csi
  7. stringData:
  8. userID: kubernetes
  9. userKey: AQBnz11fclrxChAAf8TFw8ROzmr8ifftAHQbTw==
  10. EOF

部署 Secret:

$ kubectl apply -f csi-rbd-secret.yaml

RBAC 授权

将所有配置清单中的 namespace 改成 ceph-csi:

  1. $ sed -i "s/namespace: default/namespace: ceph-csi/g" $(grep -rl "namespace: default" ./)
  2. $ sed -i -e "/^kind: ServiceAccount/{N;N;a\ namespace: ceph-csi # 输入到这里的时候需要按一下回车键,在下一行继续输入
  3. }" $(egrep -rl "^kind: ServiceAccount" ./)

创建必须的 ServiceAccount 和 RBAC ClusterRole/ClusterRoleBinding 资源对象:

  1. $ kubectl create -f csi-provisioner-rbac.yaml
  2. $ kubectl create -f csi-nodeplugin-rbac.yaml

创建 PodSecurityPolicy:

  1. $ kubectl create -f csi-provisioner-psp.yaml
  2. $ kubectl create -f csi-nodeplugin-psp.yaml

部署 CSI sidecar

将 csi-rbdplugin-provisioner.yaml 和 csi-rbdplugin.yaml 中的 kms 部分配置注释掉:
在这里插入图片描述
在这里插入图片描述

部署 csi-rbdplugin-provisioner:

$ kubectl -n ceph-csi create -f csi-rbdplugin-provisioner.yaml

这里面包含了 6 个 Sidecar 容器,包括 external-provisioner、external-attacher、csi-resizer 和 csi-rbdplugin。

部署 RBD CSI driver

最后部署 RBD CSI Driver:

$ kubectl -n ceph-csi create -f csi-rbdplugin.yaml

Pod 中包含两个容器:CSI node-driver-registrar 和 CSI RBD driver。

创建 Storageclass

  1. $ cat <<EOF > storageclass.yaml
  2. ---
  3. apiVersion: storage.k8s.io/v1
  4. kind: StorageClass
  5. metadata:
  6. name: csi-rbd-sc
  7. provisioner: rbd.csi.ceph.com
  8. parameters:
  9. clusterID: 154c3d17-a9af-4f52-b83e-0fddd5db6e1b
  10. pool: kubernetes
  11. imageFeatures: layering
  12. csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
  13. csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi
  14. csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
  15. csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi
  16. csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
  17. csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi
  18. csi.storage.k8s.io/fstype: ext4
  19. reclaimPolicy: Delete
  20. allowVolumeExpansion: true
  21. mountOptions:
  22. - discard
  23. EOF
  • 这里的 clusterID 对应之前步骤中的 fsid。
  • imageFeatures 用来确定创建的 image 特征,如果不指定,就会使用 RBD 内核中的特征列表,但 Linux不一定支持所有特征,所以这里需要限制一下。

3. 试用 ceph-csi

Kubernetes 通过 PersistentVolume 子系统为用户和管理员提供了一组 API,将存储如何供应的细节从其如何被使用中抽象出来,其中 PV(PersistentVolume) 是实际的存储,PVC(PersistentVolumeClaim) 是用户对存储的请求。

下面通过官方仓库的示例来演示如何使用 ceph-csi。

先进入 ceph-csi 项目的 example/rbd 目录,然后直接创建 PVC:

$ kubectl apply -f pvc.yaml

查看 PVC 和申请成功的 PV:

  1. $ kubectl get pvc
  2. NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
  3. rbd-pvc Bound pvc-44b89f0e-4efd-4396-9316-10a04d289d7f 1Gi RWO csi-rbd-sc 8m21s
  4. $ kubectl get pv
  5. NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
  6. pvc-44b89f0e-4efd-4396-9316-10a04d289d7f 1Gi RWO Delete Bound default/rbd-pvc csi-rbd-sc 8m18s

再创建示例 Pod:

$ kubectl apply -f pod.yaml

进入 Pod 里面测试读写数据:

  1. $ kubectl exec -it csi-rbd-demo-pod bash
  2. root@csi-rbd-demo-pod:/# cd /var/lib/www/
  3. root@csi-rbd-demo-pod:/var/lib/www# ls -l
  4. total 4
  5. drwxrwxrwx 3 root root 4096 Sep 14 09:09 html
  6. root@csi-rbd-demo-pod:/var/lib/www# echo "https://fuckcloudnative.io" > sealos.txt
  7. root@csi-rbd-demo-pod:/var/lib/www# cat sealos.txt
  8. https://fuckcloudnative.io

列出 kubernetes pool 中的 rbd images:

  1. $ rbd ls -p kubernetes
  2. csi-vol-d9d011f9-f669-11ea-a3fa-ee21730897e6

查看该 image 的特征:

  1. $ rbd info csi-vol-d9d011f9-f669-11ea-a3fa-ee21730897e6 -p kubernetes
  2. rbd image 'csi-vol-d9d011f9-f669-11ea-a3fa-ee21730897e6':
  3. size 1 GiB in 256 objects
  4. order 22 (4 MiB objects)
  5. snapshot_count: 0
  6. id: 8da46585bb36
  7. block_name_prefix: rbd_data.8da46585bb36
  8. format: 2
  9. features: layering
  10. op_features:
  11. flags:
  12. create_timestamp: Mon Sep 14 09:08:27 2020
  13. access_timestamp: Mon Sep 14 09:08:27 2020
  14. modify_timestamp: Mon Sep 14 09:08:27 2020

可以看到对 image 的特征限制生效了,这里只有 layering。
实际上这个 image 会被挂载到 node 中作为一个块设备,到运行 Pod 的 Node 上可以通过 rbd 命令查看映射信息:

  1. $ rbd showmapped
  2. id pool namespace image snap device
  3. 0 kubernetes csi-vol-d9d011f9-f669-11ea-a3fa-ee21730897e6 - /dev/rbd0

在 node 上查看挂载信息:

  1. $ lsblk -l|grep rbd
  2. rbd0 252:32 0 1G 0 disk /var/lib/kubelet/pods/15179e76-e06e-4c0e-91dc-e6ecf2119f4b/volumes/kubernetes.io~csi/pvc-44b89f0e-4efd-4396-9316-10a04d289d7f/mount

在 容器中查看挂载信息:

  1. $ kubectl exec -it csi-rbd-demo-pod bash
  2. root@csi-rbd-demo-pod:/# lsblk -l|grep rbd
  3. rbd0 252:32 0 1G 0 disk /var/lib/www/html

一切正常!

4. 试用卷快照功能

要想使用卷快照(Volume Snapshot)功能,首先需要在 apiserver 的 --feature-gates 参数中加上 VolumeSnapshotDataSource=true,不过从 Kubernetes 1.17 开始这个特性已经默认开启了,不需要再手动添加。

卷快照功能不是 Kubernetes 的核心 API,它是通过 CRD 来实现的,同时还需要一个卷快照控制器(需要单独部署)。卷快照控制器和 CRD 独立于特定的 CSI 驱动,无论 Kubernetes 集群中部署了多少 CSI 驱动,每个集群都必须只运行一个卷快照控制器和一组卷快照 CRD。

卷快照 CRD 和控制器都在这个项目中:https://github.com/kubernetes-csi/external-snapshotter。
将 external-snapshotter

项目拉取到本地:

$ git clone --depth 1 https://github.com/kubernetes-csi/external-snapshotter

创建卷快照 CRD:

  1. $ cd external-snapshotter
  2. $ kubectl create -f client/config/crd

将卷快照部署清单中的 namespace 改成 kube-system:

$ sed -i "s/namespace: default/namespace: kube-system/g" $(grep -rl "namespace: default" deploy/kubernetes/snapshot-controller)

部署卷快照控制器:

$ kubectl create -f deploy/kubernetes/snapshot-controller

现在可以回到 ceph-csi 的 examples/rbd 目录试用卷快照功能了。先将 snapshotclass.yaml 中的 clusterID 改成 Ceph 的集群 ID:

  1. ---
  2. apiVersion: snapshot.storage.k8s.io/v1beta1
  3. kind: VolumeSnapshotClass
  4. metadata:
  5. name: csi-rbdplugin-snapclass
  6. driver: rbd.csi.ceph.com
  7. parameters:
  8. # String representing a Ceph cluster to provision storage from.
  9. # Should be unique across all Ceph clusters in use for provisioning,
  10. # cannot be greater than 36 bytes in length, and should remain immutable for
  11. # the lifetime of the StorageClass in use.
  12. # Ensure to create an entry in the configmap named ceph-csi-config, based on
  13. # csi-config-map-sample.yaml, to accompany the string chosen to
  14. # represent the Ceph cluster in clusterID below
  15. clusterID: 154c3d17-a9af-4f52-b83e-0fddd5db6e1b
  16. # Prefix to use for naming RBD snapshots.
  17. # If omitted, defaults to "csi-snap-".
  18. # snapshotNamePrefix: "foo-bar-"
  19. csi.storage.k8s.io/snapshotter-secret-name: csi-rbd-secret
  20. csi.storage.k8s.io/snapshotter-secret-namespace: ceph-csi
  21. deletionPolicy: Delete

然后创建 snapshot class:

$ kubectl create -f snapshotclass.yaml

查看 snapshot class 是否创建成功:

  1. $ kubectl get volumesnapshotclass
  2. NAME DRIVER DELETIONPOLICY AGE
  3. csi-rbdplugin-snapclass rbd.csi.ceph.com Delete 2s

还记得上一节创建的 rbd-pvc 吗,现在我们可以直接创建该 PVC 的快照来进行备份了,卷快照的配置清单如下:

  1. ---
  2. apiVersion: snapshot.storage.k8s.io/v1beta1
  3. kind: VolumeSnapshot
  4. metadata:
  5. name: rbd-pvc-snapshot
  6. spec:
  7. volumeSnapshotClassName: csi-rbdplugin-snapclass
  8. source:
  9. persistentVolumeClaimName: rbd-pvc

通过该配置清单创建 PVC rbd-pvc 的快照:

$ kubectl create -f snapshot.yaml

验证快照是否创建成功:

  1. $ kubectl get volumesnapshot
  2. NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS SNAPSHOTCONTENT CREATIONTIME AGE
  3. rbd-pvc-snapshot false rbd-pvc csi-rbdplugin-snapclass snapcontent-9011a05f-dc34-480d-854e-814b0b1b245d 16s

在 Ceph 集群中可以看到新创建快照的 image 名称:

  1. $ rbd ls -p kubernetes
  2. csi-snap-4da66c2e-f707-11ea-ba22-aaa4b0fc674d
  3. csi-vol-d9d011f9-f669-11ea-a3fa-ee21730897e6

查看新创建的快照信息:

  1. $ rbd snap ls csi-snap-4da66c2e-f707-11ea-ba22-aaa4b0fc674d -p kubernetes
  2. SNAPID NAME SIZE PROTECTED TIMESTAMP
  3. 9 csi-snap-4da66c2e-f707-11ea-ba22-aaa4b0fc674d 1 GiB Tue Sep 15 03:55:34 2020

快照也是 pool 中的一个 image,所以可以用常规的命令查看快照的详细信息:

  1. $ rbd info csi-snap-4da66c2e-f707-11ea-ba22-aaa4b0fc674d -p kubernetes
  2. rbd image 'csi-snap-4da66c2e-f707-11ea-ba22-aaa4b0fc674d':
  3. size 1 GiB in 256 objects
  4. order 22 (4 MiB objects)
  5. snapshot_count: 1
  6. id: 66cdcd259693
  7. block_name_prefix: rbd_data.66cdcd259693
  8. format: 2
  9. features: layering, deep-flatten, operations
  10. op_features: clone-child
  11. flags:
  12. create_timestamp: Tue Sep 15 03:55:33 2020
  13. access_timestamp: Tue Sep 15 03:55:33 2020
  14. modify_timestamp: Tue Sep 15 03:55:33 2020
  15. parent: kubernetes/csi-vol-d9d011f9-f669-11ea-a3fa-ee21730897e6@33d02b70-bc82-4def-afd3-b7a40567a8db
  16. overlap: 1 GiB

如果想恢复快照,可以直接基于快照创建 PVC,配置清单内容如下:

  1. ---
  2. apiVersion: v1
  3. kind: PersistentVolumeClaim
  4. metadata:
  5. name: rbd-pvc-restore
  6. spec:
  7. storageClassName: csi-rbd-sc
  8. dataSource:
  9. name: rbd-pvc-snapshot
  10. kind: VolumeSnapshot
  11. apiGroup: snapshot.storage.k8s.io
  12. accessModes:
  13. - ReadWriteOnce
  14. resources:
  15. requests:
  16. storage: 1Gi

创建 PVC:

$ kubectl apply -f pvc-restore.yaml

查看 PVC 和申请成功的 PV:

  1. $ kubectl get pvc
  2. NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
  3. rbd-pvc Bound pvc-44b89f0e-4efd-4396-9316-10a04d289d7f 1Gi RWO csi-rbd-sc 22h
  4. rbd-pvc-restore Bound pvc-e0ef4f6a-03dc-4c3b-a9c2-db03baf35ab0 1Gi RWO csi-rbd-sc 2m45s
  5. $ kubectl get pv
  6. pvc-44b89f0e-4efd-4396-9316-10a04d289d7f 1Gi RWO Delete Bound default/rbd-pvc csi-rbd-sc 22h
  7. pvc-e0ef4f6a-03dc-4c3b-a9c2-db03baf35ab0 1Gi RWO Delete Bound default/rbd-pvc-restore csi-rbd-sc 2m14s

可以看到 PV 申请成功了,对应到 Ceph 里面就多了一个 RBD image:

  1. $ rbd ls -p kubernetes
  2. csi-snap-4da66c2e-f707-11ea-ba22-aaa4b0fc674d
  3. csi-vol-d9d011f9-f669-11ea-a3fa-ee21730897e6
  4. csi-vol-e32d46bd-f722-11ea-a3fa-ee21730897e6

创建一个新 Pod,使用该 PV 作为持久化存储:

$ kubectl apply -f pod-restore.yaml

待 Pod 运行成功后,到运行 Pod 的 Node 上可以通过 rbd 命令查看映射信息:

  1. $ rbd showmapped
  2. id pool namespace image snap device
  3. 0 kubernetes csi-vol-d9d011f9-f669-11ea-a3fa-ee21730897e6 - /dev/rbd0
  4. 1 kubernetes csi-vol-e32d46bd-f722-11ea-a3fa-ee21730897e6 - /dev/rbd1

5. 清理

结束对示例应用的体验后,就可以使用下面的命令来完成应用的删除和清理了:

  1. $ kubectl delete -f pod-restore.yaml
  2. $ kubectl delete -f pvc-restore.yaml
  3. $ kubectl delete -f snapshot.yaml
  4. $ kubectl delete -f snapshotclass.yaml
  5. $ kubectl delete -f pod.yaml
  6. $ kubectl delete -f pvc.yaml

最后

欢迎大家关注和转发文章,也欢迎大家关注我的公众号:程序员麦冬,回复“007”领取200页的Java核心面试资料整理,每天都会分享java相关技术文章或行业资讯

转载至https://blog.csdn.net/weixin_49114080/article/details/109204488

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/832938
推荐阅读
相关标签
  

闽ICP备14008679号