运维Ceph集群的人,大概都逃不过这个场景:某个周一早上,监控突然报警,cephfs的空间还剩不到10%,客户端开始出现卡顿,日志里全是POOL_FULL。你赶到机房,一边安抚业务同事,一边在脑子里飞快过了一遍解决方案——扩容量。于是你拉了一批新磁盘,准备往集群里加OSD。又或者反过来,老板让你降本增效,回收几台服务器,你得从集群里安全退掉一批OSD,还不能让上面跑着的文件系统出任何状况。
这两种操作,一个加、一个减,看似是Ceph运维里最常见的动作,但真正做起来,坑不少。尤其是配合CephFS这种对延迟和一致性都敏感的上层服务,OSD的增减不只是执行几条命令那么简单。扩容后的数据均衡会影响客户端IO,缩容时的数据迁移会占用空间和带宽,稍有不慎就可能把集群状态从HEALTH_OK推到HEALTH_WARN甚至HEALTH_ERR。这篇就专门讲CephFS环境下OSD的增删,从原理到实操,再到我踩过的那些坑,一条龙说清楚。
1. 先搞明白CephFS和OSD的关系
1.1 CephFS读写链路中的OSD角色
CephFS不是个独立的文件系统守护进程,它由三部分组成:客户端挂载的基础,MDS(元数据服务器),以及底层真正存放数据的OSD集群。当你访问一个CephFS目录,客户端的请求会先经过MDS去查元数据——比如文件在哪个目录、叫什么、权限是什么。但文件内容本身,是被切成一个个对象(object),通过CRUSH算法映射到osd上去刷盘的。
这里容易有个错觉:很多人以为CephFS的数据主要靠MDS管理,OSD只是底层存储。实际上恰恰相反,MDS只负责目录树和文件元数据,真正的数据写入压力全都落在OSD上。一个OSD就是一个对象存储守护进程,通常对应一块盘。CephFS的元数据池(通常是cephfs_metadata)和数据池(cephfs_data)最终都由OSD来承载。也就是说,OSD的数量和健康度,直接决定了这个文件系统的可用容量和整体性能。
所以你在为CephFS扩容的时候,本质上是在为文件系统增加可供数据落盘的OSD。缩容的时候也一样,你是在减少文件系统可用的存储底座,这个动作会触发数据迁移,因为CRUSH算法需要重新分布数据,保持副本数满足配置要求。
1.2 什么情况下你会动OSD
实践中,增删OSD的触发原因就几类:
- 容量水位告急:这是最常见的扩容信号。数据池使用率超过80%,cephfs写入出现
EDQUOT或者卡顿,这时候你得加盘扩容。 - 硬件故障替换:某块盘IO错误,SMART报警,或者OSD频繁down,你需要让这个OSD下线并更换硬件。
- 缩容降本:某些业务下线,服务器要退回机房,或者项目组要求把集群规模收敛,这时候需要主动淘汰一批OSD。
- 性能调优:集群里OSD过少,单个OSD承担的压力太大,你希望增加OSD来分散IO压力,提升并发能力。
确定了你属于哪种场景,才能选对操作路径。比如只是临时调低某个OSD的权重来压数据量,跟直接remove掉一个OSD,两者的风险等级完全不一样。下面我把增加和删除两个方向分开来写,每个方向你都能照着一步步做。
2. 增加OSD的完整操作流程
2.1 硬件与系统准备
在敲命令之前,先花半小时把准备工作做扎实,后面会省掉很多麻烦。
第一件事是确认新磁盘的状态。拿到的机器可能装过系统,或者被人用来放过ZFS/RAID分区,直接交给ceph-volume很可能报错。我习惯上用lsblk和blkid看一眼盘符和文件系统类型,如果有残留,先用wipefs -a /dev/sdb把分区表和文件系统签名全清掉。注意,这步会摧毁盘上所有数据,操作前务必确认盘的序列号和你规划的槽位对得上。
第二件事是检查网络和时钟。OSD之间的数据迁移、复制都走网络,建议至少万兆网卡并且做了bond。同时NTP不能省,时钟漂移会造成MON误判OSD宕机,我在一个混合硬件集群里吃过这个亏。另外确认/etc/ceph/ceph.conf里配置了正确的cluster网络,新加的节点如果网段不对,找MON注册都费劲。
第三件事,确认你用的是哪种部署工具。如果集群是用cephadm部署的,那加OSD可以直接走orch,省事很多。如果是手动用ceph-volume部署的传统集群,那你得确保新节点的OSD软件包已安装,并且/etc/ceph/里放着和集群一致的keyring文件。两种方式下面都会讲到,但核心逻辑是一样的:让Ceph认领这块盘,初始化为一个OSD。
2.2 用ceph-volume部署一个OSD
传统手动部署方式下,我推荐用ceph-volume而不是老旧的ceph-disk,前者支持BLUESTORE且功能更全。执行步骤大致是这样:
# 先清除磁盘残留 ceph-volume lvm zap /dev/sdb # 创建OSD(自动创建LV并配置bluestore) ceph-volume lvm create --data /dev/sdb执行完以后,系统会创建一个以UUID为名的LV,并把该块盘注册为OSD。你可以用ceph-volume lvm list查看结果,确认磁盘设备、OSD ID和FSID对应关系。
如果你的集群用的是cephadm,命令更简单,在MON所在的容器环境中执行:
ceph orch device ls ceph orch daemon add osd <hostname>:/dev/sdb或者直接让cephadm自动扫描未使用的设备:
ceph orch apply osd不过我不太建议在已有生产数据的情况下让orch全自动apply,那可能会把一些规划外的盘也拉进来。最好手动指定主机和盘符,一次一个,稳。
创建完OSD后,它会自动加入CRUSH map,进入集群并参与PG的数据分布。不需要手动调整权重,因为刚加入的OSD权重是默认值,CRUSH会逐步把PG迁移过来。这里有一个经验:如果是老集群扩容,新OSD加入后,整个集群的PG会自动开始回填,回填速度取决于集群里设置的osd_max_backfills参数。想让新盘尽快收到数据,可以临时把这个值调高一点,但不要超过8,否则客户端IO延迟会明显上升。
2.3 扩容后的验证与数据均衡
OSD加完后,至少要到第三步确认状态:
ceph osd tree ceph osd stat ceph health detail看三件事:新的OSD状态是否为up和in;集群整体HEALTH状态还是没有PG异常;数据池里的PG是否在逐步回填。回填过程中你会看到很多active+remapped或者backfilling的PG,这很正常,说明数据正在重新分布。
有个容易被忽略的细节:CephFS有元数据池和数据池,OSD扩容后,你可能希望让某个文件系统专门使用新加的那批高性能盘,而不是让它和旧数据混在一起。这时候需要提前把池的CRUSH规则区分开,比如用ssd类别的OSD专门承载cephfs_data池。我在实际项目里见过太多人没规划好这个,结果SATA和NVMe混在一个池里,性能被低效盘拖垮。如果你有这个诉求,得在添加OSD的时候给不同设备的OSD设置不同的device class,然后为数据池创建对应的CRUSH rule。这个属于规划层面的话题,不是简单加个盘就完事的,但列出来提醒你。
3. 删除OSD的完整操作流程
3.1 删除前的评估和规划
删OSD比加OSD危险得多,因为数据要迁走,期间任何意外都可能造成PG不可用。所以第一步别急着敲命令,先回答这几个问题:
- 集群当前磁盘空间还剩多少?数据迁移期间,源OSD上的数据会被复制到其他OSD,目标位置需要的容量约等于源OSD上已用数据量乘副本数再除以目标OSD数量,总之会留出冗余。如果集群空间低于30%可用,我劝你先别急着删。
- 目标OSD上现在分布着哪些PG?用
ceph osd find <id>找到对应节点,再看ceph pg ls-by-osd <id>里PG数量。如果这个OSD承担了很多热点PG,删除前最好还是等业务低峰期。 - 集群里有没有足够健康的OSD来接管数据?查看
ceph osd tree,确认其他OSD状态正常,没有大量down的盘。 - 是否要保留这个OSD的数据副本?如果是计划内更换硬件,数据不需要保留,直接走淘汰流程。
做完整评估后,我习惯先把目标OSD在纸面上记录下来:OSD ID、对应宿主机、设备路径、实际使用的pool。这样后面无论哪一步出了问题,都能快速回滚或定位。
3.2 标准删除流程(out -> crush reweight -> purge)
很多人上来就执行ceph osd rm,那是大忌。除非你是想强行从集群里踢掉一个已损坏的OSD来减少故障影响,否则正常淘汰流程应该严格按下面顺序来:
第一步,让OSD退出。所谓“退出”,就是让CRUSH算法不再把新的PG分配给这个OSD,同时触发该OSD上已有PG向其他OSD迁移。
ceph osd out <osd_id>执行之后,你会看到这个OSD的状态从in变成out。数据迁移马上开始,这个OSD上的活动PG会逐渐重映射到其他OSD上。这一步本身无风险,因为它不涉及删除任何东西,随时可以用ceph osd in <osd_id>恢复。
第二步,等待所有PG恢复为clean。这一步可能是整个流程里最耗时也最容易让人焦虑的部分。你需要持续观察:
ceph pg stat ceph pg dump | grep -c 'active+clean'当目标OSD上的PG数减少到0,也就是ceph pg ls-by-osd <osd_id>输出为空时,数据已经全部迁出。此时就算物理拔盘也不会丢数据。有些版本下,你还可能看到PG处于active+backfill状态,这表示还在写数据,继续等。
如果等待过程太长,想加速,可以临时调高osd_max_backfills和osd_recovery_max_active两个参数,并在回填完成后调回原值。注意,这个操作会占用集群IO,业务高峰期慎用。
第三步,永久剔除OSD。确认PG迁移完成后,执行:
ceph osd purge <osd_id> --yes-i-really-mean-it这条命令会把OSD从OSD map、CRUSH map中彻底移除,并把这个OSD上的认证key也删掉。如果集群里该OSD其实还在运行,purge前最好先执行ceph osd down <osd_id>再把对应进程停掉,否则OSD进程会反复尝试连MON并重新注册,导致状态异常。
如果你用的不是太老的版本,也可以分步执行:
ceph osd down <osd_id> ceph osd crush remove <osd_name> ceph osd rm <osd_id>效果类似,但不如purge一步到位。我个人推荐直接用purge,除非你想对CRUSH权重做特殊处理,比如某个OSD只是临时调整,并不想删除实体。
第四步,清理物理资源。OSD从集群移除后,磁盘可能还保留着LVM卷和BLUESTORE元数据。如果这块盘还要继续用,执行:
ceph-volume lvm zap /dev/sdb如果这块盘要被物理拔掉,直接拔也没问题,但最好先把LV清理干净,避免后续别人插上这块盘时误以为它是系统盘。
3.3 物理更换与后续清理
如果是故障盘替换,流程上还多一个步骤:确认故障盘对应的槽位,记录盘序列号,拔盘后插新盘,然后按照第二节新增OSD的流程重新初始化。这里重点提醒:新盘的序列号可能跟旧盘不一样,但OSD ID会重新分配一个,不会沿用旧的。你要是还在监控脚本里写死了“这个槽位对应OSD.12”,那替换后就要同步更新脚本。
曾经遇到过这样的情况:某台机器上原OSD.12挂了,我们把系统盘身份信息清除后插了新盘,用ceph-volume lvm create初始化,结果发现新OSD起不来。排查到最后,是因为新盘上遗留着老LVM设备,ceph-volume默认拒绝覆盖已有VG。解决办法其实很简单,就是先ceph-volume lvm zap /dev/sdb --destroy,彻底清掉所有VG/LV信息再创建。记住这条,能帮你省掉半小时。
4. CephFS场景下的注意事项
4.1 容量阈值和监控指标
CephFS对集群容量的敏感度可能比RBD卷还高。因为RBD卷的使用率是由客户端文件系统控制的,Ceph自身只关心底层pool的空间有没有被撑满。而CephFS是一个共享文件系统,客户端随时可能写文件,如果容量接近上限,没有任何优雅的降级方式——满池直接导致元数据写入失败、文件系统只读。所以你在增删OSD时,一定要清楚CephFS两大核心池的容量分布。
建议把ceph df detail的输出纳入常规监控,重点关注cephfs_data池的UTIL值,以及cephfs_metadata池的USED值变化。增加OSD后,文件系统容量理论上会随之上涨,但要注意:新建的OSD会按CRUSH规则均衡地分散到集群里所有pool中,并不保证“我的文件系统容量立刻翻倍”。如果你希望新增的OSD真正为cephfs_data池所用,最好把池对应的CRUSH rule只关联到新加入的那组OSD上。
删除OSD则相反:目标OSD里可能既有文件系统数据也有块存储数据。为了不让文件系统空间在迁移中触顶,删之前最好用ceph osd pool autoscale-status查一下各pool的容量,如果cephfs_data的使用率本来就很高,那迁移时要特别小心。我通常的做法是在迁移期间,把文件系统池的full_ratio再稍微放宽一点,例如调到0.95,防止因为空间紧张导致Ceph进入full状态后云里雾里。
4.2 文件系统与PG数的影响
CephFS的PG数由pool的pgp_num决定,而PG数量又受OSD数量影响。缩容后,如果OSD数量大幅减少,但pool的PG数没有调整,就会出现PG分布不均:少数OSD上可能压着几十个PG,其他OSD却只有几个。这种不均衡会直接影响文件系统的吞吐。
举个例子,原来集群有60个OSD,cephfs_data池设置了512个PG,每个OSD平均约8.5个PG,还算均衡。如果一次性下线了20个OSD,剩下40个OSD平均每个要扛12.8个PG,压力上升50%,而且因为CRUSH算法重新分布,很多PG会rebalance,短期内性能波动很大。
所以在删除OSD之前,我建议先评估最终保留的OSD数量,必要时提前调整cephfs_data和cephfs_metadata池的pg_num和pgp_num。但这又是一个大坑——pg_num只增不减,要减的话得重新创建pool,这可以说是灾难级操作。所以真实生产里,更好的策略是分批次删OSD,一批删两到三个,等集群完全clean再继续下一批。千万不要一次性把20个OSD全部out,那会让剩余OSD的PG数量瞬间暴涨,甚至因为回填风暴拖垮整个集群。
4.3 删除OSD时对客户端IO的影响
CephFS客户端对延迟比较敏感,尤其是小文件读写场景。删除OSD时,数据回填占用磁盘和网络IO,必然会对客户端的IO造成一定干扰。很多运维在ceph osd out之后就把注意力放在PG状态上,忽略了客户端的实际感受。如果业务侧反馈卡顿,你得马上意识到可能是回填风暴。
控制回填风暴有三板斧。第一板斧,限制回填速度,设置osd_max_backfills为1或2,让集群“优雅地”迁移数据。第二板斧,调整osd_recovery_delay_start,让OSD启动后延迟一段时间再开始回填,给客户端一段平稳窗口。第三板斧,利用osd_recovery_op_priority降低恢复操作优先级,让正常IO优先,回填任务靠后。这三个参数可以动态调整,实测对CephFS整体可用性帮助很大。
另外一个很隐蔽的问题:CephFS挂载客户端在OSD删除进程中有可能碰到MDS的元数据请求超时。表现为客户端目录ls卡住,或者某个文件stat无响应。这通常不是MDS故障,而是底层数据迁移太猛,导致对应元数据所在的OSD被挤占资源。此时优先降回填速度,等缓解后再继续观察。
5. 常见问题排查与避坑记录
5.1 问题速查表
我把这些年做OSD增删时遇到的高频问题整理成了表格,你在实际操作中如果踩到类似的,直接对照着处理:
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
ceph osd out后PG长时间不迁移 | 集群本来就不健康,或者有PG处于down状态 | ceph pg dump_stuck查找异常PG,先修复基础故障再继续 |
删除OSD后还有active+remapped的PG | 有其他OSD同时down,导致副本数不够 | 先恢复其他down掉的OSD,或检查min_size副本配置 |
新加入的OSD状态为down | 磁盘或文件系统遭到破坏,或Ceph服务未启动 | systemctl status ceph-osd@<id>查看日志,多半需要ceph-volume lvm zap后重建 |
| 扩容后CephFS写速下降 | 回填任务占用了集群IO | 调低osd_max_backfills和回填优先级 |
ceph osd purge报权限错误 | 输入的认证key没有管理员权限 | 使用client.admin的keyring,或检查caps |
| pool空间不够,迁移无法完成 | Ceph进入full状态,禁止写入 | 立即临时加OSD或用ceph osd set noout暂时防止数据迁移,把空间释放出来 |
| 拔掉旧盘后,Ceph的device monitor一直在报警 | 物理移除后未清理OSD记录 | 执行ceph device rm手动清理设备记录,或等待ceph-device自动管理端润滑 |
| 删除OSD期间CephFS目录操作卡顿 | 回填导致元数据池的OSD负载过高 | 调低回填速度,必要时重启MDS(低峰期) |
看到表格里的“重启MDS”,我得多说一句:别轻易重启MDS,除非你确认元数据池所在OSD一切正常,并且重启窗口不影响业务。MDS故障切换本身没问题,但会产生短暂的元数据downtime,对于很多应用来说,这就够“卡”了。
5.2 我的几个独家心得
第一个心得:增删OSD的最佳时机永远是业务低峰期。我知道很多运维会想“反正数据迁移是自动的,白天晚上没区别”,但实际体验告诉你区别非常大。白天突然的写入高峰会叠加回填峰值,集群的IO曲线会出现双峰,互相放大,最终谁都跑不动。我在夜班窗口做这种操作,一次也没有翻过车。
第二个心得:给新OSD做预写入测试。别直接拿一块新盘就进生产环境,先用FIO或者vdbench压一下盘的最大顺序写和随机读能力,选掉那些体质差的盘。这个步骤可能让你多花两个小时,但能避免几个月后因为坏盘再次触碰到OSD增删这个麻烦流程。
第三个心得:记得在变更后刷新监控基线。很多团队的监控系统还在用半个月前的容量数据,你增删完OSD如果不更新Prometheus或者Zabbix的指标基线,报警阈值可能一直对不上。特别是CephFS的使用率,删除完后可能从80%降到60%,但报警还挂在80%上,到时候误报了你都不知道问题在哪。
第四个心得,也是我认为最有价值的:做好OSD变更的“回滚演练”。我知道直接把OSD in回去比out更简单,但purge之后是没有后悔药的。所以我在大批量删除OSD前,一定先拿去某台测试环境,完整跑一遍out、等待、purge、zap,确认操作脚本没有任何意外才在正式集群执行。这套演练的成本不高,但给了你足够的安全感。
6. 结尾还是想说点实在的
CephFS下的OSD增删,说到底考验的不是你会不会几条命令,而是对数据分布、集群容量、IO折损的综合理解。加盘时要会控制回填节奏,删盘时要等数据完全迁出,每一步都要监控PG状态和客户端体验。我这些年在生产环境里进进出出几十个OSD,最深的体会就是:慢就是快,多等一会儿PG变clean,比在出问题时抢救强一百倍。
如果你正准备在自己的环境做一次OSD变更,建议先对照这篇的步骤列一个checklist,尤其是如果计划一次性删一批盘,宁可分几次操作,也别挑战CRUSH的极限。最后提醒一句:执行ceph osd purge时,那句--yes-i-really-mean-it不是开玩笑,按下去之前再确认一次盘符和OSD ID,这是我踩过无数次坑后最值钱的教训。