RBD Mirror 是 Ceph 块存储(RBD)的一项功能,支持不同 Ceph 集群之间的异步数据复制,实现跨集群的灾难恢复(DR)。其核心功能是以主备模式同步数据,确保主集群故障时备份集群能够快速接管服务。
启用 Primary 集群块存储池镜像功能
在 Primary 集群的 Control 节点执行以下命令:
kubectl -n rook-ceph patch cephblockpool <block-pool-name> \
--type merge -p '{"spec":{"mirroring":{"enabled":true,"mode":"image"}}}'
cephblockpool.ceph.rook.io/<block-pool-name> patched
参数说明:
<block-pool-name>:块存储池名称。
获取 Peer Token
该令牌是建立集群镜像连接的关键凭证。
在 Primary 集群的 Control 节点执行以下命令:
kubectl get secret -n rook-ceph \
$(kubectl get cephblockpool.ceph.rook.io <block-pool-name> -n rook-ceph -o jsonpath='{.status.info.rbdMirrorBootstrapPeerSecretName}') \
-o jsonpath='{.data.token}' | base64 -d
# 输出因敏感信息被截断
eyJmc2lkIjoiMjc2N2I3ZmEtY2YwYi00N...
参数说明:
<block-pool-name>:块存储池名称。
在 Secondary 集群创建 Peer Token Secret
在 Secondary 集群的 Control 节点执行以下命令:
kubectl -n rook-ceph create secret generic rbd-primary-site-secret \
--from-literal=token=<token> \
--from-literal=pool=<block-pool-name>
secret/rbd-primary-site-secret created
参数说明:
<token>:从步骤 2获取的令牌。
<block-pool-name>:块存储池名称。
启用 Secondary 集群块存储池镜像功能
在 Secondary 集群的 Control 节点执行以下命令:
kubectl -n rook-ceph patch cephblockpool <block-pool-name> --type merge -p \
'{
"spec": {
"mirroring": {
"enabled": true,
"mode": "image",
"peers": {
"secretNames": [
"rbd-primary-site-secret"
]
}
}
}
}'
cephblockpool.ceph.rook.io/<block-pool-name> patched
参数说明:
<block-pool-name>:块存储池名称。
在 Secondary 集群部署 Mirror Daemon
该守护进程负责监控和管理 RBD 镜像同步进程,包括数据同步和错误处理。
在 Secondary 集群的 Control 节点执行以下命令:
cat << EOF | kubectl apply -f -
apiVersion: ceph.rook.io/v1
kind: CephRBDMirror
metadata:
name: rbd-mirror
namespace: rook-ceph
spec:
count: 1
EOF
cephrbdmirror.ceph.rook.io/rbd-mirror created
验证镜像状态
在 Secondary 集群的 Control 节点执行以下命令:
kubectl get cephblockpools.ceph.rook.io <block-pool-name> -n rook-ceph -o jsonpath='{.status.mirroringStatus.summary}'
# 所有 "OK" 状态表示运行正常
{"daemon_health":"OK","health":"OK","image_health":"OK","states":{}}
参数说明:
<block-pool-name>:块存储池名称。
启用 Replication Sidecar
该功能支持高效的数据复制和同步,且不会中断主应用操作,提升系统的可靠性和可用性。
- 部署 csiaddons-controller
在 Primary 和 Secondary 集群的 Control 节点执行以下命令:
点击查看
kubectl create -f https://raw.githubusercontent.com/csi-addons/kubernetes-csi-addons/v0.5.0/deploy/controller/crds.yaml
kubectl create -f https://raw.githubusercontent.com/csi-addons/kubernetes-csi-addons/v0.5.0/deploy/controller/rbac.yaml
cat << EOF | kubectl apply -f -
apiVersion: v1
data:
controller_manager_config.yaml: |
apiVersion: controller-runtime.sigs.k8s.io/v1alpha1
kind: ControllerManagerConfig
health:
healthProbeBindAddress: :8081
metrics:
bindAddress: 127.0.0.1:8080
webhook:
port: 9443
leaderElection:
leaderElect: true
resourceName: e8cd140a.openshift.io
kind: ConfigMap
metadata:
name: csi-addons-manager-config
namespace: csi-addons-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: csi-addons
name: csi-addons-controller-manager
namespace: csi-addons-system
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: csi-addons
template:
metadata:
annotations:
kubectl.kubernetes.io/default-container: manager
labels:
app.kubernetes.io/name: csi-addons
spec:
containers:
- args:
- --secure-listen-address=0.0.0.0:8443
- --upstream=http://127.0.0.1:8080/
- --logtostderr=true
- --v=10
image: <registry>/brancz/kube-rbac-proxy:v0.8.0
name: kube-rbac-proxy
ports:
- containerPort: 8443
name: https
protocol: TCP
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 10m
memory: 64Mi
- args:
- --health-probe-bind-address=:8081
- --metrics-bind-address=127.0.0.1:8080
- --leader-elect
command:
- /manager
image: <registry>/csiaddons/k8s-controller:v0.5.0
livenessProbe:
httpGet:
path: /healthz
port: 8081
initialDelaySeconds: 15
periodSeconds: 20
name: manager
readinessProbe:
httpGet:
path: /readyz
port: 8081
initialDelaySeconds: 5
periodSeconds: 10
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 10m
memory: 64Mi
securityContext:
allowPrivilegeEscalation: false
securityContext:
runAsNonRoot: true
serviceAccountName: csi-addons-controller-manager
terminationGracePeriodSeconds: 10
EOF
参数说明:
- 启用 csi sidecar
在 Primary 和 Secondary 集群的 Control 节点执行以下命令:
kubectl patch cm rook-ceph-operator-config -n rook-ceph --type json --patch \
'[
{
"op": "add",
"path": "/data/CSI_ENABLE_OMAP_GENERATOR",
"value": "true"
},
{
"op": "add",
"path": "/data/CSI_ENABLE_CSIADDONS",
"value": "true"
}
]'
创建 VolumeReplicationClass
在 Primary 和 Secondary 集群的 Control 节点执行以下命令:
cat << EOF | kubectl apply -f -
apiVersion: replication.storage.openshift.io/v1alpha1
kind: VolumeReplicationClass
metadata:
name: rbd-volumereplicationclass
spec:
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
mirroringMode: snapshot
schedulingInterval: "<scheduling-interval>"
replication.storage.openshift.io/replication-secret-name: rook-csi-rbd-provisioner
replication.storage.openshift.io/replication-secret-namespace: rook-ceph
EOF
volumereplicationclass.replication.storage.openshift.io/rbd-volumereplicationclass created
<scheduling-interval>:调度间隔(例如,schedulingInterval: "1h" 表示每小时执行一次)。
为 PVC 启用镜像功能
在 Primary 集群的 Control 节点执行以下命令:
cat << EOF | kubectl apply -f -
apiVersion: replication.storage.openshift.io/v1alpha1
kind: VolumeReplication
metadata:
name: <vr-name>
namespace: <namespace>
spec:
autoResync: false
volumeReplicationClass: rbd-volumereplicationclass
replicationState: primary
dataSource:
apiGroup: ""
kind: PersistentVolumeClaim
name: <pvc-name>
EOF
volumereplication.replication.storage.openshift.io/<mirror-pvc-name> created
<vr-name>:VolumeReplication 对象名称,建议与 PVC 名称相同。
<namespace>:VolumeReplication 所属命名空间,必须与 PVC 命名空间一致。
<pvc-name>:需要启用镜像的 PVC 名称。
注意
启用后,Secondary 集群中的 RBD 镜像将变为只读。