在之前的章节中,我们介绍了Ceph集群的组件,一个最小的Ceph集群包括Mon、Mgr和Osd三个部分。为了更好地理解Ceph,我建议在进行部署时采取手动方式,这样方便我们深入了解Ceph的底层。今天我们将进行较长的章节讲解,希望您能耐心阅读完(个人建议可以动手实践一次,效果更佳)。因为Ceph官方文档中对该过程进行了过于简单的描述,许多细节都被隐藏了,然而这些细节对于理解Ceph概念至关重要。
在部署之前我们先介绍下Ceph的网络,Ceph集群是划分了两种网络(集群网络)Cluster Network、(公共网络)Public Network 。
Cluster Network: 就是Ceph 集群组件内部通信时使用的网络,也称为存储内网。如mon之间相互通信,osd向mon上报其状态信息,主osd向从osd 复制数据等内部操作。
Public Network: Ceph集群中用于客户端访问和管理的网络。它是集群与外部世界(客户端、管理员等)通信的主要通道。也称为存储外网。说简单点就是集群外部客户端访问集群内部时的网络。
总结:集群内部访问走Cluster Network ,集群外访问集群内时走Public Network,集群内外怎么区分了? 集群内部组件有 Mon Mgr OSD Mds 等这些内部组件自身通信就是走Cluster Network ,客户或者运维人员使用ceph命令与集群通信,此时走的就是Public Network 。
思考1 :OpenStack 将Ceph作为后端存储时,对Ceph的访问是走哪个网络了? 当我们上传镜像到Ceph存储池时走的是哪个网络了?
做过OpenStack运维的小伙伴们,一定少不了镜像制作和上传,如果后端存储是Ceph时,该网络的流量是怎么走了的呢?
#OpenStack 镜像上传命令如下: openstack image create --container-format bare --disk-format qcow2 \ --public --file /path/to/centos-image.qcow2 centos-image ### 参数说明 --container-format bare 表示容器格式是裸(bare)。 --disk-format qcow2 表示磁盘格式是qcow2。 --public 表示将镜像设置为公共镜像。 --file /path/to/centos-image.qcow2 指定CentOS镜像文件的路径。 centos-image 是你给镜像起的名称。
此时的流量是先是走了OpenStack的管理网,访问了Glance镜像服务,然后Glance作为客户端走Public 网络访问Ceph集群,将数据存储在后端Ceph集群中。(管理网一般是千兆网络,而Ceph 无论是Public 还是 Cluster 网络一般都是万兆及以上高速网络。)
window镜像动辄10GB的大小,上传一个镜像少则几分钟,多则1个小时,那镜像上传的过程可以发现,瓶颈是在OpenStack管理网上,如果我们传文件时不走OpenStack管理网,就能解决该问题。
openstack image create
命令创建一个空镜像并记录其uuid .此过程只是在第一步,创建空镜像时使用了OpenStack管理网,后面所有的操作都是走Public 网络。其效率提高了至少10倍。
思考2: Ceph两个网段是必须的吗?
测试环境中是可以将两个网络合并为一个网络,但是生产环境中是强烈不建议这样使用的。
此时我们是一个测试环境就简单规划为一个网络 192.168.200.0/24
一个Ceph集群至少需要一个Mon和少量OSD,部署一个Mon 需要提前先了解下如下几个概念
Unique Identifier: 集群唯一标识符,在集群中显示为fsid, (由于最初的ceph集群主要支持文件系统,所以最初fsid代表文件系统ID,现在ceph集群也支持了块存储和对象存储,但是这个名字确保留下来。文件存储是最先被规划的,相对对象存储和块存储,却是最后生产可用的。)
Cluster Name 集群名字,如果不指定默认为ceph,注意如果是多个ceph集群的环境需要指定。
当一个节点做为客户端要访问两个Ceph集群 cluster1 和 cluster2 时,需要在ceph 命令指定参数
ceph --cluster CLUSTER cluster name
Monitor Name: Mon名字,默认mon使用主机名为自Mon节点的名字,因此需要做好域名解析。
Monitor Map:启动初始monitor需要生成monitor map。monitor映射需要fsid,集群的名字以及一个主机名或IP地址。( 在生活中我们去一个陌生地方会先查地图(map),同理mon第一次初始化和查找同伴时也需要Mon Map)
Keyring :Ceph 认证密钥环,用于集群身份认证。Cephx认证的不仅有客户端用户(比如某客户端要想执行命令来操作集群,就要有登录Ceph的密钥),也有Ceph集群的服务器,这是一种特殊的用户类型MON/OSD/MDS。也就是说,Monitor、OSD、MDS都需要账号和密码来登录Ceph系统。因此这里的Keyring既有集群内组件的,也有用于管理的Keyring 。(这一点和K8s集群的认证很类似,都是采用双向认证)
了解上述这些是为了能看懂Ceph的配置文件,但是我们在部署时可以不写配置文件,但是在生产环境中强烈建议是手动编写配置文件
环境说明: 部署环境 vmware 虚拟机 虚拟机系统 CentOS Linux release 7.9.2009 (Core) 部署ceph版本: 14.2.22 nautilus (stable)
ip | 主机名 | 角色 | 磁盘 |
---|---|---|---|
192.168.200.11 | mon01 | mon mgr osd | sdb,sdc,sde,sdf |
1 修改主机名,添加hosts 文件解析 hostnamectl set-hostname mon01 echo "192.168.200.11 mon01" >> /etc/hosts 2 关闭防火墙和seliux systemctl stop firewalld setenforce 0 getenforce #Disabled 3 配置ceph 的yum 源,这里使用国内的aliyun的镜像站点 cat > /etc/yum.repos.d/ceph.repo <<EOF [ceph] name=ceph baseurl=https://mirrors.aliyun.com/ceph/rpm-nautilus/el7/x86_64/ gpgcheck=0 EOF 4 检查repo yum repolist 5 自身免密 ssh-keygen -t rsa #自己的管理IP ssh-copy-id mon01: 6 安装ceph 包和其依赖包 yum install -y snappy leveldb gdisk python-argparse gperftools-libs ceph
检查安装包
检查ceph客户端的版本
[root@mon01 ~]# ceph -v ceph version 14.2.22 (ca74598065096e6fcbd8433c8779a2be0c889351) nautilus (stable)
【注意】安装了ceph 的基础组件包之后,系统默认在/var/lib/ceph
目录下生成了一系列的目录如下
而且其属主和属组都是ceph用户。为什么强调这个,在很多利旧的环境中,在清理集群时清理目录要清理这些目录下的文件。如果不清理,或者清理不干净,在ceph多次部署时会产生各种问题,本人在生产环境中就遇见过多次。文件清理不彻底,文件权限不正确的问题。
这里提供一个生产环境中清理ceph集群的命令
#停止服务 systemctl stop ceph-osd.target systemctl stop ceph-mon.target systemctl stop ceph-mgr.target #删除文件 rm -f /var/lib/ceph/bootstrap-mds/ceph.keyring rm -f /var/lib/ceph/bootstrap-mgr/ceph.keyring rm -f /var/lib/ceph/bootstrap-osd/ceph.keyring rm-f /var/lib/ceph/bootstrap-rbd/ceph.keyring rm -f /var/lib/ceph/bootstrap-rbd-mirror/ceph.keyring rm -f /var/lib/ceph/bootstrap-rgw/ceph.keyring rm -rf /etc/ceph/* rm -fr /var/lib/ceph/mon/* rm -fr /var/lib/ceph/mgr/* rm -rf /etc/systemd/system/multi-user.target.wants/ceph-volume* rm -rf /etc/systemd/system/ceph-osd.target.wants/ceph-osd* 取消osd挂载 umount /var/lib/ceph/osd/* rm -rf /var/lib/ceph/osd/* rm -f /var/log/ceph/* #删除lv vg pv 分区信息 for i in `ls /dev/ | grep ceph-`; do j=/dev/$i/osd*; lvremove --force --force $j; done for i in $(vgdisplay |grep "VG Name"|awk -F' ' '{print $3}'); do vgremove -y $i; done for j in $(pvdisplay|grep 'PV Name'|awk '{print $3}'); do pvremove --force --force $j; done vgscan --cache pvscan --cache lvscan --cache
1 生成uuid 即集群的fsid,即集群的唯一标识符 [root@mon01 ~]# uuidgen 51be96b7-fb6b-4d68-8798-665278119188 2 安装完ceph组件包之后,已经生成了/etc/ceph目录 接下来我们补充下ceph.conf 的配置文件 cat > /etc/ceph/ceph.conf <<EOF fsid = 51be96b7-fb6b-4d68-8798-665278119188 mon_initial_members = mon01 mon_host = 192.168.200.11 public_network = 192.168.200.0/24 #cluster_network = 192.168.200.0/24 EOF
3、生成mon的私钥文件,进行身份验证
上文中提到集群内的组件访问也是需要认证的,Ceph 默认是使用Cephx 协议进行认证,此时分别给mon 和bootstrap-osd 和client.admin 来生成私钥文件
# mon key ceph-authtool --create-keyring /tmp/ceph.mon.keyring \ --gen-key -n mon. --cap mon 'allow *' #bootstarp-osd key ceph-authtool --create-keyring /var/lib/ceph/bootstrap-osd/ceph.keyring \ --gen-key -n client.bootstrap-osd --cap mon 'profile bootstrap-osd' \ --cap mgr 'allow r' #client.admin key ceph-authtool --create-keyring /etc/ceph/ceph.client.admin.keyring \ --gen-key -n client.admin --cap mon 'allow *' --cap osd 'allow *'\ --cap mds 'allow *' --cap mgr 'allow *'
cat /etc/ceph/ceph.client.admin.keyring
查看其结构也很容易理解,key 表示其私钥文件,caps mds = allow *
,表示对mds 拥有了所有的权限,其他同理。
[client.admin] key = AQCni2NlDuN7ERAAYr/aL5A5R0OJFeBkwmrBjQ== caps mds = "allow *" caps mgr = "allow *" caps mon = "allow *" caps osd = "allow *"
4、导入key到mon.keyring 文件中
将client.admin 和bootstrap-osd key,导入到mon的 keyring 文件中。并将keyring 文件复制到/etc/ceph/目录下
ceph-authtool /tmp/ceph.mon.keyring --import-keyring \ /etc/ceph/ceph.client.admin.keyring #将bootstap-osd的key 文件导入并复制到了 /var/lib/ceph/bootstrap-osd/ceph.keyring ceph-authtool /tmp/ceph.mon.keyring --import-keyring \ /var/lib/ceph/bootstrap-osd/ceph.keyring importing contents of /var/lib/ceph/bootstrap-osd/ceph.keyring into /tmp/ceph.mon.keyring
查看mon此时的keyring 文件,验证client.admin和client.bootstrap-osd keyring 已经导入
[root@mon01 ceph]# cat /tmp/ceph.mon.keyring [mon.] key = AQD8h2NlYzQWLRAA306ur5iOEjoHwarGx77FFg== caps mon = "allow *" [client.admin] key = AQCni2NlDuN7ERAAYr/aL5A5R0OJFeBkwmrBjQ== caps mds = "allow *" caps mgr = "allow *" caps mon = "allow *" caps osd = "allow *" [client.bootstrap-osd] key = AQCKi2NlASwkDxAAPPXUeSwX8nQJJcJao+bgCw== caps mgr = "allow r" caps mon = "profile bootstrap-osd"
5 修改权限为ceph
chown ceph:ceph /tmp/ceph.mon.keyring
6、创建monmap
#单节点mon环境 monmaptool --create --add {hostname} {ip-address} --fsid {uuid} /tmp/monmap monmaptool --create --add mon01 192.168.200.11 \ --fsid 51be96b7-fb6b-4d68-8798-665278119188 /tmp/monmap #多节点mon环境 monmaptool --create --add mon01 192.168.200.11 \ --add node2 192.168.200.12 --add node3 192.168.200.13 \ --fsid 51be96b7-fb6b-4d68-8798-665278119188 /tmp/monmap
6.1、什么是monmap? monmap是做什么用的?
Monitor Map: Ceph 集群中的 Monitors 负责维护集群的状态信息、监控数据等。monmap 包含了 Monitors 的信息,包括它们的主机名、IP地址以及集群的唯一标识(FSID)等。
启动 Monitors: 在 Ceph 集群的启动过程中,Monitors 首先需要从 monmap 中获取集群的初始信息。monmaptool 的这个命令就是为了生成一个初始化的 monmap 文件,以供 Monitors 使用。这个文件会在 Monitors 启动时被加载。
维护集群状态: 一旦 Monitors 启动,它们会使用 monmap 文件来维护集群的状态。Monitors 之间会相互通信,共享集群的状态信息。monmap 中包含的信息帮助 Monitors 确定其他 Monitor 节点的位置,从而进行集群管理和数据的一致性。
Monitor 选举: 当一个 Monitor 节点发生故障或新的 Monitor 节点加入集群时,集群需要进行 Monitor 的选举。monmap 包含的信息有助于集群中的 OSD(Object Storage Daemon)和客户端找到 Monitor 节点,并确保选举过程正确进行。
6.2 、怎么验证和查看当前集群的monmap ?
[root@mon01 tmp]# monmaptool --print /tmp/monmap monmaptool: monmap file monmap epoch 0 fsid 51be96b7-fb6b-4d68-8798-665278119188 #集群id last_changed 2023-11-27 03:23:10.956578 created 2023-11-27 03:23:10.956578 min_mon_release 0 (unknown) 0: v1:192.168.200.11:6789/0 mon.mon01 #mon节点信息
6.3 、写错了怎么覆盖写?
# --clobber 参数 将会覆盖写 monmaptool --create --add mon01 192.168.200.12 --fsid \ 91e36b46-8e6b-4ac6-8292-0a8ac8352907 /tmp/monmap --clobber
7 修改ceph 权限
chown -R ceph:ceph /tmp/{monmap,ceph.mon.keyring}
8 创建mon01 工作目录
#mkdir /var/lib/ceph/mon/{cluster-name}-{hostname} sudo -u ceph mkdir /var/lib/ceph/mon/ceph-mon01 #默认cluster-name 就是ceph
9 用monitor map和keyring填充monitor守护程序,生mon01的数据库文件
#sudo -u ceph ceph-mon [--cluster {cluster-name}] \ #--mkfs -i {hostname} --monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring sudo -u ceph ceph-mon --cluster ceph --mkfs -i mon01 \ --monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring
验证
[root@mon01 ceph-mon01]# cat keyring [mon.] key = AQD8h2NlYzQWLRAA306ur5iOEjoHwarGx77FFg== caps mon = "allow *" [root@mon01 ceph-mon01]# ls keyring kv_backend store.db [root@mon01 ceph-mon01]# pwd /var/lib/ceph/mon/ceph-mon01
【提示】mon 完成之后,即使key误删了,但admin keyring还在,可以使用ceph auth list
查看集群所有的keyring
完成第9步之后,在以systemd的方式拉起mon01的守护进场就算完成了mon的安装,但是在拉其服务之前,我们先介绍下两个概念,副本和纠删码
Ceph存储池在配置有两种分别是 副本池(Replicated Pool)和纠删码池(Erasure-coded Pool),这两种类型也很好理解,如果是副本池,其存放是以副本的方式存放的,每份副本其数据是完全一致的,相当于1份数据存多份来冗余。
纠删码池一般Ceph是采用前向纠错码(Forward Error Correction,FEC)
FEC代码将K个chunk(以下称为块)数据进行冗余校验处理,得到了N个块数据。这N个块数据既包含原数据,也包括校验数据。这样就能保证K个块中如果有数据丢失,可以通过N个块中包含的校验数据进行恢复。
具体地说,在N=K+M中,变量K是数据块即原始数量;变量M代表防止故障的冗余块的数量;变量N是在纠删码之后创建的块的总数。这种方法保证了Ceph可以访问所有原始数据,可以抵抗任意N–K个故障。例如,在K=10、N=16的配置中,Ceph会将6个冗余块添加到10个基本块K中。在M=N–K(即16–10=6)的配置中,Ceph会将16个块分布在16个OSD中,这样即使6个OSD掉线,也可以从10个块中重建原始文件,以确保不会丢失数据,提高容错能力。
简单来说就是 K个数据块 + M 个冗余块 = N个总块
【思考3】生产环境中我们是选副本还是纠删码呢?
性能优先选副本池,容量优先选纠删码。(本质上纠删码就是牺牲部分计算性能换存储容量)
在实际的生产环境中我们的数据都是存储在磁盘中的,磁盘对应OSD
,磁盘是服务器上的一个组件,服务器对应Host
而服务器是在机架中存放的,一个机柜RACK
中有N个机架,而机柜是属于一个房间的ROOM
,一个大型的数据中心(Data Center
)可能有N个房间,而每个房间可能在同一个地区,也可以在不同地区。
对应其关系为 1Data Center = NRoom = NRACK = NHost = NOSD
总结:Ceph集群中有很多硬件设备,从上到下可能涉及某些逻辑单元,类似数据中心→设备所在机房→机架→行→服务器→OSD盘等的关系。那么,如何描述这些逻辑单元的关系、
Bucket 专门用于描述以上提到的这些逻辑单元属性,以便将来对这些属性按树状结构进行组织。(Bucket逻辑视图
)(选取规则RuleSet
) (磁盘设备Device
) 组成了ceph的Crush Map
.(混个脸熟即可,将来会重点介绍)
在ceph中使用 ceph osd tree
就可用查看该视图
上述视图中有3个机架 rack1 rack2 rack3 ,每个rack下分别由一个mon主机和两个osd 设备。
无论是副本池还是纠删码池,数据都是存储在osd中的,如果是副本池,默认3副本,那这3个osd,怎么选取了?
我们先不讨论Crush算法选取OSD的问题,我们就考虑一个问题,数据冗余问题。如果我们3个OSD 都在同一个节点,该节点down了,则我们数据都访问不了了,则我们称我们数据的冗余级别是OSD的级别的(Host下一级)。
如果我们的选取的3个OSD都在不同节点上(Host),但是这三个节点都在同一个机柜中(Rack),如果机柜断电了,则我们的数据无法访问了,我们称我们的冗余级别是节点级别(Host),同理3个OSD 在不同的机柜中,但在同一个ROOM中,我们称我们数据的冗余级别是RACK级别。
那我们怎么定义数据冗余级别了,osd_crush_chooseleaf_type 参数则可以定义,其值是一个数字 代表了类型。
ceph osd crush dump #可以查看到其type # types type 0 osd type 1 host type 2 chassis #一般不使用,服务器机框。 type 3 rack type 4 row type 5 pdu type 6 pod type 7 room type 8 datacenter
数字0 代表了其故障域是osd级别,虽然这种说法不严谨但是方便理解。后面我们在学习了Crush算法第二步之后就知道其OSD 是如何通过Bucket 和RuleSet 来选取OSD的,这里我们简单理解就是将3副本分散到3个osd就能满足要求。如果是数字1 表示其冗余级别是host 级别。要在不同的节点上,其他同理。
此实验环境中我们osd都在同一个节点上因此我们将其参数值设置为0
最后ceph.conf 文件修该为如下
最后我们启动mon服务
systemctl daemon-reload systemctl start ceph-mon@mon01 systemctl enable ceph-mon@mon01 查看集群状态 [root@mon01 ceph-mon01]# ceph -s cluster: id: 51be96b7-fb6b-4d68-8798-665278119188 health: HEALTH_WARN mon is allowing insecure global_id reclaim 1 monitors have not enabled msgr2 services: mon: 1 daemons, quorum mon01 (age 6s) mgr: no daemons active osd: 0 osds: 0 up, 0 in data: pools: 0 pools, 0 pgs objects: 0 objects, 0 B usage: 0 B used, 0 B / 0 B avail pgs:
如果ceph状态显示如上图,恭喜你,表示第一个mon已经成功部署了.
mon组件可以说是Ceph最重要的组件了,因此本章节对其每一步操作都做了详细说明,剩下的mgr osd的部署则会简单很多,由于篇幅所限,我们将在下一章节继续。