一个ceph战争故事

2021-04-10 15:39:46

这一切都始于大爆炸!我们几乎在Proxmox / Ceph集群上丢失了33个磁盘;这是我们如何恢复它们的故事。

在2020年底,我们最终有一个很好的优秀维护窗口,用于在客户进行系统升级。在此维护窗口中,涉及重新启动服务器系统,所涉及的Ceph集群意外地进入了临界状态。在傍晚计划是几个小时的清单工作,结果是一个紧急情况;让我们称之为噩梦(不仅是因为它包括夜间的大部分)。由于我们从验尸和RCA学到了一些东西,因此值得与他人分享。但首先是首先,让我们退后一步,澄清我们必须处理的东西。

升级的一部分包括3个Debian服务器(我们在这里调用Server1,Server2和Server3),在ProxMox V5 + Debian / Selret中运行,每个Ceph OSD(总共65.45TB),所谓的Proxmox Hyper-融合了Ceph集群。

首先,在更新Ceph光亮V12.2.13之前,我们将升级ProxMox V5 / STRACK系统,以便更新CEPH发光V12.2.13到最新的v14.2版本,由ProxMox V6 / Buster支持。 ProxMox升级包括从v2到v3的更新corosync。作为此升级的一部分,我们必须应用一些配置更改,例如调整Ring0 + Ring1地址设置,并将Mon_host配置添加到Ceph配置。

