写在前面
近日ceph集群有台节点中毒了!-.-!病毒严重影响节点性能和系统稳定,所以我们需要对节点重装
该节点基本信息:
ceph-deploy节点
主mon
主mgr
38个8T的HDD磁盘,共38个osd
我们的想法是,节点重装后,原来的所有ceph服务都可以恢复起来,尤其是osd,如果要重建的话,38个8T的盘需要的恢复的数据太多了
开始
重装前的备份
重装系统前,我们需要对必要的相关文件进行备份,需要备份的内容有
1、/etc/ceph
目录
2、ceph-deploy相关keyring,后续要用到ceph-deploy
3、/etc/systemd/system/multi-user.target.wants
中所有ceph-volume@lvm-
开头的链接文件,别问,问就是后面有用
4、/etc/systemd/system
中所有ceph相关的service文件(如果有)
5、/var/lib/ceph/mon/ceph-$hostname
目录下的全部内容,注意先stop了mon进程再打包
6、其他自定义服务及相关脚本,例如中断绑定、sysctl.conf等
重装后的恢复
首先是前期的准备
1、配置hostname、hosts文件、系统基础设置例如firewall、selinux等
2、配置网络、yum源,安装系统必要的软件包和ceph,注意ceph版本要与原来一致
3、其他系统配置恢复,例如中断绑定、sysctl.conf等
然后是集群的恢复
第一,我们将备份的service文件全部拷贝回去,注意路径与原来保持一致
第二,将备份的/etc/ceph/
目录,拷回去
第三,准备尝试启动osd
osd的启动使用的方法是启动之前备份的ceph-volume@lvm-
开头的那些服务
for x in `cat ~/volume_service.txt`;do systemctl start $x;done
稍等片刻,查看集群状态,发现osd成功起来
[root@xxx ~]# ceph -s
cluster:
id: 67f60ac1-70c3-4b96-a124-f5a077b473a8
health: HEALTH_WARN
noout,noscrub,nodeep-scrub flag(s) set
1 osds down
204473/587486091 objects misplaced (0.035%)
Degraded data redundancy: 3201856/587486091 objects degraded (0.545%), 122 pgs degraded, 129 pgs undersized
1/3 mons down, quorum server05,server06
services:
mon: 3 daemons, quorum server05,server06, out of quorum: server04
mgr: server03(active)
osd: 189 osds: 188 up, 189 in; 19 remapped pgs
flags noout,noscrub,nodeep-scrub
rgw: 2 daemons active
data:
pools: 7 pools, 5664 pgs
objects: 117.5 M objects, 57 TiB
usage: 129 TiB used, 1.2 PiB 1.3 PiB avail
pgs: 3201856/587486091 objects degraded (0.545%)
204473/587486091 objects misplaced (0.035%)
5517 active+clean
121 active+undersized+degraded
11 active+remapped+backfilling
7 active+clean+remapped
7 active+undersized
1 active+undersized+degraded+remapped+backfilling
io:
client: 0 B/s rd, 0 B/s wr, 0 op/s rd, 0 op/s wr
recovery: 1 B/s, 0 objects/s
mon的恢复
节点原来是主mon和主mgr,重装后,可以看到集群只剩下一个mgr了,mgr重建很容易,使用ceph-deploy mgr add
就可以加上并正常运行起来
mon的恢复比较麻烦一些
首先,使用ceph-deploy mon add
的方式在节点上创建一个全新的mon,但是新建的mon会有问题,不能直接加入到集群,提示错误为
cephx server client.admin: unexpected key: req.key=b41539c7a52299ea expected_key=7e5a790e3f705cab
看起来是key认证有问题,但是通过对比,key是没问题的
解决办法是,将该节点的mon先stop,然后将之前备份的mon目录,拷贝到新建的mon对应目录下覆盖,目录通常为/var/lib/ceph/mon/ceph-$hostname/
完成替换后,启动mon,就可以了
osd恢复原理解析
首先,我们可以快速恢复osd的依据是:osd需要的全部信息都保存在osd磁盘上
新版本的ceph,默认在lvm上创建osd,osd创建过程中,ceph-volume会将osd相关的信息,存放在osd的磁盘上,具体位置是磁盘lvm的lv_tags中,具体存了什么呢?
[root@xxx ~]# lvs -o lv_tags|head -n5
LV Tags
ceph.block_device=/dev/ceph-01491655-4024-4129-9fa0-230f7ed3ede5/osd-block-f0459426-2f75-403d-a654-df1f748c78e3,
ceph.block_uuid=ANmX2Y-uiAN-Ndhf-0Zqw-hdTq-3PxF-CaBruU,ceph.cephx_lockbox_secret=,
ceph.cluster_fsid=67f60ac1-70c3-4b96-a124-f5a077b473a8,
ceph.cluster_name=ceph,
ceph.crush_device_class=None,
ceph.encrypted=0,
ceph.osd_fsid=f0459426-2f75-403d-a654-df1f748c78e3,
ceph.osd_id=99,
ceph.type=block,ceph.vdo=0
可以看到,osd所需要的全部信息都在上面,也就是不管重装多少次系统,只要磁盘不坏,lvm信息还在,就可以知道这个盘对应的集群信息和osd信息
基于此,我们得知osd在重装后是可以直接拉起的,可是,如果有非常多的磁盘例如本例中38个盘,系统怎么知道启动某个osd进程时去读哪个盘呢?也就是,例如我们用systemctl start ceph-osd@99.service
来启动这个osd,但是系统怎么知道它对应哪个盘呢?因此这里我们不能直接使用systemctl来拉起osd,因为一方面systemctl并不知道osd.99对应哪块盘,另一方面systemctl无法帮我们处理osd启动前一些必要的操作,例如挂载osd目录到tmpfs
因此我们需要用ceph-volume来拉起osd,这涉及到ceph-volume的机制,ceph-volume是一个服务,它提供了osd的创建、挂载等一系列重要的功能,我们把ceph安装的时候会安装上这个服务,这个服务负责帮我们在系统启动的时候,自动激活、挂载osd并启动osd
重装系统前我们备份了一个关键的东西,就是/etc/systemd/system/multi-user.target.wants
下以ceph-volume@lvm-
开头的所有链接,例如
lrwxrwxrwx. 1 root root 44 7月 4 17:13 ceph-volume@lvm-92-31b3ffde-8637-4c34-a6a1-904b50ecc0ff.service -> usr/lib/systemd/system/ceph-volume@.service
这些链接文件的命名规则为ceph-volume@lvm-OSDID-OSDUUID,而@
后面的值将会作为参数,传递给实际的service服务中
也就是启动ceph-volume服务时,会传入lvm-OSDID-OSDUUID
这个参数,由于OSDUUID与lvm卷是对应的,系统可以通过lvm卷号找到对应的物理磁盘,所以ceph-volume服务就得到了osd的id和其lvm磁盘的对应关系了
这里我们再看下ceph-volume是怎么启动osd的,首先看ceph-volume@.service
内容
ExecStart=/bin/sh -c 'timeout $CEPH_VOLUME_TIMEOUT /usr/sbin/ceph-volume-systemd %i'
参数进来后,又传递给了ceph-volume-systemd
,在它的main
中可以看到它执行了命令
process.run(command, terminal_logging=False)
命令格式为['ceph-volume', 'lvm', 'trigger', 'OSDID-OSDUUID']
,最终会执行到active
db_device_path = get_osd_device_path(osd_lv, lvs, 'db', dmcrypt_secret=dmcrypt_secret)
wal_device_path = get_osd_device_path(osd_lv, lvs, 'wal', dmcrypt_secret=dmcrypt_secret)
这里就比较清晰了,ceph-volume通过传入的参数,通过get_osd_device_path
定位到lvs并取出其中的内容,这样就得到了osd所需的全部信息,就可以实现osd的启动了




