目录
一、前言
二、故障现象
三、初步调试
四、故障排查操作
五、降级MON副本操作
一、前言
记一次测试环境rook-ceph故障排查始末,故障原因为使用nerdctl创建测试容器后多个节点创建了nerdctl0网桥导致calico组件故障,记录本文为排查故障和rook-ceph特殊操作参考。
基础环境:
kubernetes: v1.30.1
rook-ceph: release-1.19.0
nerdctl: v2.1.1
containerd: v2.1.0
二、故障现象
登录rook-ceph-dashboard页面,可查询到日志如下
MON_DOWN: 1/3 mons down, quorum b,c mon.a (rank 0) addr [v2:10.97.242.52:3300/0,v1:10.97.242.52:6789/0] is down (out of quorum) PG_AVAILABILITY: Reduced data availability: 1 pg inactive pg 1.0 is stuck inactive for 6d, current state undersized+peered, last acting [1] PG_DEGRADED: Degraded data redundancy: 1 pg undersized pg 1.0 is stuck undersized for 6d, current state undersized+peered, last acting [1] POOL_NO_REDUNDANCY: 3 pool(s) have no replicas configured pool 'replicapool' has no replicas configured pool 'sata-myfs-metadata' has no replicas configured pool 'sata-myfs-replicated' has no replicas configured本次环境为单主机三硬盘测试搭建搭最小副本可行性,故告警内的PG异常和存储池高危配置忽略不计,由日志可看出问题在于MON集群故障,节点a离线导致仲裁票数不足,集群只读 / 阻塞、无法正常数据调度,此时测试业务还在正常运行,但是新建PVC失败会一直pending。
三、初步调试
查询故障mon-a的日志,可查询到关键信息
mon.a@0(probing) e3 handle_auth_request failed to assign global_id
1,mon-a本地 RocksDB 元数据正常加载完成,MON 进程正常启动、绑定端口成功;
2,但 mon.a 始终处于 probing 探测状态,无法加入仲裁集群,认证阶段无法从当前 quorum(mon.b、mon.c)申请分配全局 ID;
3,表现为:MON 进程活着,但一直探测、无法加入集群,长时间重试认证失败,最终被判定 down。
常见诱因如下:
1,集群时间不同步(最常见):三个 MON 节点宿主机时间偏差过大,Ceph 认证基于时间戳校验,直接拒绝分配 global_id;
2,集群密钥损坏:ceph.client.admin.keyring、mon.keyring 多节点不一致;
3,原有 MON 残留集群信息异常,Paxos 仲裁同步卡住;
4,网络问题:mon.a Pod 可以通集群内网,但安全策略 / 防火墙 / NetworkPolicy 拦截了 MON 之间 6789、3300 端口互访。
#由于所有pod均running,未注意部分calico未ready初期未排查网络(个人失误)
登录tool容器执行命令查询mon仲裁状况
root@rook-node1:~# kubectl exec -it deploy/rook-ceph-tools -n rook-ceph -- bash bash-5.1$ ceph mon stat查询命令卡死,初步判断为Ceph MON 集群仲裁不满足导致无法查询。
四、故障排查操作
执行下列命令,试图绕过仲裁阻塞删除mon-a
root@rook-node1:~# kubectl exec -it deploy/rook-ceph-tools -n rook-ceph -- bash -c "ceph --mon-host=mon.b,mon.c mon remove a" server name not found: mon.b (Name or service not known) unable to parse addrs in 'mon.b,mon.c' 2026-06-18T11:07:12.553+0000 7f96e3b17640 -1 monclient: get_monmap_and_config cannot identify monitors to contact [errno 22] RADOS invalid argument (error connecting to the cluster) command terminated with exit code 1此时怀疑为tools 容器内无法解析该短域名,必须使用MON 实际集群 IP而非服务名,故使用命令查询对应IP,使用IP重试删除命令
root@rook-node1:~# kubectl -n rook-ceph get svc | grep mon rook-ceph-mon-a ClusterIP 10.99.156.163 <none> 6789/TCP,3300/TCP 3d19h rook-ceph-mon-b ClusterIP 10.99.235.118 <none> 6789/TCP,3300/TCP 3d19h rook-ceph-mon-c ClusterIP 10.99.12.177 <none> 6789/TCP,3300/TCP 3d19h root@rook-node1:~# kubectl -n rook-ceph get pods | grep mon rook-ceph-mon-a-5dd9cc8c77-h2dqd 2/2 Running 0 3d19h rook-ceph-mon-b-5fd88bd66c-bcv6v 2/2 Running 0 3d19h rook-ceph-mon-c-dbffdd9b5-pf7nk 2/2 Running 0 3d19h root@rook-node1:~# kubectl exec -it deploy/rook-ceph-tools -n rook-ceph -- bash -c "ceph --mon-host=10.99.235.118,10.99.12.177 mon remove a"使用IP操作也会卡死,尝试进入容器b内部进行执行
root@rook-node1:~# kubectl -n rook-ceph exec -it rook-ceph-mon-b-5fd88bd66c-bcv6v -- bash Defaulted container "mon" out of: mon, log-collector, chown-container-data-dir (init), init-mon-fs (init)此时判断mon-a一直处于探测认证失败状态,整个 MON 集群 Paxos 仲裁锁卡死,现在不论进 tools 还是 mon 容器都会阻塞等待集群仲裁响应,常规 ceph 管理命令全部无法执行,尝试走强制降级 MON 副本的兜底方案来解锁集群。
五、降级MON副本操作
由于ceph-mon 进程是pod的形式存在,RocksDB 文件锁无法释放,故直接在本地安装ceph工具停止服务等操作无法执行,最终方案为:启动特权测试容器挂载主机节点的 /var/lib/rook/mon-c/data 目录
#缩容operator避免mon容器启动RocksDB 文件锁无法释放 root@rook-node1:~# kubectl scale deploy rook-ceph-operator --replicas=0 -n rook-ceph root@rook-node1:~# kubectl delete deploy rook-ceph-mon-b rook-ceph-mon-c -n rook-ceph #修改mon的data删除故障节点a的IP,只使用b,c的IP root@rook-node1:~# kubectl edit configmap rook-ceph-mon-endpoints -n rook-ceph data: b=10.99.235.118:6789,c=10.99.12.177:6789 root@rook-node2:~# nerdctl run -it --rm --privileged -v /var/lib/rook/mon-b/data:/var/lib/ceph/mon/ceph-b -v /var/lib/rook:/var/lib/rook mon镜像名称 bash-5.1$ ceph-mon --id b --mon-data /var/lib/ceph/mon/ceph-b --conf /dev/null --extract-monmap /tmp/monmap bash-5.1$ monmaptool --rm a /tmp/monmap bash-5.1$ ceph-mon --id b --mon-data /var/lib/ceph/mon/ceph-b --conf /dev/null --inject-monmap /tmp/monmap bash-5.1$ exit #在c节点执行相同的操作即可完成a节点的删除如上完成mon配置文件的修改后,还是无法完成选举。
重新排查集群状态时,发现calico-node仅running长时间没有ready查询日志后发现是故障发生前使用nerdctl创建容器默认创建了nerdctl0网桥使用了10.4.0.1IP,全节点冲突导致,删除该网桥重启calico组件,通信问题消失,手动恢复rook-ceph的三节点仲裁,一切正常。
六、总结
kubernetes内服务故障时优先查询kube-system等组件的状态,先确认所组件ready再排查具体业务pod的问题。
后续使用nerdctl工具时需注意,nerdctl命令仅用于管理镜像,在kubernetes内创建容器只使用kubectl,避免nerdctl0网桥的影响。