Ceph MON 法定人数挂了怎么救(生产恢复实战)
MON 是 Ceph 的"大脑",3 个 MON 挂 2 个集群就死。本文记录我处理过的几次恢复,按"死多少 MON"分支。
一个挂了:稳
集群可用,只是冗余降级。
ceph -s # 看 quorum 信息
systemctl restart ceph-mon@<id> # 老版本
# 或
ceph orch daemon restart mon.<id> # cephadm
不行就重建:
# 1. 找一个活的 MON 导出 monmap
ceph mon getmap -o /tmp/monmap
# 2. 停掉坏的,删它的 store
systemctl stop ceph-mon@<id>
rm -rf /var/lib/ceph/mon/ceph-<id>/*
# 3. 用 monmap 重建
ceph-mon -i <id> --mkfs --monmap /tmp/monmap --keyring /etc/ceph/ceph.mon.keyring
systemctl start ceph-mon@<id>
两个挂了:危
集群只读甚至完全不可用。怎么救:
先想:是机器问题还是 mon 数据问题?
- 机器问题(网络、磁盘)→ 修复机器,mon 自己会回来
- mon 数据损坏 → 进入"单 MON 恢复模式"
单 MON 恢复模式
让仅剩的那个 MON 单独组成 quorum:
# 在活着的 MON 节点上
systemctl stop ceph-mon@<id>
monmaptool /tmp/monmap --rm <挂掉的mon1> --rm <挂掉的mon2>
ceph-mon -i <id> --inject-monmap /tmp/monmap
systemctl start ceph-mon@<id>
这样集群恢复成 1-MON,业务能跑了。然后重建挂掉的 2 个 MON。
全挂了:极危
3 个 MON 全死,且数据可能损坏。此时如果有 OSD 还活着,Ceph 提供了从 OSD 重建 MON store 的工具:
# 在任意 OSD 节点上
ceph-objectstore-tool --type bluestore --data-path /var/lib/ceph/osd/ceph-<id> \
--op update-mon-db --mon-store-path /tmp/mon-store
# 在所有 OSD 节点都跑一遍,把 mon-store 累积起来
# 然后用累积的 mon-store 启一个新 MON
ceph-mon --mkfs -i <new_id> --keyring /etc/ceph/ceph.mon.keyring \
--monmap /tmp/monmap
cp -r /tmp/mon-store/* /var/lib/ceph/mon/ceph-<new_id>/store.db/
这是最后的稻草,恢复出来的集群可能丢部分元数据(pool 配置、用户权限)。
预防
- MON 一定要奇数个(3 或 5),不要 2 也不要 4
- MON 节点分散在不同机架/机房,避免单点故障带走多个
- 每天备份 monmap:
ceph mon getmap -o /backup/monmap-$(date +%F) - monitor 节点磁盘用 SSD:MON 是写密集,HDD 会被慢死
教训:MON 挂的恢复操作都是高危,操作前 dd 备份每个 MON 的 /var/lib/ceph/mon 目录,搞错可以回退。