Rook v1.20 的 Breaking Changes 写得很硬:Ceph-CSI
Operator 是管理 CSI 驱动设置所必需的;CSI 设置从
rook-ceph-operator-config 与
rook-ceph Helm chart 移除;新装必须用
OperatorConfig 与 Driver
CR。继续只改旧 ConfigMap 键值,是在对一个不再拥有 CSI
权威的对象说话。
本文回答四个问题:为何拆出、两个 CR 如何分工、清单/Helm 怎么装、升级时如何避免把定制冲掉。不展开 RBD CreateVolume 参数(第 6 篇)与 features(第 7 篇)。
本篇在系列中的位置
篇目 核心内容 第 4 篇 · CephCluster 生命周期 mon/mgr/osd 与健康闸门 第 5 篇 · Ceph-CSI Operator OperatorConfig/Driver、迁移、谁拥有设置 第 6 篇 · RBD 供给路径 StorageClass → CreateVolume → image(规划)
版本锚定:Rook v1.20.4;Ceph-CSI v3.17.0(驱动版本线以 Rook 支持的最近 Ceph-CSI 为准,调镜像时查 ImageSet / chart);K8s v1.31–v1.36。
一、v1.20 断裂点:旧入口失效
依据 Rook v1.20.0 Release Notes 与 v1.20 CSI Configuration / Upgrade 文档:
| 旧世界(≤ 过渡期) | v1.20 新装 / 继续改设置 |
|---|---|
在 rook-ceph-operator-config 里设
CSI_* 键 |
不再应用 CSI 设置 |
在 rook-ceph chart values 里改大量 CSI
项 |
CSI 调谐转到 ceph-csi-drivers chart / CR |
| Rook Operator「顺带」拥有驱动部署细节 | ceph-csi-operator 管理驱动设置;Rook 升级文档表述为 admin-managed via ceph-csi-operator |
升级集群的特殊情况:Release Notes 写明,已有设置在升级后可继续工作,但后续更新需由管理员落到 Ceph-CSI 资源上;默认设置的集群未必需要定制。新装则必须走新模型。
Quickstart 的 TL;DR 因此变成:
git clone --single-branch --branch v1.20.4 https://github.com/rook/rook.git
cd rook/deploy/examples
kubectl create -f crds.yaml -f common.yaml -f csi-operator.yaml
kubectl create -f operator.yaml -f cluster.yaml漏掉 csi-operator.yaml,后面的 CSI
故事会缺运算符。Helm 用户则要按升级指南顺序处理
rook-ceph →
ceph-csi-drivers(v1.20
新要求) → rook-ceph-cluster。
二、OperatorConfig
与 Driver:默认与覆盖
CSI Configuration 文档给出设计分工:
OperatorConfig(名通常为ceph-csi-operator-config):每 Operator 命名空间一份;spec.driverSpecDefaults存放所有驱动共享的默认(日志级别、controller 副本、nodePlugin kubelet 路径、共享镜像默认等)。Driver:每种驱动一份,例如rook-ceph.rbd.csi.ceph.com、rook-ceph.cephfs.csi.ceph.com;spec覆盖默认,或设置仅该驱动有意义的字段(如 RBD 的deployCsiAddons/enableFencing,CephFS 的cephFsClientType)。
优先级:Driver 上与 defaults
同名的字段优先于
OperatorConfig.driverSpecDefaults。
默认设置出现在 deploy/examples/operator.yaml
中 Operator ConfigMap 之后的那段(Release
Notes 指向该文件区间)。清单安装时,若将来完整
apply 默认 operator.yaml,可能把 CSI
相关资源打回默认——定制必须先写回该文件或改用明确的 CR/Helm
工作流。
示意(字段以你环境文档为准):
apiVersion: csi.ceph.io/v1
kind: OperatorConfig
metadata:
name: ceph-csi-operator-config
namespace: rook-ceph
spec:
driverSpecDefaults:
controllerPlugin:
replicas: 2
nodePlugin:
kubeletDirPath: /var/lib/kubeletapiVersion: csi.ceph.io/v1
kind: Driver
metadata:
name: rook-ceph.rbd.csi.ceph.com
namespace: rook-ceph
spec:
deployCsiAddons: true
enableFencing: true驱动名即 provisioner
名:Driver.metadata.name 必须与
StorageClass provisioner、VolumeSnapshotClass
driver 一致。自定义前缀时,改的是 Driver
名本身(以及所有引用),不是只改一个已废弃的 ConfigMap
键。
三、从
rook-ceph-operator-config 迁移对照
文档给出多组「Previously → Now」映射。写进变更清单时可直接当检查表:
| 旧键 / 行为(概念) | v1.20 落点 |
|---|---|
CSI_ENABLE_CSIADDONS |
deployCsiAddons on
OperatorConfig or Driver |
CSI_*_IMAGE |
ImageSet ConfigMap(由 OperatorConfig
引用;见示例 operator.yaml) |
CSI_PROVISIONER_REPLICAS |
controllerPlugin.replicas /
deploymentStrategy |
CSI_FORCE_CEPHFS_KERNEL_CLIENT |
cephFsClientType(如
fuse) |
CSI_DRIVER_NAME_PREFIX |
Driver 的 metadata.name |
CSI_KUBELET_DIR_PATH / SELinux host
mount |
nodePlugin.kubeletDirPath /
enableSeLinuxHostMount |
| NFS 驱动启用 | 创建 NFS Driver CR(示例见
deploy/examples/csi/nfs/driver.yaml) |
升级指南要求:升到 v1.20 之前,先把现有资源导出备份:
kubectl -n "$ROOK_OPERATOR_NAMESPACE" get drivers.csi.ceph.io -o yaml > preupgrade-drivers.yaml
kubectl -n "$ROOK_OPERATOR_NAMESPACE" get operatorconfigs.csi.ceph.io -o yaml > preupgrade-opconfig.yaml(自 v1.18 起 Rook 已开始把旧设置转换成自动创建的
OperatorConfig/Driver;v1.20
则把「继续改旧 CM」这条路掐掉。)
四、Helm:ceph-csi-drivers
chart 不是可选装饰
v1.20 Upgrade 文档对 Helm 用户列出硬条件:
- 必须安装
ceph-csi-driverschart,否则 CSI 驱动会因 缺少 ServiceAccount 等而失败。 - 必须使用 Rook 提供的推荐 values(含正确的驱动名前缀,通常带 Operator 命名空间);仅用 chart 默认值会失败。
- 以往在
rook-cephchart 里做的 CSI 定制,改为在 drivers chart 配置。
安装示例(官方文档口径,版本钉 v1.20.4):
helm install ceph-csi-drivers --namespace rook-ceph ceph-csi-operator/ceph-csi-drivers \
-f https://raw.githubusercontent.com/rook/rook/v1.20.4/deploy/charts/ceph-csi-drivers/values.yaml前置:rook-ceph chart 先装,以提供 Ceph-CSI
operator 与 CRD。自定义镜像仍可能落在 rook-ceph
chart 的 CSI image 相关 values(Release Notes 区分:operator
设置走 drivers chart,部分自定义镜像仍走 rook-ceph
values)——改前读当前 tag 的 values
注释,不要凭记忆跨小版本混用。
社区在 v1.20.0 初期出现过「Driver CR 在、但 SA/RBAC 未装
→ ctrlplugin 起不来」的事故叙事(GitHub issue
讨论升级路径)。机制结论与文档一致:运算符 + Driver
CR 不足以代替 drivers chart / RBAC 清单。 排障时先
get operatorconfig,driver,再确认 SA
是否存在,而不是先重装 CephCluster。
对清单用户,若环境不用 Helm,仍须保证与 chart 等价的
RBAC/SA 材料被 apply(上游以 csi-operator
与示例清单演进为准;升级说明要求 apply
csi-operator.yaml)。不要假设「只升
Operator 镜像」会自动创建缺失的 ServiceAccount。
这是 v1.20 相对旧版本最容易踩的运维裂缝。
自定义 kubelet 路径、SELinux host mount、controller
副本策略等,属于节点发行版与平台安全基线差异,而不是 Ceph
性能旋钮。把这些项留在 drivers chart values 或
OperatorConfig 里做平台级默认,比让每个业务
StorageClass 各自发明一套更安全。业务侧应尽量只碰
pool、fsName、imageFeatures 等数据面参数(第 6–7 篇)。
五、清单安装:csi-operator.yaml
的位置
清单路径下,csi-operator.yaml 与
crds.yaml、common.yaml 一起出现在
Operator 启动之前。补丁升级示例(官方):
kubectl apply -f common.yaml -f crds.yaml -f csi-operator.yaml
kubectl -n rook-ceph set image deploy/rook-ceph-operator rook-ceph-operator=rook/ceph:v1.20.4验证语义(需真实集群):
kubectl -n rook-ceph get operatorconfig,driver期望看到 OperatorConfig 与 RBD/CephFS 等 Driver。应用存储是否可用,还要看 ctrlplugin/nodeplugin 是否 Ready,以及 CephCluster 是否健康——三者同时成立才进入第 6 篇的供给故事。
清单与 Helm
的等价关系可以记成:csi-operator.yaml 负责把
Ceph-CSI Operator 及其 CRD/运行时
送进集群;operator.yaml 里的默认
OperatorConfig/Driver 段(或
drivers chart)负责 声明驱动期望;Rook
operator.yaml 的 Rook Operator 段负责
Ceph
生命周期。三者缺一,故障表象会非常像「Rook
坏了」,实则只是安装矩阵不完整。
补丁升级(同主版本内,如 v1.20.0 → v1.20.4)官方叙述相对简单:更新 common/crds/csi-operator,再改 Rook Operator 镜像。即便如此,仍建议在变更窗口确认 Driver CR 未被意外重置,尤其当自动化流水线喜欢「整目录 apply examples」时。
六、v1.20 之后谁拥有 CSI 设置
用一句话收束所有权:
管理员(通过
OperatorConfig/Driver 或
ceph-csi-drivers Helm values)拥有 CSI
调谐权威;Ceph-CSI Operator 拥有调和执行;Rook Operator 拥有
Ceph daemon 与集群
CR;rook-ceph-operator-config 不再拥有 CSI
键值语义。
| 你想改的内容 | 改哪里 |
|---|---|
| provisioner 副本、kubelet 路径、CSI-Addons、fencing | OperatorConfig / Driver 或
drivers chart |
| CSI 容器镜像集 | ImageSet ConfigMap + OperatorConfig 引用(及文档所述 chart 值) |
| mon 数量、OSD 设备、Ceph 镜像 | CephCluster |
| 池、FS、RGW | 对应 Ceph* CR |
| PVC 参数、扩容开关 | StorageClass / PVC |
混淆所有权的典型症状:改了
rook-ceph-operator-config 里旧
CSI_* 键,重启了 Rook Operator,CSI Deployment
毫无变化。在 v1.20 上这是预期行为,不是
reconcile 坏了。
再补一张「变更工单」检查表,避免升级窗口现场争论:
- 变更的是 Ceph 镜像还是 CSI 调谐?两者工单分开。
- 若是 CSI:目标对象是
OperatorConfig、某个Driver,还是 ImageSet? - Helm 还是清单?Helm 是否已包含
ceph-csi-driversrelease? - StorageClass / VolumeSnapshotClass 中的名字是否仍等于
Driver.metadata.name? - 变更后验证对象是 ctrlplugin/nodeplugin Ready,还是只看 Operator Deployment?
五问都答得出来,才进入应用命名空间做 PVC 冒烟。冒烟失败时,按第 2 篇 RPC 轴归因,而不是立刻回滚 Ceph 主版本。
与第 3 篇 Rook 所有权对照:Rook
拥有「集群是否存在、daemon 是否按 CR 滚动」;Ceph-CSI
Operator
拥有「驱动进程如何被创建与调谐」;两者通过驱动名、Secret、mon
信息接线。接线断裂时,Ceph 可以 HEALTH_OK 而
PVC 永久
Pending——这正是拆分所有权后必须学会的新故障类,也是本系列相对纯
ceph/ 教程多出来的那一层。
加密、read affinity、CSI-Addons fencing
等高级开关,文档已示范应写在
OperatorConfig/Driver 或
CephCluster.spec.csi 的对应位置(例如 read
affinity 在集群 CR 的
csi.readAffinity)。本篇不展开这些功能语义(第
7、15 篇),但强调:高级开关的「写在哪」已经从旧
ConfigMap 迁走;写错对象等于没写。
七、谱系、争论与开放问题
Rook 内嵌 CSI 部署与 ConfigMap 键值
→ v1.18+:自动生成 OperatorConfig/Driver(过渡)
→ v1.20:Ceph-CSI Operator 必选;旧 CSI 键移除
→ Helm 拆出 ceph-csi-drivers(SA/RBAC + CR 配置)
争论:便利 vs 所有权清晰
| 立场 | 主张 | 证据/代价 |
|---|---|---|
| A:希望单一 chart / 单一 ConfigMap | 安装步骤少 | v1.20 已否决该模型作为 CSI 权威 |
| B:独立 CSI Operator + drivers chart | CSI 与 Ceph 升级面分离 | 多一个必须记住的安装/升级步骤;漏装即挂载面故障 |
本系列接受 B 为当前上游现实,并在第 11、13 篇把「漏装 drivers / CR 被默认清单覆盖」写成显式故障类。
开放问题:
多 CephCluster / 多命名空间下,Driver 名与 Secret/mon 路由如何避免 PVC Events 不可唯一归因?(第 3 篇已提,配置所有权拆分后更尖锐。)
GitOps 下的 apply 纪律:如何防止 CI 完整 apply 示例
operator.yaml静默打回 Driver 定制?需要平台级 kustomize/helm 冻结策略,而不是靠口头提醒。观测信号是否足够:
kubectl get operatorconfig,driver只能说明 CR 存在,不能说明 sidecar 版本与 VolumeSnapshot CRD 兼容,也不能说明 nodeplugin 在每个可调度节点都 Ready。第 12 篇需要回答:最小充分的 CSI 控制面健康信号集是什么?在信号集缺失时,平台是否应阻断升级流水线?
把 v1.20 迁移写成可关闭条件:旧 ConfigMap
中不再存在仍被文档引用的 CSI_*
键依赖;OperatorConfig/Driver 与
StorageClass provisioner 名一致;Helm 用户有
ceph-csi-drivers release;清单用户在升级
checklist 中显式勾选
csi-operator.yaml。四条任一未关闭,就不宣称「已完成
v1.20 CSI 迁移」。
从研究台账的角度看,这场拆分回应的是 Operator 模式里反复出现的张力:一个控制器是否应该拥有「应用(Ceph)+ 接入插件(CSI)」的全部旋钮。A 派认为单一入口降低安装成本;B 派认为配置面膨胀后,任何一次 Rook 升级都可能误伤挂载面。v1.20 选择了 B,并用 Breaking Changes 强制迁移。工程间隙是:文档与 chart 必须同步教会用户「第二张安装表」,否则强制迁移会把故障从「改错键」变成「漏装组件」——后者往往更难一眼看懂。
因此本篇的实践结论不是「Ceph-CSI Operator
更高级」,而是「所有权可命名之后,排障才可分工」。平台组可以规定:Ceph
镜像与 CephCluster
归存储内核值班;Driver/OperatorConfig
归 K8s 存储插件值班。两本 runbook 分开,比一本「Rook
百科」更接近 v1.20 的真实结构。
八、小结
- Rook v1.20:Ceph-CSI Operator
required;新装用
OperatorConfig+Driver;旧rook-ceph-operator-configCSI 键失效。 OperatorConfig管共享默认,Driver管每驱动覆盖与专用字段;Driver 名即 provisioner 名。- Helm 必须装
ceph-csi-drivers(推荐 values);清单路径必须含csi-operator.yaml。 - 升级前导出 CR;不要用「改旧 CM」验证新模型。
- 下一部分进入卷路径:RBD StorageClass →
CreateVolume→ image(第 6 篇)。
读完本篇,应能在变更评审里一票否决两类提案:其一,以「只改
rook-ceph-operator-config」作为 v1.20 集群的
CSI 变更方案;其二,以「只升级 rook-ceph Operator
镜像」作为完整的 v1.19→v1.20
挂载面迁移方案。前者改不到权威对象,后者漏掉 drivers/RBAC
面。两者都会在应用侧呈现为 Pending 或 attach 失败,却在 Ceph
侧呈现为健康——这正是编排层专文存在的理由。
第一部分(01–05)到此收束:有了五轴、RPC/sidecar、Rook CRD、CephCluster 生命周期与 CSI 所有权,才能安全进入供给与挂载细节,而不至于把每个失败都重装一遍集群。
若只能记住一句:v1.20 之后,CSI 设置的权威对象是
OperatorConfig 与 Driver,不是
Rook Operator ConfigMap。Helm 用户把同一句话翻译成:权威落在
ceph-csi-drivers release 的 values 与其生成的
CR 上。
九、参考资料
规范 / 官方文档(A)
- Rook v1.20.0 Release Notes — Breaking Changes(Ceph-CSI Operator required;CSI settings removed from operator configmap / rook-ceph chart)。
- Rook v1.20 CSI Configuration —
rook.io/docs/rook/v1.20/Storage-Configuration/Ceph-CSI/csi-configuration/。 - Rook v1.20 Ceph-CSI Drivers chart —
rook.io/docs/rook/v1.20/Helm-Charts/csi-drivers-chart/。 - Rook v1.20 Rook Upgrades — Breaking changes;保存
Driver/OperatorConfig;Helm 安装顺序。 - Rook v1.20 Quickstart —
csi-operator.yaml安装顺序。
源码 / 清单(A)
rook/rooktag v1.20.4:deploy/examples/operator.yaml(默认 CSI CR 段)、deploy/examples/csi-operator.yaml、deploy/charts/ceph-csi-drivers/values.yaml。
站内对照
实验台账
- 本篇无自有集群输出;迁移表来自官方 CSI Configuration 对照。
→ 上一篇:CephCluster 生命周期 · 系列目录 · 下一篇:RBD 供给路径
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
【Rook / CSI】编排全景:五轴坐标系与 16 篇路线
相对 ceph/ RADOS 内核与 storage/ 云块选型,钉清 Rook/CSI 编排层缺口;定义 CSI RPC、sidecar、Operator/CRD、数据面归属、升级闸门五条坐标系,给出 16 篇阅读路线与 PVC Bound 之后 I/O 仍走 krbd→PG→BlueStore 的边界。
【Rook / CSI】Rook Operator 与 CRD:CephCluster 所有权边界
把 Rook 写成 Kubernetes Operator:钉 CephCluster、CephBlockPool、CephFilesystem、CephObjectStore 等核心 CRD 的职责;划清 reconcile 所有权与 rook-ceph 默认命名空间;明确 Rook 不重写 RADOS 内核,并讨论 Operator 边界与 Driver CR 所有权争论。
【Rook / CSI】RBD 供给路径:StorageClass 到 CreateVolume 到 image
拆解 Rook 默认 RBD CSI 如何把 StorageClass 参数与 Secret 转成 CreateVolume,再落到 Format 2 image;钉死 provisioner 命名前缀、池与 imageFeatures 边界,并外链 ceph/12 的对象命名——不重写 BlueStore。
【Rook / CSI】挂载与 features:NodeStage、krbd 错位与 read affinity
拆解 RBD 的 NodeStageVolume/NodePublishVolume、map 路径与 imageFeatures 对 krbd 的依赖;说明失败为何常表现为挂上但怪;钉死 csi.readAffinity 与 Tentacle v20.2.0 损坏警告,并简述 network fencing。