在前两个服务器的重启期间,我们注意到配置毛刺。修复这些后,我们也会重新启动第三服务器。然后我们注意到几个Ceph OSD出乎意料地崩溃了。升级后,NTP服务无法正常工作。底层问题是NTP的竞争条件与Systemd-timeyyncd(见#889290)。因此,我们有Ceph的时钟偏差问题,表明Ceph监视器的时钟没有在同步中运行(这对于适当的Ceph操作至关重要)。我们最初假设我们的CephOSD失败导出了从这个时钟偏差问题,所以我们照顾它。在另一轮重新启动之后,为了确保系统运行所有具有相同和良好的配置和服务,我们发现大量失败的OSD。这次除了三个OSD(19,21和22)之外的所有时间都被下降了:

%sudo cephosd树 ID类权重类型名称状态重新款项PRI-AFF -1 65.44138根默认 -2 21.81310主机服务器1 0 HDD 1.08989 OSD.0下跌1.0 000 1.00000 1 HDD 1.08989 OSD.1下跌1.0万1.00000 2 HDD 1.63539 OSD2下降1.0万本1.00000 3 HDD 1.63539 OSD.3下跌1.0万本1.00000 4 HDD 1.63539 OSD.4下跌1.0万本二1.00000 5 HDD 1.63539 OSD.5下跌1.0万本1.00000 18 HDD 2.18279 OSD.18下跌1.0万本1.00000 20 HDD 2.18179 OSD.20下跌1.0万本1.00000 28 HDD 2.18179 OSD.28下跌1.0 000 1.00000 29 HDD 2.18179 OSD.29下跌1.0万本二1.00000 30 HDD 2.18179 OSD.30下跌1.0万本1.00000 31 HDD 2.18179 OSD.31下跌1.0万本 -4 21.81409主机服务器2 6 HDD 1.08989 OSD.6下跌1.0万本1.00000 7 HDD 1.08989 OSD.7下跌1.0万1.00000 8 HDD 1.63539 OSD.8下跌1.0万本1.00000 9 HDD 1.63539 OSD.9下跌1.0万本1.00000 10 HDD 1.63539 OSD.10下降1.0万本1.00000 11 HDD 1.63539 OSD.11下跌1.0 000 1.00000 19 HDD 2.18179 OSD.19上升1.00000 1.00000 21 HDD 2.18279 OSD.21上升1.00000 1.00000 22 HDD 2.18279 OSD.22上升1.00000 1.00000 32 HDD 2.18179 OSD.32下跌1.0万本1.00000 33 HDD 2.18179 OSD.33下跌1.0万本 34 HDD 2.18179 OSD.34下跌1.0万本1.00000 -3 21.81419主机服务器3 12 HDD 1.08989 OSD.12下跌1.0 000 1.00000 13 HDD 1.08989 OSD.13下降1.0000 1.00000 14 HDD 1.63539 OSD.14下跌1.0万1.00000 15 HDD 1.63539 OSD.15下跌1.0万本1.00000 16 HDD 1.63539 OSD.16下跌1.0万本1.00000 17 HDD 1.63539 OSD.17下跌1.0 000 1.00000 23 HDD 2.18190 OSD.23下跌1.0万本1.00000 24 HDD 2.18279 OSD.24下跌1.0万码1.00000 25 HDD 2.18279 OSD.25下跌1.0万本二1.00000 35 HDD 2.18179 OSD.35下跌1.0万本1.00000 36 HDD 2.18179 OSD.36下跌1.0万本1.00000 37 HDD 2.18179 OSD.37下跌1.0万本1.00000

我们的血压略有增加!我们只是失去了所有的集群吗?发生了什么,我们如何让所有其他osds回来?

Warning: Can only detect less than 5000 characters

SynPromika @ Server1〜%OSD_ID = 0 synpromika @ server1〜%sudo ceph auth获取OSD。" $ {OSD_ID}" -f json 2> / dev / null | JQ -R'。[] | .key' aqckfpzdm0we [...]

SynPromika @ Server1〜%OSD_ID = 0 synpromika @ server1〜%sudo cephosd元数据OSD。" $ {osd_id}" -f json | JQ -R' bluestore_bdev_partition_path' / dev / sdc2

通过所有这些,我们重建了keyring,fsid,whoami,block + block_uuid文件。 XFS元数据分区中的所有其他文件在每个OSD上都是相同的。因此,在XFS分区上放置和调整相应的元数据进行Ceph使用情况后,我们得到了一个工作的OSD - 欢呼!由于我们必须修复另外32个OSD,我们决定自动化此XFS分区和元数据恢复过程。

我们有一个网络共享,可在/ sRV /备份上提供用于存储现有分区数据的备份。在每个服务器上,我们在迭代剩余失败的OSD的列表之前,使用一个OSD测试了一个过程。我们在Server1上使用Shell脚本开始,然后调整Server2和Server3的脚本。这是脚本,正如我们在第3个服务器上执行它。

由于这一点,我们设法让Ceph集群再次运行。我们不想在夜间继续升级Ceph升级,因为我们想确切地知道正在发生的事情以及为什么系统表现得那样。 RCA的时间!

所以除了Server2上的三个OSDS之外,所有其他OSDS都失败,问题似乎与XFS相关。因此,与Server1 + Server3相比,我们对RCA的起点是在Server2上识别Server2上的不同。我的初步假设是,这与涉及的控制器的一些固件问题有关(并且在稍后结果之后,我是对的!)。将磁盘作为JBOD设备附加到ServerAid M5210控制器(条带尺寸为512)。固件状态:

SynPromika @ Server1〜%sudo Storcli64 / C0显示全部| grep' ^固件' 固件包构建= 24.16.0-0092 固件版= 4.660.00-8156 SynPromika @ Server2〜%sudo storcli64 / c0显示全部| grep' ^固件' 固件包构建= 24.21.0-0112 固件版= 4.680.00-8489 SynPromika @ Server3〜%sudo Storcli64 / C0显示全部| grep' ^固件' 固件包构建= 24.16.0-0092 固件版= 4.660.00-8156

这看起来非常有希望,因为Server2确实在控制器上使用不同的固件版本运行。但是怎么样?嗯,Server2的主板在2020年1月由Lenovo / IBM技术人员取代,因为我们在内存升级期间有一个失败的内存插槽。作为此过程的一部分,Lenovo / IBM技术员安装了最新的固件版本。根据我们的文档,一些OSDS在3月和4月20日期间重建(由于Filestore-和Bluestore迁移)。事实证明,这些OSD是那些幸存升级的OSD。因此,使用在所涉及的控制器上运行的不同固件版本创建生存的驱动器。使用较旧的控制器固件创建所有其他OSD。但这是什么差异?

- 无法使用xfsprogs 4.19.x内核4.20(scgcq02027889)创建或挂载XFS文件系统 - XFS_INFO命令在XFS文件系统上运行,在条带大小1M上创建的XFS文件系统,显示SUNIT和SWIDTH AS 0(SCGCQ02056038)

我们的XFS问题肯定与控制器的固件有关。我们还回顾说,我们的监控系统报告了3月和4月重建的OSDS的不同Sunit设置。例如,OSD 21重新创建并获得了不同的Sunit设置:

SynPromika @ Server2〜%systemctl show var-lib-ceph-osd-ceph \\ x2d21.mount | Grep Sunit. 选项= RW,Noatime,Attr2,Inode64,Sunit = 512,Swidth = 512,Noquota SynPromika @ Server3〜%systemctl show var-lib-ceph-osd-ceph \\ x2d25.mount | Grep Sunit. 选项= RW,Noatime,Attr2,Inode64,Sunit = 1024,Swidth = 512,noquota

%diff -u ceph-disk-osd-25.log ceph-disk-osd-21.log -synpromika @ server2〜%sudo ceph-disk -v prepare - bluestore / dev / sdj --osd-id 25 + synpromika @ server3〜%sudo ceph-disk -v prepare - bluestore / dev / sdi -osd-id 21 [...] -command_check_call:运行命令:/ sbin / mkfs -t xfs -f -i size = 2048 - / dev / sdj1 -meta-data = / dev / sdj1 isize = 2048 agcount = 4,Agsize = 6272个漏斗 [...] + command_check_call:运行命令:/ sbin / mkfs -t xfs -f -i size = 2048 - / dev / sdi1 +元数据= / dev / sdi1 isize = 2048 agcount = 4,Agsize = 6336个折扣 = sectsz = 4096 attr = 2,projid32bit = 1 = CRC = 1 finobt = 1,稀疏= 0,rmapbt = 0,Reftink = 0 -data = bsize = 4096块= 25088,imaxpct = 25 - = SUNIT = 128 SWIDTH = 64个BLK +数据= bsize = 4096块= 25344,imaxpct = 25 + = SUNIT = 64 SWIDTH = 64个BLK 命名=版本2 BSIZE = 4096 ASCII-CI = 0 FTYPE = 1 log =内部日志bsize = 4096块= 1608,版本= 2 = Sectsz = 4096 Sunit = 1个漏斗,懒惰计数= 1 实时=无extsz = 4096块= 0,rtextents = 0 [...]

所以回来了,我们甚至试图跟踪这个,但却无法理解它。但是,现在这听起来非常像它与我们看到的问题有关,我们使用此Ceph / XFS失败。我们遵循occam的剃须刀,假设最简单的解释通常是正确的,因此让我们检查磁盘属性并查看有什么不同:

synpromika @ server1〜%sudo blockdev - getsz - getsize64 - getss - getpbsz --getiomin - getioopt / dev / sdk 4685545472 2398999281664 512. 4096 524288 262144 synpromika @ server2〜%sudo blockdev - getsz - getsize64 - getss - getpbsz --getiomin - getioopt / dev / sdk 4685545472 2398999281664 512. 4096 262144 262144

查看Server1和Server2之间的差异,用于相同的磁盘? Getiomin选项现在向其中报告一些不同的东西:

SynPromika @ Server1〜%sudo blockdev --getiomin / dev / sdk 524288 synpromika @ server1〜%cat / sys / block / sdk / queue / minime_io_size 524288 synpromika @ server2〜%sudo blockdev --getiomin / dev / sdk 262144 synpromika @ server2〜%cat / sys / block / sdk / queue / minept_io_size 262144

它没有意义的是,最小I / O大小(IOMIN,AKA BLKIOMIN)大于最佳I / O大小(IOOPT,AKA BLKIOOPT)。这会导致我们到错误202127 - 无法在597T设备上安装或创建XF,该设备在此匹配我们的研究结果。但为什么这个XFS分区在过去工作,现在使用较新的内核版本失败?

现在,我们有备份所有XFS分区的备份,我们想追踪a)介绍此XFS行为,b)是否有可能重用XFS分区而无需重建XFS分区从头开始(例如,如果您没有工作Ceph OSD或备份)。

