ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Ceph集群组件管理实战:从架构部署到故障恢复全解析

Ceph集群组件管理实战:从架构部署到故障恢复全解析 刚接手一套生产环境的 Ceph 集群时大多数人第一反应都是先看监控、查容量、翻告警。但真正决定这套存储系统能跑多久、出了故障能不能快速恢复的往往是一个容易被忽略的点——组件管理。Ceph 的组件不算复杂核心就是 MON、MGR、OSD、MDS 这几类角色再加上 RGW 网关。可就是这么几个角色在真实集群里组合出来的问题千奇百怪MON 挂了一多半、OSD 反复 flapping、MGR 多活切换不干净、MDS 锁竞争导致卡顿。这篇文章我就围绕“Ceph 集群组件管理”这件事把从组件选型、部署要点、日常运维到故障恢复的完整思路捋一遍顺便把我自己踩过的坑和验证过的操作记录下来给正在折腾 Ceph 或者准备接手 Ceph 集群的朋友做个参考。这套内容适合谁看两类人。一类是刚接触分布式存储、对 Ceph 组件只有模糊概念的运维或开发你能从这里搞明白每个组件到底管什么、为什么需要它以及集群里各组件之间是怎么协作的。另一类是已经有一套集群在跑、但遇到组件异常不知道怎么定位和处理的工程师后面几个章节提供了可以直接照做的排查流程和恢复操作。无论你是用 cephadm 部署的全新集群还是从 ceph-ansible、rook 之类老方案迁移过来的存量集群组件管理的底层逻辑都是相通的。1. 组件架构拆解先搞懂每个角色是干什么的Ceph 能被叫做“统一存储”核心就在于它把对象、块、文件三种存储接口全部构建在同一个底层系统之上而支撑这套系统的就是那几个各司其职的组件。做组件管理之前必须先对这些角色建立起清晰的心智模型。1.1 MON整个集群的“共识大脑”MONMonitor维护着 Cluster Map包括 OSD Map、PG Map、MDS Map 等元数据。客户端要读写数据第一步是连接 MON 获取最新的 Cluster Map然后才知道该找哪个 OSD。MON 通过 Paxos 协议保证多个副本之间的元数据强一致所以它的数量必须是 1、3、5 这类奇数生产环境至少部署 3 个。很多人容易低估 MON 的重要性觉得 OSD 才是存数据的核心。实际上 MON 一旦全部宕机客户端虽然还能用已经缓存的 Map 做读写但任何涉及 PG 变更、OSD 上下线、创建 pool 的操作都会直接卡死。更重要的是OSD 之间的心跳和对 etcd 类似也是依赖 MON 来协调状态的如果 MON 长时间不可用整个集群会陷入“假死”状态。1.2 OSD数据真正落盘的地方OSD 负责把数据写入物理磁盘并且周期性地向 MON 上报自身状态。一个 OSD 进程通常对应一块磁盘但在生产环境我更推荐把 OSD 绑定到整块物理盘或独立的逻辑卷上不要在同一块盘上叠多个 OSD否则单盘故障后的数据恢复路径会变得很复杂。OSD 之间的数据复制、故障检测、数据迁移都是通过 OSD 之间的心跳机制完成的。PG 是数据分布的最小单位每个 PG 根据副本数映射到多个 OSD 上。PG 的数量规划在组件管理中属于“一次规划、长期受益”的事后面我会专门讲。1.3 MGR集群的“运维副驾驶”MGRManager是后来引入的组件主要承担监控、调度、API 等功能。它运行了 Prometheus 模块、Dashboard、Balancer 等所有你用ceph status看到的详细指标其实都来自 MGR。MGR 支持多活部署通常建议部署 2 个互相热备。MGR 的作用常被忽视但实际影响很大。比如集群数据不均衡时开启 Balancer 模块能自动迁移 PG 实现负载均衡磁盘写满前的预测性告警也依赖 MGR 的 Telemetry 和预测模块。组件管理里如果漏掉 MGR 的配置和维护集群会少掉很大一块可观测性和自愈能力。1.4 MDS文件存储的专属管家MDSMetadata Server只服务于 CephFS负责管理文件系统的元数据目录结构、文件名、权限等并不参与实际数据读写。客户端读写文件数据时仍然直接跟 OSD 通信MDS 只负责告诉客户端“你要找的文件在哪”。MDS 可以部署多个同一个文件系统上多个 MDS 会分担不同的目录子树。生产环境建议至少 2 个避免单点故障同时要注意 Rank 的概念——每个活跃的 MDS 都对应一个 Rank如果 Rank 数量规划不合理会造成元数据访问热点。2. 组件部署与配置规划生产环境该怎么选型和落位组件管理的第一个实际问题就是“部署几个、放哪台机器”。很多集群初始化时图省事全部堆在一起等到扩容或者故障隔离时就非常被动。2.1 组件数量和节点分布规划生产环境的最低推荐配置是这样组件推荐数量说明MON3 或 53 台能容忍 1 台故障5 台能容忍 2 台故障MGR2多活热备其中一个故障不影响查询OSD每盘 1 个按容量和性能规划建议独立物理盘MDS2 起按 CephFS 业务量扩展最好和 MON 分离RGW按业务伸缩无状态前面加负载均衡即可这里有一个非常关键的部署原则MON 和 OSD 要尽量做到“故障域隔离”。所谓故障域就是当一台物理机宕机时它上面挂载的组件最好只影响集群的一小部分而不是一下子把某个组件的多数派打掉。比如你一共 3 个 MON如果全部放在同一台服务器上那这台服务器挂了就等于 MON 全挂集群直接脑裂。我自己习惯的做法是把 MON 和 MGR 放在一起作为控制面节点OSD 分布在所有存储节点上MDS 放在 CPU 较强且跟业务网络延迟低的机器上。这样既不浪费资源又能保证控制面的故障域相对独立。2.2 部署方式选型cephadm 还是容器化方案Ceph 官方推荐 cephadm 方式它用容器跑组件通过 SSH 管理整个集群。它的好处是组件升级、添加节点、替换故障磁盘都变成了标准操作而且自带 Dashboard 和监控栈省去很多手工配置的时间。如果是早年间用 ceph-ansible 部署的集群也不必着急迁移。组件管理上核心是理解 Ceph 本身而不是部署工具。cephadm 和容器化部署只是让运维更标准组件自身的逻辑不变。但要注意如果用了 Rook 在 Kubernetes 内跑 Ceph那组件管理就多了一层 K8s 资源管理需要额外关注 Operator 的版本兼容性。2.3 关键配置参数在组件管理里的作用组件管理不只是“启停组件”还包括组件的运行时参数调优。最典型的是 MON 相关参数# ceph.conf 中与 MON 相关的关键参数 mon_osd_down_out_interval 600 mon_osd_min_down_reporters 2 mon_pg_warn_max_object_skew 100000mon_osd_down_out_interval的作用是当一个 OSD 被判定为 down 后等待多久才把它从 Cluster Map 中移除out。默认值 600 秒意味着 OSD 故障 10 分钟后才触发数据重新分布。如果业务对数据冗余要求高、并且网络环境稳定可以把值调短一些让故障恢复更快但如果磁盘本身有偶发卡顿调短反而会导致频繁的数据迁移对集群造成额外负载。这类参数在 cephadm 部署的集群中通常用ceph config set来动态调整不需要改配置文件后重启组件。这也是我推荐新集群用 cephadm 的原因之一——运行时配置的灵活性和安全性高很多。3. 组件生命周期管理启停、扩缩容与状态检查组件管理的日常绝大多数时候是在跟“状态”打交道。你需要确切知道每个组件当前的状态、它们属于哪个节点、最近有没有异常重启而这些信息全部可以通过命令行拿到。3.1 查看组件状态的标准姿势最常用的几条命令# 查看集群整体状态 ceph status # 查看 MON 状态和选举情况 ceph mon stat ceph quorum_status --format json-pretty # 查看 MGR 状态 ceph mgr stat # 查看 OSD 树了解每个 OSD 所在的节点和状态 ceph osd tree # 查看 MDS 状态 ceph fs status ceph mds stat很多人习惯只看ceph status的最下面几行觉得HEALTH_OK就够了。但实际上ceph status的顶层信息非常粗糙只有深入对应组件的子命令才能看到更多细节。比如ceph osd tree不仅能看出 OSD 是否在线还能看出每个 OSD 所在的 host、rack、failure domain这对排查数据分布是否均衡非常关键。我做过的一个真实案例某个集群明明HEALTH_OK但发现个别 OSD 的容量使用率高达 85%其他 OSD 只有 40%。单看健康状态完全发现不了问题只有ceph osd tree配合ceph osd df才能定位到是 PG 分布不均还是 OSD 权限集weight设置有误。3.2 组件的启停和重启操作Ceph 组件的启停要特别小心。以 cephadm 为例# 查看某个组件服务 ceph orch ps --daemon-type mon ceph orch ps --daemon-type osd # 重启某个组件 ceph orch restart mon.host1 # 重启某个主机上的所有 OSD ceph orch daemon restart osd.host1.abc123在非 cephadm 环境中重启组件需要登录到对应主机用 systemd 管理。比如systemctl restart ceph-monhost1 systemctl restart ceph-osd1 systemctl restart ceph-mdshost1有一点必须强调重启 OSD 和重启 MON/MGR 是完全不同的风险级别。重启 OSD 只会影响该 OSD 上的 PG如果副本数为 3数据仍可访问只是暂时少了一个副本但重启 MON 会影响集群的 quorum一旦操作不当可能导致客户端短时间拿不到最新的 Cluster Map。所以在生产环境做 MON 重启时我通常会先确认 quorum 是否正常然后逐个重启等前一个恢复正常再操作下一个。任何时候都不要一次重启多个 MON这是组件管理中最基本的一条红线。3.3 组件扩容的正确姿势集群扩容是每个存储系统都要经历的事。扩容分两种一种是新增 OSD 扩展容量另一种是新增 MON 或 MGR 提升控制面可用性。新增 OSD 在 cephadm 环境下非常容易# 向集群增加新节点 ceph orch host add newhost 192.168.1.101 # 让 cephadm 自动发现并部署该节点上的 OSD ceph orch apply osd --all-available-devices但这里有个容易踩坑的地方--all-available-devices会把节点上所有可用磁盘都初始化为 OSD包括系统盘。如果你不想让系统盘被征用需要先给系统盘加过滤标签比如用ceph orch device zap newhost /dev/sda --force的相反逻辑——先标记设备为不可用再自动部署。如果是手动方式新增 OSD则需要经过准备好独立的块设备或逻辑卷把该设备加入 LVM 组并创建 OSD 数据分区用ceph-volume lvm create --data /dev/xxx初始化启动 OSD 进程并确认它被 MON 接纳。扩容 MON 相对简单在 cephadm 中直接ceph orch apply mon --placementhost1,host2,host3,host4,host5会自动完成新增和调整。手动环境则要把新节点加入[mon]段并执行ceph-mon --mkfs初始化再逐个加入 quorum。3.4 组件缩容与下线比扩容更考验水平下线组件比扩容容易翻车。最常见的是下线 OSD步骤必须严谨因为涉及数据迁移# 1. 把目标 OSD 从 Cluster Map 中移除Ceph 会自动把该 OSD 上的 PG 迁移出去 ceph osd out osd.12 # 2. 等待数据迁移完成 ceph status # 观察 rebalanced 状态直到回到 HEALTH_OK # 3. 停掉 OSD 进程并从 crush map 中删除 ceph osd crush remove osd.12 ceph osd rm osd.12 # 4. 如果还需要清除 LVM 配置执行 ceph-volume lvm zap /dev/xxx很多事故发生在第一步和第二步之间。有些朋友执行完ceph osd out后发现数据迁移太慢为了赶时间直接跳过等待执行了后续的crush remove。结果就是 OSD 虽然删了但部分 PG 还在等待迁移数据面临丢失风险。过程中务必用ceph status里的rebalancing进度确认或者用ceph pg stat看 activeclean 的比例达到 100% 再继续。下线 MON 节点时要注意 quorum 变化。先执行ceph mon remove hostname然后确认剩余 MON 能继续形成 quorum。如果剩下两个 MON 而其中之一又挂了那就只有一个能参与选举集群可用性会瞬间下降。所以缩容 MON 后至少保留 3 个是底线。4. 组件故障排查与恢复把集群从水深火热中拉回来组件管理最核心的价值体现在故障发生时的快速定位与恢复。真实的故障场景通常是很乱的多个组件同时告警日志刷屏这时候最忌讳的是看到什么就动什么。4.1 组件状态异常的定位思路第一步先确认基础网络和磁盘健康# 检查所有主机的连通性 ceph orch host ls # 查看所有 OSD 的 up/down 状态 ceph osd stat # 查看最近告警 ceph health detail --format json-pretty定位阶段的核心思想是“由远及近、由面到点”。先用ceph health detail看全局告警面再逐步收敛到某个组件类型最后落到具体的 daemon。举个例子如果某个 OSD 呈现 down 状态常见的定位链条是磁盘是否还能正常识别用lsblk看设备是否存在文件系统是否只读用mount看挂载状态OSD 日志是否有 IO 错误用journalctl -u ceph-osd12看最近日志系统日志里是否有内核报错用dmesg -T | tail -100检查是否有 I/O error、blocked for more than 120 seconds 的记录。很多时候 OSD down 的根因不是 Ceph 本身而是宿主机的磁盘老化或 HBA 卡驱动异常。这时候你在 Ceph 层做任何操作都是徒劳的必须先恢复底层硬件。4.2 MON 故障处理与 quorum 恢复MON 故障最严重的情况是 majority down即 3 个 MON 里有 2 个都挂了。这种情况下集群会失去 quorum所有写操作停止你执行ceph status都会卡住。恢复步骤比较讲究这里给出我验证过的流程找到还活着的那个 MON 节点确认它的数据目录完好在其中一台故障 MON 上尝试恢复通常使用 monmap 恢复模式如果单台恢复不了可以用存活 MON 的数据目录重新生成一台新 MON并重建 monmap。monmaptool是这里的关键工具。你可以用# 从存活节点导出当前 monmap ceph mon getmap -o /tmp/monmap.bin # 查看 monmap 内容 monmaptool --print /tmp/monmap.bin # 在要恢复的节点上用 monmap 启动临时 MON ceph-mon -i hostname --inject-monmap /tmp/monmap.bin --keyring /etc/ceph/ceph.mon.keyring这类操作在官方文档里属于灾难恢复流程建议在空闲测试集群先演练几遍。我的经验是所有 MON 故障恢复的前提是至少有 2 份有效的密钥和数据目录备份否则重建过程会非常痛苦。4.3 OSD 反复 flapping 的处理OSD flapping 指的是一个 OSD 频繁地上线和下线导致 PG 不断进行 peering 和 recovery。遇到这种问题强制重启往往适得其反因为每次都把 OSD 拉起来又掉会让集群反复震荡。正确的思路是观察至少 10 分钟日志确认触发下线的具体原因网络超时、磁盘延迟、内存不足都可能导致如果确认是网络抖动引起的短暂 flapping可以暂时将 OSD 的down_out_interval调大留出更长的容忍窗口若是磁盘延迟过高先用smartctl检查盘的健康度必要时直接下线盘并更换。实际工作中最坑的一种情况是同一块盘上的 OSD 由于数据库日志分区db/wal空间不足导致持续刷脏、性能抖动。这种问题从ceph osd df完全看不出来只有登录到节点上看/var/lib/ceph/osd/ceph-*/下的 db 空间占用才能定位。4.4 MDS 故障与 CephFS 访问异常MDS 故障的表现是 CephFS 挂载后卡死、目录操作缓慢或者客户端直接报input/output error。第一步要确认 MDS 本身的 rank 状态ceph mds stat如果看到 MDS 处于failed或damaged状态说明元数据可能已经损坏。此时可以尝试杀掉卡死的 MDS 进程释放 rank执行ceph mds fail rank让集群重新拉起如果自动拉起失败手动重启 MDS 服务若 MDS 日志提示损坏需要从备份恢复元数据情况就复杂得多。CephFS 元数据备份通常建议使用cephfs-journal-tool来导出和导入日志在损坏之前就做好定期备份能省下很多麻烦。4.5 MGR 异常对监控和调度的连带影响MGR 故障不像 MON 那样直接中断读写但会造成监控数据断流、Dashboard 无法访问、Balancer 模块停摆还会影响 Pg repair 相关的自动任务。MGR 自身支持多活只要至少一个 MGR 存活就不会有太大问题。MGR 的常见故障原因是资源泄漏或 Prometheus 模块异常导致内存暴涨。恢复方法是主动 failover# 查看 MGR 模块状态 ceph mgr module ls # 让不健康的 MGR 让位 ceph mgr fail mgr-name值得一提的是MGR 的module ls能告诉我们哪些模块被禁用。以前踩过一次坑专门在测试环境想用 Balancer结果module ls发现它根本是 disabled 状态。启用方法很简单ceph mgr module enable balancer这类“启用了模块却没生效”的问题往往不是配置写错而是模块本身没开。组件管理里最容易漏的就是各种“状态没激活”。5. 组件管理的监控告警与自动化运维组件管理做到最后一定是向自动化和可观测性靠拢。如果没有完善的监控和告警组件管理的所有操作都是事后补救有了监控和自动化很多故障可以在用户感知之前就被处理掉。5.1 cephadm 自带的监控栈落地cephadm 部署集群时可以默认安装 Prometheus、Grafana、Alertmanager。它们的组件形态是容器跟 MON、OSD 一起由ceph orch管理。这套监控栈覆盖得很好ODS、MON、MGR、MDS 的指标都会暴露给 Prometheus预置的告警规则也够用。我用过一段后感觉最实用的是这几个 Grafana 面板面板名称作用Ceph - Cluster总容量、使用率、PG 数量、健康状态Ceph - OSD每个 OSD 的 IOPS、延迟、容量、状态Ceph - Pools每个存储池的用量和性能Ceph - cephadm集群管理的任务状态和节点健康没有 cephadm 监控栈的存量集群也可以手动把ceph_exporter或 Prometheus 模块接入现有 Prometheus只是需要自己写一部分告警规则。5.2 关键告警规则配置经验监控做得好不好关键看告警能不能准确反映真实风险。以下几条告警规则是我在实际运维中反复验证过的价值很高告警规则建议阈值说明Cluster health 非 OK持续 1 分钟防呆告警任何异常都能察觉MON 数量小于 3一旦触发就告警控制面多数派失守风险极大OSD down 超过阈值持续 5 分钟防止单次抖动误报PG 数量小于 100 且 inactive持续 2 分钟读写卡死的直接表现磁盘空间使用率超 80%持续 15 分钟预留恢复和迁移空间MDS 活跃 Rank 数量低持续 10 分钟文件存储元数据处理能力下降值得一说的是磁盘空间使用率的 80% 这条线。Ceph 不同于普通文件系统它在 OSD 空间不足时会出现full保护机制此时所有写入都会失败。如果等到 90% 甚至 95% 才处理往往已经连迁移的空间都不够了所以建议告警阈值放得保守一点留足缓冲。5.3 自动恢复与人工介入的边界自动化能做的事情很多但组件管理的自动化要设置边界。比如OSD down 后自动设置noout可以防止偶发故障触发大规模 PG 迁移磁盘故障检测后用ceph orch device alert隔离坏盘需要确保硬件支持热插拔定期执行数据均衡任务用 Balancer 自动整理 PG 分布。我自己一直以来不建议完全自动化替代人工判断的场景是 MON 恢复和 MDS 恢复。MON 涉及 quorum连锁影响大MDS 涉及元数据完整性错误操作可能引发数据丢失。这类组件的操作宁可保留人工介入的环节让告警通知到人由有经验的工程师判断后再执行。6. 组件管理的实操案例与踩坑复盘理论讲再多都不如实际案例让人印象深刻。这里分享三个我遇到过的真实问题都是组件管理层面的典型场景。6.1 一场由错误osd out引发的数据迁移风暴某次计划内维护需要下线一批老磁盘。我事前把集群状态确认无误然后执行了ceph osd out osd.100。但没想到这个 OSD 正好承载了大量 PG而且集群整体负载较高数据迁移一开始就非常缓慢。由于迁移迟迟不完我下意识又执行了ceph osd out osd.101想着加快迁移速度。实际上这种操作是典型的“迁移风暴放大器”。进行中的 PG 迁移本身就会占用大量网络和磁盘 IO你再去掉更多的 OSD只会让集群的迁移任务叠加造成数据重分布越来越慢甚至影响正常业务 IO。后来我养成了一个习惯无论多着急一次只下线一个 OSD并设置迁移速度上限用osd_max_backfills或target_max_backfill参数调节确保业务 IO 不被拖垮。6.2 MON 磁盘空间耗尽导致的假死我之前维护的一台 MON监控一直显示磁盘使用率 75% 左右看似安全。结果某天集群突然多个 OSD 报 down再过几分钟整个集群进入 noout 状态ceph status也开始出现异常。登录那台 MON 主机检查发现根分区已经写满。原因是 MON 日志默认不自动滚动长时间运行后/var/log/ceph占满了磁盘。MON 写不了日志内部状态同步也会出问题继而影响整个控制面。处理方法是清理日志、开启 logrotate并给/var/log/ceph挂了一个独立分区。这件事之后我所有集群的 MON 节点都检查了一遍日志保留策略。组件维护不只是管进程还要管好组件的“周边生态”比如日志、临时目录、数据目录的磁盘空间。6.3 MDS 卡死引起客户端 IO 停顿某个 CephFS 客户端反馈写入卡死一查 MDS 状态发现 rank 1 处于replay状态很久rank 0 正常。这类问题在 CephFS 多 MDS 场景下并不少见原因是某个目录的元数据操作特别集中导致该 rank 的加载压力过大。我当时的处理是先调整mds_bal_split_size和mds_bal_merge_size尝试让目录拆分更积极如果调整参数后仍然卡顿考虑重新分配 MDS rank 到不同主机最坏情况下把故障 rank 上的 CephFS 客户端先切走再重启 MDS 服务。踩过之后我才意识到的组件管理思路是MDS 的性能瓶颈往往不在 CPU 和内存当然也会而在元数据访问的局部性。热点目录如果天然集中无论怎么调 MDS 参数效果都有限。真正的解决方向是业务侧拆分热点目录或者让 CephFS 的多个 rank 覆盖不同子树。7. 组件管理工具链与实战建议聊了这么多最后落地到“用什么工具、按什么流程做”。组件管理的工具链选择会直接影响日常效率。7.1 核心命令速查表整理一份最常用的命令速查方便大家直接收藏操作命令查看集群状态ceph status查看 OSD 树ceph osd tree查看每个 OSD 容量ceph osd df查看 PG 分布ceph pg dump查看 MON 选举ceph quorum_status管理 MGR 模块ceph mgr module enable/disable管理 MDSceph mds stat/ceph fs status查看 cephadm 服务ceph orch ps重启服务ceph orch restart daemon设备管理ceph orch device ls7.2 组件管理的规范化操作流程为了避免人为失误我建议团队里把常见的组件管理动作做成 Checklist比如 OSD 下线流程评估该 OSD 上的 PG 数量和数据量执行ceph osd out每 10 分钟检查一次ceph status确认迁移进度迁移完成后确认activeclean停 OSD 进程从 crush map 移除清理 LVM 配置更新资产记录。这套流程看起来简单但真的能严格执行能避免绝大多数误操作。7.3 关于人工管理与自动化管理的取舍最后说说我的观点。Ceph 组件管理确实是“越自动化越轻松”但自动化是针对常规操作的关键时刻人必须能兜底。一个合格的 Ceph 运维人员至少要能在命令行里完成组件的启停、状态检查和故障定位而不是只会点 Dashboard。因为 Dashboard 给你看到的是结果而命令行能让你理解过程和原因。工具链可以逐步完善从最早的 shell 脚本到后来的 Ansible 剧本再到 cephadm 标准操作本质都是把重复劳动自动化。但组件管理的底层思维——理解每个组件在系统里的角色、它们之间的依赖、故障的传播路径——这部分永远不会被工具替代。这也是我希望这篇文章能带给你的最有价值的东西。我自己这些年下来最深的感受是Ceph 的组件管理并不难难的是在出现问题的时候能不能保持清晰的思路。把每个组件的职责和相互作用关系整理清楚把常用操作流程固化成肌肉记忆剩下的问题就交给耐心和时间去解决了。
返回列表