Ceph-集群内分布式存储解决方案及基于Docker的部署

Ceph

很早以前在玩集群的时候就折腾过分布式存储服务来作为跨节点的数据共享和可靠存储,以前尝试过GlusterFS,但是由于读写速度实在是太低,就放弃了。见基于GlusterFS设计 Docker集群存储方案

后来的解决方案是所有机器都挂载了 NAS ,读写速度是提升上去了,但是存在着几个问题:

  • 一是 NAS 的单点故障问题,虽然 NAS 做过了RAID,但是故障率还是很高。(后来的事实证明,NAS 确实坏了,集群所有数据都丢了)
  • 另一个是安全性问题,NFS 协议没有验证机制(或者说需要设置),存在安全性问题。
  • 规模受限,当集群规模扩大到数十个节点时,读写性能就很受影响了。

最近接触到了 Ceph,看上去比 GlusterFS 要好很多,正好最近在实验室折腾集群docker化,搞大数据的人连抗单点故障的分布式存储都没有着实是让人嘲笑的。(以及前几天因为服务器故障,组里的服务全挂了,好几天都没恢复,实验室官网也访问不了,想想还是蛮尴尬的。。。)

关于 Ceph 的介绍,就不搬运了,最近事多,也没怎么深入研究。

部署

使用了 5 个节点,系统都是刚装上的 CentOS Linux release 7.6.1810 (Core)

Ceph 集群中必需的有:

  • 若干个 monitor (mon) 服务
  • 若干个 数据存储 (osd) 服务
  • 独立的管理 (mgr) 服务,在 luminous 之后是必须的

此外,还有可选的 mds 服务等,这个服务仅在需要使用 CephFS 时才需要

因为倾向于所有东西都放在docekr里,尽量保持宿主机的纯净,所以不太想安装ceph的客户端,而且发现 centos 默认就能挂载ceph类型的文件系统,所以采用了 CephFS 方式,需要部署一个 mds 服务。

以下是每个节点上规划的 Ceph 服务。

hostname ip roles
node1 192.168.1.1 mon, mgr, mds
node2 192.168.1.2 mon, osd
node3 192.168.1.3 osd
node4 192.168.1.4 mon, osd
node5 192.168.1.5 osd

node1 节点作为 master 节点,重要的服务都放在这上面,为了保持该节点的性能,该节点不部署 osd 服务。(实际上,该服务器在真实集群中作为跳板机使用,且做了RAID,磁盘空间较小)

理论上还是存在单点故障,不过考虑到node1作为跳板机,它挂了,所有节点都连不上,而且即便是挂了,数据也不会丢失,在可以接受的范围之内。

以下服务都是基于 docker 部署的,可以说,本次部署 Ceph 不需要宿主机安装任何额外的软件。

部署 monitor

首先在 node1 上执行以下命令启动一个 mon 服务 (需要提前新建 /data/ceph/etc 以及 /data/ceph/lib 目录)

1
2
3
4
5
6
7
8
9
10
docker run \
--name=ceph_mon \
-d \
--net=host \
--restart=always \
-v /data/ceph/etc:/etc/ceph \
-v /data/ceph/lib:/var/lib/ceph \
-e MON_IP=192.168.1.1 \
-e CEPH_PUBLIC_NETWORK=192.168.1.1/24 \
ceph/daemon mon

待服务启动一段时间后(自动初始化,容器启动后数十秒即可)。

使用命令 docker exec -it ceph_mon ceph -s 查看当前集群情况,如果一切正常,会看到结果里显示 HEALTH_OK

ceph setup OK

使用命令 docker rm -f ceph_mon 停止mon服务,然后编辑 /data/eph/etc/ceph.conf 并在最后添加两行:

1
2
osd max object name len = 256
osd max object namespace len = 64

具体原因稍后再说。

使用命令 scp -r /data/ceph 192.168.1.x:/data 将生成的配置文件复制到其他节点上(/data目录都预先建立好了)。

然后在 node1、node2、node4 上执行上述命令,启动另外两个 mon 服务(需要修改其中的 MON_IP 为各自节点的IP)。

