- 云原生
- 存储
- 容器编排
- 运维
【免费下载链接】rook
Storage Orchestration for Kubernetes
Rook 通过自定义资源定义(CRD)CephRBDMirror允许用户以声明式方式创建和更新 rbd-mirror 守护进程,从而在两个 Ceph 集群之间实现 RBD(块设备)镜像的异步复制。本文基于仓库中的 ceph-rbd-mirror-crd.md 展开,并结合 Rook 操作器源码与部署示例,系统讲解CephRBDMirror的字段含义、最小部署、完整配置示例、镜像对等体的配置方法以及底层控制器的工作机制,帮助你快速上手基于 Rook 的 RBD 跨集群灾备方案。
背景:什么是 RBD 镜像,为什么要用 CephRBDMirror
RBD 镜像是 Ceph 提供的一种块级异步复制机制:主集群(primary)中写入的 RBD 镜像数据会被持续、异步地复制到对端集群(secondary/peer),实现跨集群的数据冗余与灾难恢复。在 Kubernetes 环境中,Rook 将这一能力封装为CephRBDMirror自定义资源,操作器(rook-ceph operator)负责在集群中创建并维护 rbd-mirror 守护进程的 Deployment、Service、ConfigMap 等相关资源。
从 API 定义看,CephRBDMirror属于ceph.rook.io/v1组,并注册了短名cephrbdm,同时支持.status.phase列输出(见 pkg/apis/ceph.rook.io/v1/types.go):
// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase` // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` // +kubebuilder:subresource:status // +kubebuilder:resource:shortName=cephrbdm type CephRBDMirror struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata"` Spec RBDMirroringSpec `json:"spec"` Status *RBDMirrorStatus `json:"status,omitempty"` }关于 RBD 镜像的用户管理、能力(capabilities)与 Ceph 层面的概念细节,请参考 Ceph 官方关于 rbd-mirroring 的文档(本文聚焦 Rook 的 CRD 用法)。
快速开始:创建一个最小 CephRBDMirror
以下是一个最简单的示例,部署 1 个 rbd-mirror 守护进程:
apiVersion: ceph.rook.io/v1 kind: CephRBDMirror metadata: name: my-rbd-mirror namespace: rook-ceph spec: count: 1应用后,操作器会在rook-ceph命名空间内创建对应的 Deployment,副本数即count的值。仓库自带的示例文件 deploy/examples/rbdmirror.yaml 给出了可kubectl create -f直接使用的完整版本。
前置条件
- 已按官方 Quickstart guide 创建好一个可用的 Rook Ceph 集群;
- 集群中已安装
ceph.rook.io/v1的 CRD(由 Rook operator 安装,示例见 deploy/examples/crds.yaml); - 两个集群之间的网络可达,并且已互相交换镜像对等信息(peer token,见下文"配置镜像对等体")。
CephRBDMirror 完整配置字段解析
如果某个字段未指定,Rook 会自动使用合适的默认值。完整的可用字段定义在 pkg/apis/ceph.rook.io/v1/types.go 的RBDMirroringSpec中,同时 deploy/examples/rbdmirror.yaml 提供了带注释的实战样例。
metadata:名称与命名空间
name:CephRBDMirror 资源的名称,用于标识该 rbd-mirror 守护进程组,也是生成下属资源名称的依据。namespace:Rook 集群所在的 Kubernetes 命名空间。操作器创建的服务、Pod 及其他资源都会放入该命名空间,通常与CephCluster同命名空间(如rook-ceph)。
spec:RBDMirror 设置
spec下各字段含义如下:
| 字段 | 类型 | 说明 | 默认行为 |
|---|---|---|---|
count | int | 要运行的 rbd-mirror 实例数量 | 必填,最小值 1(CRD 校验Minimum=1) |
peers | object | 对等体配置,见下文"配置镜像对等体" | 可选 |
placement | object | 标准 Kubernetes 调度约束:nodeAffinity、tolerations、podAffinity、podAntiAffinity,用法与 CephCluster CRD 中 daemon 的 placement 一致 | 默认放置到任意可用节点 |
annotations | map | 要添加到 Pod 相关对象上的键值对注解 | 可选 |
labels | map | 要添加到 Pod 相关对象上的键值对标签 | 可选 |
resources | object | rbd-mirror Pod 的资源请求与限制(requests/limits) | 可选 |
priorityClassName | string | 设置到 rbd-mirror Pod 上的 PriorityClass 名称 | 可选 |
完整示例(取自 deploy/examples/rbdmirror.yaml):
apiVersion: ceph.rook.io/v1 kind: CephRBDMirror metadata: name: my-rbd-mirror namespace: rook-ceph # namespace:cluster spec: # 要部署的 rbd-mirror 守护进程数量 count: 1 # 存放 peer token 的 Kubernetes Secret 名称列表 # 关于 bootstrap peers 的更多细节见 Ceph 官方文档 #peers: # secretNames: # - secondary-cluster-peer # 应用到 rbd-mirror Deployment 的亲和性规则 placement: # nodeAffinity: # requiredDuringSchedulingIgnoredDuringExecution: # nodeSelectorTerms: # - matchExpressions: # - key: role # operator: In # values: # - rbd-mirror-node # tolerations: # - key: rbd-mirror-node # operator: Exists # podAffinity: # podAntiAffinity: # 键值对形式的注解列表 annotations: # key: value resources: # requests 与 limits,例如允许 rbd-mirror Pod 使用半个 CPU 核心和 1GiB 内存 limits: memory: "1Gi" requests: cpu: "500m" memory: "1Gi" # priorityClassName: my-priority-class字段的实际生效路径(源码视角)
从控制器实现看,spec中各个字段会直接映射到底层 Deployment 的构建过程。在 pkg/operator/ceph/cluster/rbd/spec.go 的makeDeployment中:
count被转换为 Deployment 的Replicas(replicas := int32(rbdMirror.Spec.Count));placement通过rbdMirror.Spec.Placement.ApplyToPodSpec(&podSpec.Spec)应用到 Pod 模板;annotations/labels分别应用到 Pod 模板对象元数据与 Deployment 对象元数据;priorityClassName直接写入 Pod 模板的PriorityClassName;- 同时还会自动追加不可达节点容忍(
AddUnreachableNodeToleration),若集群开启了日志采集(LogCollector.Enabled)则会注入日志收集 sidecar 容器,镜像守护进程的日志文件过滤规则为*-client.rbd-mirror*。
配置镜像对等体(Mirroring Peers)
rbd-mirror 守护进程本身并不直接决定"镜像哪些数据、镜像到哪里"——真正的镜像策略(peer 关系、镜像模式)是在存储池级别配置的。Rook 将 peer 配置分别挂载到两类资源上:
- CephBlockPool:为每个块存储池单独配置镜像对等体,详见 CephBlockPool 文档 中的 mirroring 小节;
- CephBlockPoolRadosNamespace:为池内每个 RADOS 命名空间单独配置镜像对等体,详见 CephBlockPoolRadosNamespace 文档 中的 mirroring 小节。
在 CephRBDMirror 中引用 peer Secret
在CephRBDMirror的spec.peers.secretNames中列出包含 peer token 的 Kubernetes Secret 名称,操作器便会尝试将这些 Secret 中的对等信息引导(bootstrap)到守护进程。MirroringPeerSpec的定义如下(见 types.go):
// MirroringPeerSpec represents the specification of a mirror peer type MirroringPeerSpec struct { // SecretNames represents the Kubernetes Secret names to add rbd-mirror or cephfs-mirror peers SecretNames []string `json:"secretNames,omitempty"` }对应的辅助方法HasPeers()(见 pkg/apis/ceph.rook.io/v1/mirror.go)通过检查SecretNames是否非空来判断是否存在需要连接的 peer:
// HasPeers returns whether the RBD mirror daemon has peer and should connect to it func (m *MirroringPeerSpec) HasPeers() bool { return len(m.SecretNames) != 0 }在控制器协调流程中(见 pkg/operator/ceph/cluster/rbd/controller.go),操作器会先调用reconcileAddBootstrapPeer完成 peer 引导,再创建守护进程 Deployment。因此,如果使用池级镜像(pool mode),必须先通过CephBlockPool/CephBlockPoolRadosNamespace配置好 peer 与镜像模式,再部署或更新CephRBDMirror使守护进程接入对端集群。
在存储池上启用镜像(配套操作)
虽然CephRBDMirror只负责守护进程本身,但完整的镜像方案离不开池侧配置。在 deploy/examples/pool.yaml 中可以看到CephBlockPool的镜像与健康检查配置:
mirroring: enabled: false # 镜像模式:pool(池级)或 image(每镜像) # 更多细节见 Ceph 官方 rbd-mirroring 文档 mode: image # 指定快照的调度计划 # snapshotSchedules: # - interval: 24h # 每日快照 # startTime: 14:00:00-05:00 # 开启时上报池镜像状态 statusCheck: mirror: disabled: false interval: 60s对应 API 类型MirroringSpec(见 types.go)支持:
enabled:是否启用池镜像;mode:镜像模式,合法值为pool、image、init-only(CRD 枚举校验);snapshotSchedules:镜像快照调度计划,SnapshotScheduleSpec包含interval(周期,如24h)、startTime(起始时间,含时区偏移,如14:00:00-05:00)、path(仅 CephFS 有效);peers:池级 peer 配置。
当snapshotSchedules非空时,SnapshotSchedulesEnabled()返回 true(见 pool.go),操作器会据此创建对应的快照调度。
控制器工作原理:从 CR 到运行中的守护进程
CephRBDMirror由名为ceph-rbd-mirror-controller的 controller-runtime 控制器驱动(见 pkg/operator/ceph/cluster/rbd/controller.go)。它 watch 以下对象:
CephRBDMirrorCR 本身(变化触发协调);- 由该 CR 拥有的
Service、ConfigMap、Deployment(owned 资源变化时通过TypedEnqueueRequestForOwner触发父对象重新协调)。
每次Reconcile的核心步骤(见 controller.go):
- 获取并初始化状态:拉取
CephRBDMirror对象;若Status为空则初始化Cephx状态字段。 - 校验 spec:调用
validateSpec,不合法则立即重试并上报失败状态。 - 等待 CephCluster 就绪:如果同命名空间的
CephCluster尚未就绪,则延迟重试。 - 加载集群信息与版本检测:读取
ClusterInfo,对比运行中与期望的 Ceph 版本;若集群正处于升级过程中(mon 版本与期望版本不一致),则等待升级完成再继续,避免在升级窗口创建守护进程(外部集群模式除外)。 - 引导 peer:
reconcileAddBootstrapPeer将peers.secretNames指向的 Secret 中的对端 token 引导进守护进程。 - cephx 密钥轮换检查:根据
CephCluster的安全配置判断是否需要对守护进程密钥进行轮换。 - 创建/更新 Deployment:
reconcileCreateCephRBDMirror→start→makeDeployment,生成最终 Deployment 并应用到集群。 - 更新状态:将
Status.Phase置为 Ready,写入ObservedGeneration与 cephx 状态。
这一流程保证了 CR 声明与集群实际状态的一致性:修改count、placement、resources等字段后,操作器会自动滚动更新对应 Deployment,无需人工干预。
验证与运维建议
- 使用
kubectl -n rook-ceph get cephrbdm(或完整名cephrbdmirror)查看 CR 状态,其中Phase列反映协调结果; - 使用
kubectl -n rook-ceph get deployment -l app=rook-ceph-rbd-mirror检查守护进程副本是否就绪; - 池级镜像的健康状态可通过
CephBlockPool的statusCheck.mirror(默认每 60s 上报一次)配合 Ceph 监控体系 观察; - 排障时可借助 Ceph toolbox 执行
rbd mirror pool status <pool>查看对端状态与延迟。
小结
CephRBDMirror是 Rook 承载 RBD 跨集群异步镜像能力的核心 CRD:它以count声明守护进程规模,以placement/resources/annotations/labels/priorityClassName控制调度与资源,并通过peers.secretNames接入对端集群;而具体的镜像策略(模式、快照调度、peer 关系)由CephBlockPool与CephBlockPoolRadosNamespace在池级别配置。两者配合,即可在 Kubernetes 上构建一套声明式、可版本控制的 RBD 灾备复制方案。
- 云原生
- 存储
- 容器编排
- 运维
【免费下载链接】rook
Storage Orchestration for Kubernetes
相关推荐
Rook 中 CephFilesystemMirror CRD 完全指南:在 Kubernetes 上部署与配置 cephfs-mirror 异步复制守护进程
Rook 中 CephFilesystemMirror CRD 完全指南:在 Kubernetes 上部署与配置 cephfs mirror 异步复制守护进程
云原生存储容器编排运维Rook CephBlockPool CRD 完全指南:Ceph RBD 存储池的声明式配置、副本/纠删码与镜像实践
Rook CephBlockPool CRD 完全指南:Ceph RBD 存储池的声明式配置、副本/纠删码与镜像实践 导读 本文以 Rook 项目中的 Ceph
云原生存储容器编排运维FoundationDB Kubernetes Monitor 完全指南:在 Kubernetes 中启动与守护 fdbserver 进程
FoundationDB Kubernetes Monitor 完全指南:在 Kubernetes 中启动与守护 fdbserver 进程 导读 fdb kub
分布式数据库KV存储数据库后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考