1. 什么是Ceph
Ceph是一种开源的分布式的存储系统,可用于为云平台提供Ceph对象存储,为云平台提供Ceph块设备服务。Ceph可用于部署Ceph文件系统,所有Ceph存储集群部署都从设置每个Ceph节点开始,然后设置网络。
Ceph具有高扩展性、高性能、高可靠性等优点,同时提供块存储服务(rbd)、对象存储服务(rgw)以及文件系统存储服务(cephfs)。Ceph在存储的时候,充分利用存储节点的计算能力,在存储每一个数据时,都会通过计算得出该数据的位置,尽量分布均衡。
一个Ceph存储集群需要以下条件:至少一个Ceph Monitor和至少一个CephManager,以及至少与存储在Ceph集群上的对象副本一样多的Ceph OSD(例如,如果给定对象的三个副本存储在Ceph集群上,那么该Ceph集群中必须至少存在三个OSD)。
Ceph的官方网站:https://ceph.io/
Ceph元数据服务器是运行Ceph文件系统客户端所必需的。
- Monitors:Ceph Monitor(ceph-mon)维护集群状态图,包括监视器图、管理器图、OSD图、MDS图和CRUSH图。这些映射是Ceph守护进程相互协调所需的关键集群状态。监视器还负责管理守护进程和客户端之间的身份验证。通常至少需要三个监视器才能实现冗余和高可用性。
- Managers:Ceph管理器守护进程(ceph-mgr)负责跟踪运行时指标和Ceph集群的当前状态,包括存储利用率、当前性能指标和系统负载。Ceph Manager守护进程还托管基于Python的模块来管理和公开Ceph集群信息,包括基于Web的Ceph Dashboard和REST API。高可用性通常至少需要两个管理器。
- Ceph OSDs:一个对象存储守护进程(Ceph OSD,ceph-osd)存储数据,处理数据复制,恢复,重新平衡,并通过检查其他Ceph OSD守护进程的心跳向Ceph Monitors和Managers提供一些监控信息。通常至少需要三个Ceph OSD才能实现冗余和高可用性。
- MDS:Ceph元数据服务器(MDS,ceph-mds)代表Ceph文件系统存储元数据(即,Ceph块设备和Ceph对象存储不使用MDS)。Ceph元数据服务器允许POSIX文件系统用户执行基本命令(如ls、find等),而不会给Ceph存储集群带来巨大负担。
注意:为每个Monitor配备一个Ceph Manager是最佳做法,但这不是必需的。
Ceph将数据作为对象存储在逻辑存储池中。使用CRUSH算法,Ceph计算出哪个归置组(PG)应该包含该对象,以及那个OSD应该存储该归置组。CRUSH算法使Ceph存储集群能够动态扩展、重新平衡和恢复。
2. Ceph架构
Ceph使用RADOS提供对象存储,通过librados封装库提供多种存储方式的文件和对象转换。外层通过RGW(Object,有原生的API,而且也兼容Swift和S3的API,适合单客户端使用)、RBD(Block,支持精简配置、快照、克隆,适合多客户端,有目录结构)、CephFS(File,Posix接口,支持快照,没有目录结构不能直接打开)将数据写入存储。
高性能
- 摒弃了传统的集中式存储元数据寻址的方案,采用CRUSH算法,数据分布均衡,并行度高。
- 考虑了容灾域的隔离,能够实现各类负载的副本放置规则,例如跨机房、机架感知等。
- 能够支持上千个存储节点的规模,支持TB到PB级的数据。
高可扩展性
- 去中心化。
- 扩展灵活。
- 随着节点增加而线性增长。
特性丰富
- 支持三种存储接口:块存储、文件存储、对象存储。
- 支持自定义接口,支持多种语言驱动。
2.1 Ceph核心概念
① RADOS
全程Reliable Autonomic Distributed Object Store,即可靠的、自动化的分布式对象存储系统。RADOS是Ceph集群的精华,用户实现数据分配、Failover等集群操作。
② Librados
Rados提供库,因为RADOS是协议,很难直接访问,因此,上层的RBD、RGW和CephFS都是通过librados访问,目前提供PHP、Ruby、Java、Python、C和C++支持。
③ Crush
Crush算法是Ceph的两大创新之一,通过Crush算法的寻址操作,Ceph得以摒弃传统的集中式存储元数据寻址方案。而Crush算法在一致性哈希基础上很好的考虑了容灾域的隔离,使得Ceph能够实现各类负载的副本规则,例如,跨机房、机架感知等。同时,Crush算法有相当强大的扩展性,理论上可以支持数千个存储节点,这为Ceph在大规模云环境中的应用提供了先天的便利。
④ Pool
Pool是存储对象的逻辑分区,它规定了数据冗余的类型和对应的副本分布策略,支持两种类型:副本(replicated)和纠删码(Erasure Code)。
⑤ PG
PG(placement group)是一个放置策略组,他是对象的集合,该集合里的所有对象都具有相同的放置策略,简单来说,就是相同PG内的对象都会放到相同的硬盘上,PG是ceph的逻辑概念,服务端数据均衡和恢复的最小粒度就是PG,一个 PG包含多个OSD。引入PG这一层其实是为了更好的分配数据和定位数据。
⑤ Object
简单来说,块存储读写快,不利于共享,文件存储读写慢,利于共享。能否弄一个读写快,利于共享的出来,于是就有了对象存储。最底层的存储单元,包含元数据和原始数据。
2.2 Ceph核心组件
① OSD
OSD是负责物理存储的进程,一般配置成和磁盘一一对应,一块磁盘启动一个OSD进程。主要功能是存储数据、复制数据、平衡数据、恢复数据,以及与其它OSD间进行心跳检查,负责响应客户端请求返回具体数据的进程等。
Pool、PG和OSD的关系:
- 一个Pool里有很多PG;
- 一个PG里包含一堆对象,一个对象只能属于一个PG;
- PG有主从之分,一个PG分布在不同的OSD上(针对三副本类型)。
② Monitor
一个Ceph集群需要多个Monitor组成的小集群,它们通过Paxos同步数据,用来保存OSD的元数据。负责监视整个Ceph集群运行的Map视图(如OSD Map、Monitor Map、PG Map和CRUSH Map),维护集群的健康状态,维护展示集群状态的各种图表,管理集群客户端认证与授权。
③ MDS
MDS全程Ceph Metadata Server,是CephFS服务依赖的元数据服务。负责保存文件系统的元数据,管理目录结构。对象存储和块设备不需要元数据服务。
④ Mgr
Ceph官方开发了ceph-mgr,主要目标实现ceph集群的管理,为外界提供统一的入口。例如cephmetrics、zabbix、calamari、prometheus等。
⑤ RGW
RGW全称RADOS gateway,是Ceph对外提供的对象存储服务,接口与S3和Swift兼容。
⑥ Admin
Ceph常用管理接口通常都是命令行工具,如rados、ceph、rbd等命令,另外Ceph还有一个专用的管理节点,在此节点上部署专门的管理工具来实现近乎集群的一些管理工作,如集群部署,集群组件管理等。
2.3 Ceph三种存储类型
① 块存储(RBD)
优点:
- 通过Raid与LVM等手段,对数据提供了保护;
- 多块廉价的硬盘组合起来,提高容量;
- 多块磁盘组合出来的逻辑盘,提升读写效率。
缺点:
- 采用SAN架构组网时,光纤交换机,造价成本高;
- 主机之间无法共享数据。
使用场景:
- docker容器、虚拟机磁盘存储分配;
- 日志存储;
- 文件存储。
② 文件存储(CephFS)
优点:
- 造价低,随便一台机器就可以了;
- 方便文件共享。
缺点:
- 读写速率低;
- 传输速率慢。
使用场景:
- 日志存储;
- FTP、NFS;
- 其它有目录结构的文件存储。
③ 对象存储(Object)(适合更新变动较少的数据)
优点:
- 具备块存储的读写高速;
- 具备文件存储的共享等特性。
使用场景:
- 图片存储;
- 视频存储。
3. k8s使用Ceph存储
3.1 pod使用RBD作为持久数据卷
RBD支持ReadWriteOnce,ReadOnlyMany两种模式。
① 配置rbd-provisionner
我的k8s集群如下:
首先在k8s集群中安装rbd-provisioner,github仓库:https://github.com/kubernetes-retired/external-storage.git
[root@k8s-master Ceph]# git clone https://github.com/kubernetes-retired/external-storage.git
[root@k8s-master Ceph]# ll
总用量 4
drwxr-xr-x 17 root root 4096 6月 13 14:54 external-storage
[root@k8s-master Ceph]# cd external-storage/
[root@k8s-master external-storage]# cd ceph/rbd/deploy/
[root@k8s-master deploy]# NAMESPACE=kube-system
[root@k8s-master deploy]# sed -r -i "s/namespace: [^ ]+/namespace: $NAMESPACE/g" ./rbac/clusterrolebinding.yaml ./rbac/rolebinding.yaml
[root@k8s-master deploy]# kubectl -n $NAMESPACE apply -f ./rbac
clusterrole.rbac.authorization.k8s.io/rbd-provisioner created
clusterrolebinding.rbac.authorization.k8s.io/rbd-provisioner created
deployment.apps/rbd-provisioner created
role.rbac.authorization.k8s.io/rbd-provisioner created
rolebinding.rbac.authorization.k8s.io/rbd-provisioner created
serviceaccount/rbd-provisioner created
部署完成后,检查rbd-provisioner deployment,确保已经正常部署: