Rook-Ceph 分布式存储

概述

Ceph 引入了一个新的 RBD 协议,也就是 Ceph 块设备(Ceph Block Device)。RBD 为客户端提供了可靠、分布式、高性能的块存储。RBD 块呈带状分布在多个 Ceph 对象之上,而这些对象本身又分布在整个 Ceph 存储集群中,因此能够保证数据的可靠性以及性能。RBD 已经被 Linux 内核支持,换句话说,RBD 驱动程序在过去的几年里已经很好地跟 Linux 内核集成。几乎所有的 Linux 操作系统发行版都支持 RBD。除了可靠性和性能之外,RBD 也支持其他的企业级特性,例如完整和增量式快照,精简的配置,写时复制(copy-on-write)式克隆,以及其他特性。RBD 还支持全内存式缓存,这可以大大提高它的性能。

Rook 是一种开源的云原生存储编排工具,提供了为云原生环境而生的平台框架级复杂存储解决方案。Ceph operator 在 2018 年 12 月的 Rook v0.9 版本中得到了稳定的支持,用户可以基于 Rook 实现面向 Ceph 存储的安装、运维管理,并提供了优秀的云原生存储使用体验。

安装部署

利用 Rook 安装部署 Ceph 集群仅需要使用简单的 kubectl 命令,安装开始之前,需要关注以下前提条件。

前提条件

  • 已部署Kubernetes集群,版本为 v1.16 或更高版本。

  • 集群最少拥有3个节点用来部署 ceph 存储集群。

  • 建议的最低内核版本为 5.4.13 。如果内核版本低于 5.4.13则需要升级内核。

  • 存储集群的服务器之间需要进行同步时间,官方要求0.05秒,并且做定时任务。

  • 安装lvm包

    • CentOS

      1. sudo yum install -y lvm2
    • Ubuntu

      1. sudo apt-get install -y lvm2
  • 存储满足以下选项之一:

    • 原始设备(无分区或格式化文件系统)
    • 原始分区(无格式化的文件系统)

如果磁盘之前已经使用过,需要进行清理,使用以下脚本进行清理

  1. #!/usr/bin/env bash
  2. DISK="/dev/vdc" #按需修改自己的盘符信息
  3. # Zap the disk to a fresh, usable state (zap-all is important, b/c MBR has to be clean)
  4. # You will have to run this step for all disks.
  5. sgdisk --zap-all $DISK
  6. # Clean hdds with dd
  7. dd if=/dev/zero of="$DISK" bs=1M count=100 oflag=direct,dsync
  8. # Clean disks such as ssd with blkdiscard instead of dd
  9. blkdiscard $DISK
  10. # These steps only have to be run once on each node
  11. # If rook sets up osds using ceph-volume, teardown leaves some devices mapped that lock the disks.
  12. ls /dev/mapper/ceph-* | xargs -I% -- dmsetup remove %
  13. # ceph-volume setup can leave ceph-<UUID> directories in /dev and /dev/mapper (unnecessary clutter)
  14. rm -rf /dev/ceph-*
  15. rm -rf /dev/mapper/ceph--*
  16. # Inform the OS of partition table changes
  17. partprobe $DISK

部署 Rook-Ceph

部署 Rook Operator

  1. git clone -b release-1.8 https://github.com/goodrain/rook.git && cd rook/deploy/examples/
  2. kubectl create -f crds.yaml -f common.yaml -f operator.yaml

为Running则Operator部署成功

  1. $ kubectl -n rook-ceph get pod
  2. NAME READY STATUS RESTARTS AGE
  3. rook-ceph-operator-b89545b4f-j64vk 1/1 Running 0 4m20s

创建Ceph集群

{kube-node1,kube-node2,kube-node3} 此处应替换为当前集群节点的 node 名称。

  • 给节点打标签

为运行ceph-mon的节点打上:ceph-mon=enabled

  1. kubectl label nodes {kube-node1,kube-node2,kube-node3} ceph-mon=enabled

为运行ceph-osd的节点,也就是存储节点,打上:ceph-osd=enabled

  1. kubectl label nodes {kube-node1,kube-node2,kube-node3} ceph-osd=enabled

为运行ceph-mgr的节点,打上:ceph-mgr=enabled

ceph-mgr最多只能运行2个

  1. kubectl label nodes {kube-node1,kube-node2} ceph-mgr=enabled
  • 创建集群

创建前修改 storage.node字段中的节点名称及对应盘符

  1. kubectl create -f cluster.yaml