再次执行命令 docker exec -it ceph_mon ceph -s 查看当前集群情况,多刷新几次,这次应该就能看到集群内有了三个mon服务。

部署 mgr

在 node1 节点上执行命令,启动一个 mgr 服务

1
2
3
4
5
6
7
8
docker run \
--name ceph_mgr \
-d \
--net=host \
--restart=always \
-v /data/ceph/etc:/etc/ceph \
-v /data/ceph/lib:/var/lib/ceph/ \
ceph/daemon mgr

部署 mds

在 node1 节点上执行命令,启动一个 mds 服务

1
2
3
4
5
6
7
8
9
docker run \
--name ceph_mds \
-d \
--net=host \
--restart=always \
-v /data/ceph/lib:/var/lib/ceph/ \
-v /data/ceph/etc:/etc/ceph \
-e CEPHFS_CREATE=1 \
ceph/daemon mds

部署 osd 服务

在 node2、node3、node4、node5 上执行以下命令,来启动四个 osd 服务。

1
2
3
4
5
6
7
8
docker run \
--name=ceph_osd \
-d \
--net=host \
--restart=always \
-v /data/ceph/etc:/etc/ceph \
-v /data/ceph/lib:/var/lib/ceph/ \
ceph/daemon osd_directory

说明

关于 osd 的挂载问题,一般教程里是选择一整块硬盘,然后全部交由osd管理,不过之前安装系统的时候没有考虑到这些,两块盘已经分配好了,没法重新分配。此外其他的服务也会占用磁盘空间,CephFS 目前没有经过长时间使用,不敢保证可用性。一开始考虑使用 dd 创建一个文件然后 loset 模拟成一块硬盘来交由 osd 管理,但是某次重启机器后发现该osd无法恢复,所以放弃了这种做法,直接采用外挂现有目录的形式。虽然在性能上有一定的损失,但是不失为一种当前环境下的可选方案。

再来说一下前面提到的修改配置文件的问题,同样是因为硬盘已经分配好了,采用了 ext4 的文件格式,而 osd 默认是 XFS 格式,ext4存储xattrs的大小有限制,使得OSD信息不能安全的保存。所以需要修改配置文件来解决。

当然了,最好的情况下还是选择一整块硬盘,然后交由 osd 自己去管理,这种情况下启动 osd 服务的命令就不是上述所说的了。

客户端挂载

docker exec -it ceph_mon ceph auth ls 然后找到一行 client.admin ,后面有一个secret串,记录下来,假设是 SECRET。

在集群中的每个节点上执行命令 mount -t ceph 192.168.1.1:6789:/ /mnt -o name=admin,secret=SECRET 就可以将CephFS 挂载到 /mnt 目录了,不需要安装任何额外的软件支持。

对比 GlusterFS

相对 GlusterFS 来说,CephFS 在速度上可能要更快一些,而且ceph的挂载有权限验证机制,即便是暴露在复杂网络环境下也能一定程度上保护数据安全。

而且,GlusterFS 在创建卷上略显复杂,需要自行指定所有的分布节点,而ceph只需要设置副本数目即可,不用关心数据分布的问题。

ceph 的osd节点加入非常简单,只需要复制配置文件然后启动osd服务即可,ceph集群会自动将数据重新分发,在遇到部分osd当机的时候仍然能保证服务,以及使用 ceph osd out N 命令来下线3号osd,并开始重新均衡数据。

ceph setup rebalancing

本文所涉及的所有命令脚本可以在 newnius/scripts 找到。

参考

Ceph介绍及原理架构分享

Ceph osd启动报错osd init failed (36) File name too long

在Docker里运行Ceph

Bootstrap your Ceph cluster in Docker

使用Docker快速部署Ceph集群

使用 Docker 部署 Ceph 集群

ceph存储 ceph-deploy部署挂载目录的osd

ceph/ceph

ceph/daemon

Adding/Removing OSDs

Ceph: properly remove an OSD

losetup命令

Ceph运维告诉你分布式存储的那些“坑”

ceph中对象读写的顺序性及并发性保证