Rook-Ceph v1.20.0 CSI ServiceAccount 命名不匹配 Bug 及修复方案
本文最后更新于:2026年6月3日 下午
前言
千万不要升级 rook-ceph helm chart 到 v1.20.0
血的教训! 差点让我的 Homelab 宕机, 数据丢失.
当时我是这样的情况:
- renovate 检查 rook-ceph helm chart 有新版本 v1.20.0
- CI helm diff 运行通过, 没有发现异常
- git 合并到主分支, argocd 升级到 v1.20.0
- 升级后发现 2 个 ctrlplugin pod 因为 SA 缺失无法启动
- github issue 检索方案, 发现这个 issue: v1.19.0 failed to delete volumeattachment due to secret name missmatch. 提供的方案是会退. (我的错. 情急之下没有注意到这个 issue 和我的版本不一样. 我的是 v1.20.0.)
- (我的错) git 回退并 push, argocd 同步. 结果部分 deployment 等永久卡住.
- (我的错) 删除卡住的 deployment, 结果删除后 arogcd 无法重建
- (我的错) 集群所有存储状态异常. git 也连不上了 (用到了 rook-ceph 存储)
- (我的错) 禁用 argocd 自动同步等功能.
- 重新安装 v1.20.0. 并 workaround 临时解决.
背景
从 rook-ceph v1.19.6 升级到 v1.20.0 后,Ceph mon 数据被升级为 Tentacle ondisk format (v20),无法降级回 v19.x。同时 v1.20.0 的 CSI operator 存在 ServiceAccount 命名不一致的 bug。
Bug 症状
升级到 v1.20.0 后,以下 Deployment 和 DaemonSet 无法创建 Pod:
| 组件 | 报错 |
|---|---|
rook-ceph.cephfs.csi.ceph.com-ctrlplugin |
serviceaccount "cephfs-ctrlplugin-sa" not found |
rook-ceph.rbd.csi.ceph.com-ctrlplugin |
serviceaccount "rbd-ctrlplugin-sa" not found |
rook-ceph.cephfs.csi.ceph.com-nodeplugin |
nodes is forbidden: ... cannot get resource "nodes" |
rook-ceph.rbd.csi.ceph.com-nodeplugin |
nodes is forbidden: ... cannot get resource "nodes" |
根因
Rook v1.20.0 的 CSI operator(ceph-csi-controller-manager)在创建 CSI Deployment / DaemonSet 时,引用的 ServiceAccount 名称使用旧命名风格(无 ceph-csi- 前缀):
cephfs-ctrlplugin-sarbd-ctrlplugin-sacephfs-nodeplugin-sarbd-nodeplugin-sa
但 Helm chart 创建的 ServiceAccount 使用新命名风格(带 ceph-csi- 前缀):
ceph-csi-cephfs-ctrlplugin-saceph-csi-rbd-ctrlplugin-saceph-csi-cephfs-nodeplugin-saceph-csi-rbd-nodeplugin-sa
名称不匹配导致 Pod 无法通过 ServiceAccount 校验。
RBAC 权限缺失链
通过拷贝创建的旧风格 SA 缺少三层 RBAC 权限,每一层都会导致不同的问题:
| 层级 | 缺失的绑定 | 影响组件 | 症状 |
|---|---|---|---|
| 1. ClusterRoleBinding(集群资源) | ceph-csi-{type}-ctrlplugin-crb、ceph-csi-{type}-nodeplugin-crb |
ctrlplugin, nodeplugin | 无法 list csinodes/volumeattachments/persistentvolumes |
| 2. RoleBinding(Leader Election) | ceph-csi-leader-election-rolebinding |
ctrlplugin | CSI attacher/resizer/snapshotter 无法 acquire leader lease,volume attach/detach 超时 |
| 3. ClusterRoleBinding(Node 权限) | ceph-csi-{type}-nodeplugin-crb、{type}-csi-nodeplugin |
nodeplugin | 无法 get nodes 信息 |
集群环境信息
- Rook 版本: v1.20.0
- Ceph 版本: v20.2.1 (Tentacle)
- CSI Operator: quay.io/cephcsi/ceph-csi-operator:v1.0.1
- Kubernetes: k3s
- 部署方式: Helm umbrella chart(rook-ceph + rook-ceph-cluster + snapshot-controller)
Workaround 方案
第一步:创建缺失的 ServiceAccount
基于已有的新风格 SA 拷贝创建旧风格 SA:
1 | |
第二步:绑定 RBAC 权限(三层全部)
旧风格 SA 缺少三层 RBAC 绑定,必须全部补齐:
2a. NodePlugin ClusterRoleBinding(集群级 node 访问权限)
1 | |
2b. CtrlPlugin ClusterRoleBinding(集群级 CSI 资源权限)
ctrlplugin 需要 list / watch csinodes、volumeattachments、persistentvolumes:
1 | |
2c. Leader Election RoleBinding(leases 权限 —— 关键!)
ctrlplugin 中的 csi-attacher、csi-resizer、csi-snapshotter 需要通过 leases 进行 leader election。如果缺少这个权限,attacher 永远无法成为 leader,导致所有 VolumeAttach / Detach 操作超时:
1 | |
诊断命令: 如果 attacher 日志中出现以下错误,说明缺少 leases 权限:
1 | |
修复后(并重启 Pod)应看到:
1 | |
第三步:重启 CSI Pod 使 RBAC 生效
1 | |
第四步:清理残留资源
RBAC 修复后,CSI attacher 恢复正常,但升级期间会产生大量残留资源需要手动清理。
4a. 删除过期的 Leader Election Leases
旧 Pod 持有的 lease 可能阻止新 attacher 成为 leader:
1 | |
4b. 强制清理卡死的 VolumeAttachment
升级期间 CSI attacher 不可用,会产生大量带有 deletionTimestamp 但 attached: true 的 VolumeAttachment。这些需要移除 finalizer 才能删除:
1 | |
诊断命令: 如果 PVC 挂载日志出现 Multi-Attach error 或 timed out waiting for external-attacher,大概率是残留 VA 未清理。
4c. 重启受影响的业务 Pod
RBAC 和 VA 清理后,之前因 CSI 不可用而卡住的业务 Pod 需要删除重建:
1 | |
第五步:验证修复
CSI 组件验证
1 | |
Attacher Leader Election 验证
修复后,attacher/resizer/snapshotter 应成功成为 leader:
1 | |
预期输出示例:
1 | |
业务 Pod 验证
1 | |
残留 VolumeAttachment 验证
1 | |
附录:RBAC 绑定映射总表
以下表格记录了从「旧 SA 名称」→「需要绑定的 ClusterRoleBinding / RoleBinding」的完整映射:
| 旧 SA 名称 | 绑定的 CRB / RoleBinding | 授予的权限 | 类型 |
|---|---|---|---|
cephfs-nodeplugin-sa |
ceph-csi-cephfs-nodeplugin-crb |
nodes get/list | ClusterRoleBinding |
cephfs-nodeplugin-sa |
cephfs-csi-nodeplugin-role |
nodes get/list | ClusterRoleBinding |
rbd-nodeplugin-sa |
ceph-csi-rbd-nodeplugin-crb |
nodes get/list | ClusterRoleBinding |
rbd-nodeplugin-sa |
rbd-csi-nodeplugin |
nodes get/list | ClusterRoleBinding |
cephfs-ctrlplugin-sa |
ceph-csi-cephfs-ctrlplugin-crb |
csinodes, volumeattachments, persistentvolumes | ClusterRoleBinding |
rbd-ctrlplugin-sa |
ceph-csi-rbd-ctrlplugin-crb |
csinodes, volumeattachments, persistentvolumes | ClusterRoleBinding |
cephfs-ctrlplugin-sa |
ceph-csi-leader-election-rolebinding |
leases (leader election) | RoleBinding |
rbd-ctrlplugin-sa |
ceph-csi-leader-election-rolebinding |
leases (leader election) | RoleBinding |
注意事项
-
这是一个 workaround,不是永久修复。 Rook operator 在 reconcile 时可能会删除这些手动创建的 SA,届时需要重新执行上述步骤。
-
不要降级到 v1.19.x。 Ceph mon 数据已被升级为 Tentacle ondisk format,旧版 Ceph 无法读取,强行降级会导致 mon 永久 crash。
-
ArgoCD 自动同步应保持关闭。 如果 ArgoCD 启用了自动同步,可能会回写 SA 配置导致冲突。建议在 Rook 发布官方修复前保持手动管理。
-
相关上游 Issue: 可以关注 rook/rook#16956 及相关 CSI operator 问题的修复进展。