验证Ceph集群

通过命令行查看以下pod启动,表示成功:

  1. kubectl get po -n rook-ceph

Rook-Ceph 分布式存储 - 图1

安装工具箱,其中包含了 Ceph 集群管理所需要的命令行工具:

  1. $ kubectl create -f toolbox.yaml
  2. $ kubectl get po -l app=rook-ceph-tools -n rook-ceph
  3. NAME READY STATUS RESTARTS AGE
  4. rook-ceph-tools-76876d788b-qtm4j 1/1 Running 0 77s

使用如下命令确定 Ceph 集群状态:

  1. $ kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash
  2. $ ceph status
  3. cluster:
  4. id: 8bb6bbd4-ec90-4707-85d7-903551d08991
  5. health: HEALTH_OK #出现该字样则集群正常
  6. services:
  7. mon: 3 daemons, quorum a,b,c (age 77s)
  8. mgr: b(active, since 27s), standbys: a
  9. osd: 6 osds: 6 up (since 37s), 6 in (since 56s)
  10. data:
  11. pools: 1 pools, 1 pgs
  12. objects: 0 objects, 0 B
  13. usage: 31 MiB used, 750 GiB / 750 GiB avail #磁盘总容量,确认是否与实际容量相同
  14. pgs: 1 active+clean

提供存储

Rook-ceph提供了三种类型的存储,三种存储类型在 Rainbond (版本要求不低于v5.7.0-release)中均可以对接使用。:

  • Block:创建由 Pod (RWO) 使用的块存储。Rainbond 平台中的有状态类型服务组件,可以在添加存储时选择 rook-ceph-block 申请并挂载块存储。
  • 共享文件系统:创建一个跨多个 Pod 共享的文件系统 (RWX)。安装 Rainbond 时可按照后文中的方式进行对接。Rainbond 平台中的服务组件在添加存储时选择默认的共享存储,即可对接 cephfs 共享文件系统。
  • Object:创建一个可以在 Kubernetes 集群内部或外部访问的对象存储。该存储类型可以对接 Rainbond 的对象存储设置,为云端备份恢复等功能提供支持。

创建共享存储

为运行 mds 的节点添加标签:role=mds-node,通常为 Ceph 的三个节点

  1. kubectl label nodes {kube-node1,kube-node2,kube-node3} role=mds-node
  1. $ kubectl create -f filesystem.yaml
  2. $ kubectl -n rook-ceph get pod -l app=rook-ceph-mds
  3. NAME READY STATUS RESTARTS AGE
  4. rook-ceph-mds-sharedfs-a-785c845496-2hcsz 1/1 Running 0 17s
  5. rook-ceph-mds-sharedfs-b-87df7847-5rvx9 1/1 Running 0 16s

在 Rook 开始供应存储之前,需要根据文件系统创建一个 StorageClass。这是 Kubernetes 与 CSI 驱动程序互操作以创建持久卷所必需的。

  1. $ kubectl create -f storageclass-sharedfs.yaml
  2. $ kubectl get sc
  3. NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
  4. rook-cephfs rook-ceph.cephfs.csi.ceph.com Delete Immediate false 72m

创建块存储

  1. kubectl create -f storageclass-block.yaml
  2. $ kubectl get storageclass rook-ceph-block
  3. NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
  4. rook-ceph-block rook-ceph.rbd.csi.ceph.com Delete Immediate true 79m

获取到 storageclass 后已创建成功,在平台上有状态组件可选择块存储进行使用。

创建对象存储

添加标签

  1. # 添加节点标签
  2. kubectl label nodes {kube-node1,kube-node2,kube-node3} rgw-node=enabled
  3. # Create the object store
  4. kubectl create -f object.yaml
  5. # To confirm the object store is configured, wait for the rgw pod to start
  6. kubectl -n rook-ceph get pod -l app=rook-ceph-rgw

创建 StorageClass

  1. cat > storageclass-bucket-delete.yaml <<EOF
  2. apiVersion: storage.k8s.io/v1
  3. kind: StorageClass
  4. metadata:
  5. name: rook-ceph-bucket
  6. provisioner: rook-ceph.ceph.rook.io/bucket
  7. reclaimPolicy: Delete
  8. parameters:
  9. objectStoreName: my-store
  10. objectStoreNamespace: rook-ceph
  11. EOF
  1. $ kubectl create -f storageclass-bucket-delete.yaml

