每天5分钟复习OpenStack(十一)Ceph部署

发布时间 2023-11-27 23:21:55作者: ALEX_li88

在之前的章节中,我们介绍了Ceph集群的组件,一个最小的Ceph集群包括Mon、Mgr和Osd三个部分。为了更好地理解Ceph,我建议在进行部署时采取手动方式,这样方便我们深入了解Ceph的底层。今天我们将进行较长的章节讲解,希望您能耐心阅读完(个人建议可以动手实践一次,效果更佳)。因为Ceph官方文档中对该过程进行了过于简单的描述,许多细节都被隐藏了,然而这些细节对于理解Ceph概念至关重要。

1、网络规划

在部署之前我们先介绍下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

思考1OpenStackCeph作为后端存储时,对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管理网,就能解决该问题。

  1. openstack image create 命令创建一个空镜像并记录其uuid .
  2. 通过rbd命令直接将镜像文件传到Ceph后端,然后给其做快照,并打上快照保护的标记.
  3. 设置glance镜像location url 为rbd的路径。

此过程只是在第一步,创建空镜像时使用了OpenStack管理网,后面所有的操作都是走Public 网络。其效率提高了至少10倍。

思考2: Ceph两个网段是必须的吗?

测试环境中是可以将两个网络合并为一个网络,但是生产环境中是强烈不建议这样使用的。

  1. 从隔离角度来说会造成Public 网络流量过高时,影响集群的稳定性,
  2. 从安全的角度,Public网络是非安全网络,而Cluster网络是安全的网络。

此时我们是一个测试环境就简单规划为一个网络 192.168.200.0/24

2、 Mon 部署

一个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的配置文件,但是我们在部署时可以不写配置文件,但是在生产环境中强烈建议是手动编写配置文件

2.1 MON 部署前置任务

环境说明:
部署环境 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

2.2 Mon 部署

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
  • fsid 对应集群id
  • mon_initial_member 对应初始化的mon主机名,
  • mon_host 对应其IP地址
  • public_network 和cluster_network 则对应了之前介绍的公共网络和集群网络。

3、生成mon的私钥文件,进行身份验证

上文中提到集群内的组件访问也是需要认证的,Ceph 默认是使用Cephx 协议进行认证,此时分别给monbootstrap-osdclient.admin 来生成私钥文件

  • mon mon 私钥文件,用于mon进行身份认证
  • bootstrap-osd 是当你添加一个新的 OSD 到 Ceph 集群时,需要向集群引导这个 OSD。这个引导过程涉及到向 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的安装,但是在拉其服务之前,我们先介绍下两个概念,副本和纠删码

3、副本 or 纠删码

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】生产环境中我们是选副本还是纠删码呢?

性能优先选副本池,容量优先选纠删码。(本质上纠删码就是牺牲部分计算性能换存储容量)

4 故障域也称为冗余级别

在实际的生产环境中我们的数据都是存储在磁盘中的,磁盘对应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的部署则会简单很多,由于篇幅所限,我们将在下一章节继续。