让我们使用GRML Live System查看这样一个失败的XFS分区:

根@ grml〜#grml-version grml64-full 2020.06发布代号ausgehfuahangl [2020-06-24] 根@ grml〜#uname -a Linux Grml 5.6.0-2-AMD64#1 SMP Debian 5.6.14-2(2020-06-09)X86_64 GNU / Linux 根@ grml〜#grml-hostname grml-2020-06 将主机名设置为GRML-2020-06:完成 根@ grml〜#exec zsh root @ grml-2020-06〜#dpkg -l xfsprogs util-linux 期望=未知/安装/删除/清除/保持 | status = not / inst / conf-files / unpacked / half-conf / half-inst / trig-await / trig-pend | / err?=(无)/ recst-resst(status,err:大写=坏) || /名称版本架构描述 +++ - ============== - ============ - ============ - ===== ====================================. II Util-Linux 2.35.2-4 AMD64杂项系统公用事业 II XFSPROGS 5.6.0-1 + B2 AMD64管理XFS文件系统的实用程序

root @ grml-2020-06〜#mount ./sdd1.dd / mnt 安装:/ mnt:mount(2)系统呼叫失败:结构需要清洁。 根@ grml-2020-06〜#dmesg |尾巴-30 [...] [64.788640] XFS(LOOP1):SB条带单元Sanity检查失败 [64.788671] XFS(LOOP1):在XFS_SB_READ_VERIFY + 0x102 / 0x170 [XFS]中检测到元数据损坏,XFS_SB块0xFFFFFFFFFFFFFFFFFFFFF [64.788671] XFS(LOOP1):卸载并运行XFS_REPAIR [64.788672] XFS(LOOP1):前128个字节损坏的元数据缓冲区: [64.788673] 00000000:58 46 53 42 00 00 00 00 00 00 00 00 00 00 00 62 00 XFSB .......... B. [64.788674] 00000010:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [64.788675] 00000020:32 B6 DC 35 53 B7 44 96 9D 63 30 AB B3 2B 68 36 2..5S.D..C0 .. + H6 [64.788675] 00000030:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 ...... ......... [64.788675] 00000040:00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 02 ................ [64.788676] 00000050:00 00 00 00 01 00 00 18 80 00 00 00 04 00 00 00 00 ................ [64.788677] 00000060:00 00 00 06 48 BD A5 10 00 08 00 00 02 00 00 00 00 ...... ............ [64.788677] 00000070:00 00 00 00 00 00 00 00 00 00 00 00 0C 0C 0B 01 0D 00 00 00 19 ................ [64.788679] XFS(LOOP1):SB验证失败,错误-117。 root @ grml-2020-06〜#mount -t xfs -o rw,relatime,attr2,inode64,sunit = 1024,swidth = 512,noquota ./sdd1.dd / mnt / 安装:/ mnt:错误的fs类型,坏选项,坏超级块上/ dev / loop1,缺少的代码页或辅助程序,或其他错误。 32根@ grml-2020-06〜#dmesg |尾巴-1 [66.342976] XFS(LOOP1):条纹宽度(512)必须是条带单元的倍数(1024) root @ grml-2020-06〜#mount -t xfs -o rw,relatime,attr2,inode64,sunit = 512,swidth = 512,noquota ./sdd1.dd / mnt / 安装:/ mnt:mount(2)系统呼叫失败:结构需要清洁。 32根@ grml-2020-06〜#dmesg |尾巴-14 [66.342976] XFS(LOOP1):条纹宽度(512)必须是条带单元的倍数(1024) [80.751277] XFS(LOOP1):SB条带单元Sanity检查失败 [80.751323] XFS(LOOP1):在XFS_SB_READ_VERIFY + 0x102 / 0x170 [XFS]中检测到元数据损坏,XFS_SB块0xFFFFFFFFFFFFFFFFFF [80.751324] xfs(loop1):卸载并运行xfs_repair [80.751325] XFS(LOOP1):第一个128字节损坏的元数据缓冲区: [80.751327] 00000000:58 46 53 42 00 00 00 00 00 00 00 00 00 00 00 62 00 XFSB .......... B. [80.751328] 00000010:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...... [80.751330] 00000020:32 B6 DC 35 53 B7 44 96 9D 63 30 AB B3 2B 68 36 2..5S.D..C0 .. + H6 [80.751331] 00000030:00 00 00 00 00 00 00 40 08 00 00 00 00 00 00 00 00 00 01 00 ...... ......... [80.751331] 00000040:00 00 00 00 00 00 00 00 00 00 00 00 00 01 02 ................ [80.751332] 00000050:00 00 00 00 01 00 00 18 80 00 00 00 00 04 00 00 00 00 ................ [80.751333] 00000060:00 00 06 48 BD A5 10 00 08 00 00

......