创建 Bucket Claim

  1. cat > object-bucket-claim-delete.yaml <<EOF
  2. apiVersion: objectbucket.io/v1alpha1
  3. kind: ObjectBucketClaim
  4. metadata:
  5. name: ceph-bucket
  6. namespace: rook-ceph
  7. spec:
  8. generateBucketName: ceph-bkt
  9. storageClassName: rook-ceph-bucket
  10. EOF
  1. $ kubectl create -f object-bucket-claim-delete.yaml

创建完成后,下面来验证。

  1. $ kubectl get svc rook-ceph-rgw-my-store -n rook-ceph
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. rook-ceph-rgw-my-store ClusterIP 10.43.4.250 <none> 80/TCP 3h32m
  4. # 出现以下返回即证明bucket创建完成
  5. $ curl 10.43.4.250
  6. <?xml version="1.0" encoding="UTF-8"?><ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Owner><ID>anonymous</ID><DisplayName></DisplayName></Owner><Buckets></Buckets></ListAllMyBucketsResult>
  1. # 获取连接信息
  2. $ kubectl -n rook-ceph get cm ceph-bucket -o jsonpath='{.data.BUCKET_HOST}'
  3. rook-ceph-rgw-my-store.rook-ceph.svc
  4. $ kubectl -n rook-ceph get secret ceph-bucket -o jsonpath='{.data.AWS_ACCESS_KEY_ID}' | base64 --decode
  5. LV9A2S7F6A8SS3NPD9Z0
  6. $ kubectl -n rook-ceph get secret ceph-bucket -o jsonpath='{.data.AWS_SECRET_ACCESS_KEY}' | base64 --decode
  7. hzuHLEjtPvaX0N4hLIJBRzP4erjMdHsuHMqeyUuW
  8. # 获取bucket name
  9. $ kubectl get ObjectBucketClaim -n rook-ceph ceph-bucket -o yaml|grep "bucketName: ceph-bkt"
  10. bucketName: ceph-bkt-6c317bdb-ce51-444e-9d96-40903b3c24cf
  1. # 进入tools容器验证
  2. $ kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash
  3. export AWS_HOST=10.43.4.250
  4. export AWS_ENDPOINT=10.43.4.250:80
  5. export AWS_ACCESS_KEY_ID=LV9A2S7F6A8SS3NPD9Z0
  6. export AWS_SECRET_ACCESS_KEY=hzuHLEjtPvaX0N4hLIJBRzP4erjMdHsuHMqeyUuW
  7. # 将其写入credentials文件
  8. cat > ~/.aws/credentials << EOF
  9. [default]
  10. aws_access_key_id = ${AWS_ACCESS_KEY_ID}
  11. aws_secret_access_key = ${AWS_SECRET_ACCESS_KEY}
  12. EOF

PUT 或 GET 对象

上传文件到新创建的bucket

  1. echo "Hello Rook" > /tmp/rookObj
  2. s5cmd --endpoint-url http://$AWS_ENDPOINT cp /tmp/rookObj s3://ceph-bkt-6c317bdb-ce51-444e-9d96-40903b3c24cf

从bucket下载并验证文件

  1. $ s5cmd --endpoint-url http://$AWS_ENDPOINT cp s3://ceph-bkt-6c317bdb-ce51-444e-9d96-40903b3c24cf/rookObj /tmp/rookObj-download
  2. $ cat /tmp/rookObj-downloadcat
  3. Hello Rook

供集群外部访问

将该svc地址在平台以第三方组件形式运行并打开对外访问策略,即可通过对外访问策略进行访问

  1. $ kubectl -n rook-ceph get service rook-ceph-rgw-my-store
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. rook-ceph-rgw-my-store ClusterIP 10.43.4.250 <none> 80/TCP 3h40m

访问dashboard

修改 Ceph 集群配置,禁用 dashboard 内置 ssl:

  1. $ kubectl -n rook-ceph edit cephcluster -n rook-ceph rook-ceph
  2. # 修改 ssl 为 false
  3. spec:
  4. dashboard:
  5. enabled: true
  6. ssl: false
  7. # 重启 operator 使配置生效
  8. $ kubectl delete po -l app=rook-ceph-operator -n rook-ceph

获取svc,在平台上使用第三方组件的形式代理

  1. $ kubectl -n rook-ceph get service rook-ceph-mgr-dashboard
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. rook-ceph-mgr-dashboard ClusterIP 10.43.168.11 <none> 7000/TCP 118m

访问到仪表板后,默认用户为admin,在服务器执行以下命令获取密码:

  1. kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{['data']['password']}" | base64 --decode && echo