从 2015 年的 Jewel 版本开始, Ceph 引入了 RBD 的 Mirror 功能, 其主要目的是对 Ceph 进行异地防灾备份和故障自动恢复.


Table of Contents

  1. Ceph RBD 镜像
    1. 开启日志功能
    2. Pool 配置
    3. Image 配置
  2. 配置 Ceph 集群之间的镜像
    1. 配置单向镜像模式
      1. 配置 Pool 镜像模式
      2. 配置 Image 镜像模式
    2. 配置双向镜像模式
      1. 配置 Pool 镜像模式
      2. 配置 Image 镜像模式
      3. 在相同名字的集群之间配置镜像
    3. 延迟副本模式
  3. 利用 Ceph 集群镜像进行灾难数据恢复
    1. 从一次正常关机进行故障转移
    2. 从一次非正常关机进行故障转移
    3. 故障恢复
    4. 利用镜像更新实例
  4. OpenStack 实现

Ceph RBD 镜像

RBD 的镜像功能是一种在两个及以上 Ceph 集群间异步副本功能。 镜像功能保证了对一个 iamge 做的更改在所有副本上保持时间点的一致性, 包括读写、块设备大小调整、快照、克隆和扁平化等等。镜像功能可以以 主-备主-主两种模式运行。使用强制的独占锁和 RBD 的日志功能, RBD 顺序记录了对一个 image 做的所有操作。 这保证了远端的镜像有一个灾难一致性的镜像可以使用。因此, 在镜像一个 image 之前, 必须要启用它的日志功能。

要保证 镜像功能 可用,本地和远端的CRUSH 架构最好要保持一致的容量和性能特征,此外还要两者之间的网络带宽要足够, 网络延迟要尽可能小以避免超时。

  1. rbd-mirror 守护进程
    RBD的镜像功能是由 rbd-mirror 守护进程实现的,其负责将 images 从一个 Ceph 集群同步到另一个。 根据副本类型, rbd-mirror 运行在单个或所有参与镜像的集群上。
  • 单向副本。 数据从一个主集群同步到一个或多个备份集群上, rbd-mirror只运行在备份集群上。 在active-passive模式下, RBD 镜像有多个备份站点。
  • 双向副本。 数据在两个Ceph集群之间互相同步,不分主次。 两个集群都必须运行 rbd-mirror。 目前,这种双向副本,或者主-主模式,只支持在两个站点之间同步。
    rbd-mirrorrbd-mirror 包提供。 每个 Ceph 集群只能有一个 rbd-mirror 在运行。
  1. 镜像模式
    RBD 镜像是基于 Pool 的。 Ceph 支持两种模式, 由一个 Pool 中的哪些 images 镜像决定。
  • Pool 模式。 这种模式下,Pool内的所有 images 都必须启用日志功能。
  • Image 模式。只有 Pool 中开启日志功能的 images 才会被镜像。在 主-备 模式下,被镜像的 images 有两种状态:
  • 主:可以被修改
  • 备:不可以被修改
    image 在被设置成 mirroring 模式时,就自动进入 状态。 将 状态降级或将升级都是可能的。

开启日志功能

我们可以在新建一个 image 时或已经存在的 image 上开启 日志 特性, 同时要开启的还有 独占锁 特性。

1
2
3
4
5
6
7
8
## Usage: when creating a new image
[ceph@ceph0 ~]$ rbd create {pool-name}/{image-name} --size {image-size} --image-feature {feature-name}
## e.g.
[ceph@ceph0 ~]$ rbd create volumes/data --size 1024 --image-feature exclusive-lock,journaling
## Usage: on an existing image
[ceph@ceph0 ~]$ rbd feature enable {pool-name}/{image-name} {feature-name}
## e.g.
[ceph@ceph0 ~]$ rbd feature enable volumes/data exclusive-lock,journaling

要是想让所有新建的 image 都开启 journaling 特性, 将下面的徽墨加到 Ceph 配置里面:

1
rbd default feature = 125

Pool 配置

以下的操作需要在所有的 同等集群上进行。

  1. 启用 Pool 的 镜像功能
1
2
3
4
5
6
## Usage
[ceph@ceph0 ~]$ rbd mirror pool enable {pool-name} {mode}
## e.g. enable pool mode
[ceph@ceph0 ~]$ rbd mirror pool enable volumes pool
## e.g. enble image mode
[ceph@ceph0 ~]$ rbd mirror pool enable volumes image
  1. 禁用 Pool 的 镜像功能
1
2
3
4
## Usage
[ceph@ceph0 ~]$ rbd mirror pool disable {pool-name}
## e.g.
[ceph@ceph0 ~]$ rbd mirror pool disable volumes

在禁用 镜像功能前, 要移除 Peer 集群。 禁用 Pool 的镜像功能,也就禁用了所有 images 的镜像功能。
3. 增加一个集群 Peer

1
2
3
4
5
## Usage
[ceph@ceph0 ~]$ rbd mirror pool peer add {pool-name} {client-name}@{cluster-name}
## e.g.
[ceph@ceph0 ~]$ rbd --cluster local mirror pool peer add data client.remote@remote
[ceph@ceph0 ~]$ rbd --cluster remote mirror pool peer add data client.local@local
  1. 查看 Peer 信息
1
2
3
4
5
6
7
8
## Usage
[ceph@ceph0 ~]$ rbd mirror pool info {pool-name}
## e.g.
[ceph@ceph0 ~]$ rbd mirror pool info data
Enabled: true
Peers:
UUID NAME CLIENT
peer-uuid ceph-remote client.admin
  1. 移除一个 Peer
1
[ceph@ceph0 ~]$ rbd mirror pool peer remove {pool-name} {peer-uuid}

需要明确指定 Pool 名字和 Peer 的 UUID。
6. 获取 Pool 的 镜像状态

1
2
3
4
5
6
## Usage
[ceph@ceph0 ~]$ rbd mirror pool status {pool-name}
## e.g.
[ceph@ceph0 ~]$ rbd mirror pool status data
health: OK
imges: 1 total

想要更多信息, 可加上 --verbose 选项。

Image 配置

image 模式下,下面的操作只在一个集群上运行。

  1. 启用 image 镜像对一个 image 启用镜像:
  • 在所有的 peer 集群上对所在的 Pool 启用镜像功能。
  • 显示指定该 image 启用镜像功能。
1
2
3
4
## Usage
[ceph@ceph0 ~]$ rbd mirror image enable {pool-name}/{image-name}
## e.g.
[ceph@ceph0 ~]$ rbd mirror image enable volumes/data
  1. 禁用 image 镜像功能
1
2
3
4
## Usage
[ceph@ceph0 ~]$ rbd mirror image disable {pool-name}/{image-name}
## e.g.
[ceph@ceph0 ~]$ rbd mirror image disable volumes/data
  1. Image 升级与降级
1
2
3
4
5
6
7
8
9
10
11
### DEMOTION
## Usage
[ceph@ceph0 ~]$ rbd mirror image demote {pool-name}/{image-name}
## e.g.
[ceph@ceph0 ~]$ rbd mirror image demote volumes/data

### PROMOTION
## Usage
[ceph@ceph0 ~]$ rbd mirror image promote {pool-name}/{image-name}
## e.g.
[ceph@ceph0 ~]$ rbd mirror image promote volumes/data

这一操作主要是用在 灾难恢复 中.
当降级不能传递到 peer 集群时,利用 --force 选项强制升级一个 image, 例如由于集群错误或者交流超时等等。
4. Image 重新同步

1
2
3
4
## Usage
[ceph@ceph0 ~]$ rbd mirror image resync {pool-name}/{image-name}
## e.g.
[ceph@ceph0 ~]$ rbd mirror image resync volumes/data

当两个集群之间数据不一致时, rbd-mirror 不会试图去镜像导致不一致的 image。 这时可用 resync 来重新同步。
5. 获取单个 image 的镜像状态

1
2
3
4
5
6
7
8
9
## Usage
[ceph@ceph0 ~]$ rbd mirror image status {pool-name}/{image-name}
## e.g.
[ceph@ceph0 ~]$ rbd mirror image status volumes/data
data:
global_id: image-uuid
state: up+replaying
description: some description here
last_update: time last update

配置 Ceph 集群之间的镜像

配置单向镜像模式

单向镜像模式即一个主集群同步副本到一个或多个次级集群. 主集群镜像牌 主(primary) 模式; 次级集群镜像处于 非主(non-primary) 模式, 只能读,不能写. 单向模式适合维护一个镜像的灾难一致性副本, 但不适合与 OpenStack结合时次级集群镜像的自动灾难重建等情况,这时需要双向模式.

  • 两个正在运行的 Ceph 集群: 将镜像从 local 集群备份到 remote 集群. 配置文件分别为 local.confremote.conf. 若两个集群名字相同, 需要做额外的工作. 见 在相同名字的集群之间配置镜像
  • 一个能够连接到 local 集群的客户端 - client.local.
  • 在两个集群上创建相同的 pool, 比如 volumes.
  • 想要镜像的 pool - volumes 中有想要镜像的 image, 并且 journaling 功能已经启用.
    前面说过, 有两种镜像块设备的方式:
  • Pool 镜像模式
  • Image 镜像模式

配置 Pool 镜像模式

  1. 保证 volumes 中的所有 images 都开启了 exclusive lockjournaling 特性.
  2. 在 remote 集群上的 monitor 节点上, 安装 rbd-mirror. 确保集群中只有一个 rbd-mirror 实例运行.
1
[ceph@ceph0 ~]$ sudo yum install -y rbd-mirror
  1. 在两个 集群上, 使用 CLUSTER 特别指定参与镜像的两个集群名字.
1
2
CLUSTER=local
CLUSTER=remote
  1. 在两个集群上, 创建能够访问 volumes 池的客户端, 并存储它们的 keyring 到 <cluster-name>.client.<user-name>.keyring.
  • 在 local 集群的 monitor 节点, 创建 client.local.
1
[ceph@ceph0 ~]$ ceph auth get-or-create client.local 'profile rbd' osd 'profile rbd pool=volumes' -o /etc/ceph/ceph.client.local.keyring --cluster local
  • 在 remote 集群的 monitor 节点, 创建 client.remote.
1
[ceph@ceph0 ~]$ ceph auth get-or-create client.remote 'profile rbd' osd 'profile rbd pool=volumes' -o /etc/ceph/ceph.client.remote.keyring --cluster remote
  1. local 集群上的 Ceph 配置文件和 新生成的 keyring 文件 拷贝到 remote 集群和 remote 集群的客户端节点上.
1
2
3
4
5
[ceph@ceph0 ~]$ scp /etc/ceph/local.conf <user>@<remote_mon_host-name>:/etc/ceph/
[ceph@ceph0 ~]$ scp /etc/ceph/ceph.client.local.keyring <user>@<remote_mon-host-name>:/etc/ceph/

[ceph@ceph0 ~]$ scp /etc/ceph/local.conf <user>@<remote_client-host-name>:/etc/ceph/
[ceph@ceph0 ~]$ scp /etc/ceph/ceph.client.local.keyring <user>@<remote_client-host-name>:/etc/ceph/
  1. 在 remote 集群的 monitor 节点上, 启用并启动 rbd-mirror 守护进程.
1
2
[ceph@ceph-remote ~]$ sudo systemctl enable ceph-rbd-mirror.target
[ceph@ceph-remote ~]$ sudo systemctl enable --now ceph-rbd-mirror@<client-id>

这里, <client-id> 是指的 rbd-mirror 运行使用的用户, 此处即 remote.
7. 在 local 和 remote 两个集群上启用 pool mirroring.

1
2
[ceph@ceph0 ~]$ rbd mirror pool enable volumes pool --cluster local
[ceph@ceph0 ~]$ rbd mirror pool enable volumes pool --cluster remote

确保 local 和 remote 集群的 mirroring 功能已成功启用.

1
2
[ceph@ceph0 ~]$ rbd mirror pool info volumes --cluster local
[ceph@ceph0 ~]$ rbd mirror pool info volumes --cluster remote
  1. 将 local 集群加入到 remote 集群的 peer 中.
1
2
3
4
5
6
[ceph@ceph0 ~]$ rbd mirror pool peer add volumes client.local@local --cluster remote
[ceph@ceph0 ~]$ rbd mirror info volumes --cluster remote
Mode: pool
Peers:
UUID NAME CLIENT
local-cluster-uuid local client.local

配置 Image 镜像模式

  1. 确保需要 镜像的 images 开启了 exclusive lockjournaling 特性.
  2. 依循 配置 Pool 镜像模式 中的 2-5 步.
  3. 开启 local 集群上 volumes 的 image 镜像功能.
1
2
[ceph@ceph0 ~]$ rbd --cluster local mirror pool enable volumes image
[ceph@ceph0 ~]$ rbd mirror pool info --cluster local
  1. 将 local 集群 加到 remote 集群的 peer 中.
1
2
3
4
5
6
[ceph@ceph0 ~]$ rbd --cluster remote mirror pool peer add volumes client.local@local
[ceph@ceph0 ~]$ rbd --cluster remote mirror pool info
Mode: pool
Peers:
UUID NAME CLIENT
local-cluster-uuid local client.local
  1. local 集群上, 显示启用 images 如 image1 的 image 镜像功能.
1
[ceph@ceph0 ~]$ rbd --cluster local mirror image enable volumes/image1

确保镜像功能已经成功启用.

1
2
3
4
5
6
7
8
9
10
11
12
[ceph@ceph0 ~]$ rbd mirror image status volumes/image1 --cluster local
image1:
global_id: image-uuid
state: up+replayingn
description: replaying, master_position=[xxxxx], mirror_position=[xxxxx], entries_behind_master=0
last_update: last_update_time
[ceph@ceph0 ~]$ rbd mirror image status volumes/image1 --cluster remote
image1:
global_id: image-uuid
state: up+replayingn
description: replaying, master_position=[xxxxx], mirror_position=[xxxxx], entries_behind_master=0
last_update: last_update_time

配置双向镜像模式

配置双向模式的下列步骤假定:

  • 有两个正在运行的 Ceph 集群 - localremote, 相应的配置文件在 /etc/ceph/local.conf/etc/ceph/remote.conf. 如果两个集群名字相同, 需要做额外的工作, 见 在相同名字的集群之间配置镜像
  • 有一个 块设备 客户端连接到两个集群 - client.localclient.remote.
  • 要镜像的 Pool - volumes 在两个集群中都有.
  • 要镜像的 Pool volumes 包含着要镜像的 images, 要开启了 journaling 特性.

配置 Pool 镜像模式

  1. 在双方客户端上, 安装 rbd-mirror.
1
[ceph@ceph0 ~]$ sudo yum install -y rbd-mirror
  1. 在双方客户端节点上, 在 /etc/sysconfig/ceph 里用 CLUSTER 特别指定集群名字.
1
2
CLUSTER=local
CLUSTER=remote
  1. 在双方集群上,创建能够访问 volumes 的客户端并输出其 keyring.
  • 在 local 集群的 monitor 节点上, 创建 client.local.
1
[ceph@ceph0 ~]$ ceph auth get-or-create client.local mon 'profile rbd' osd 'profile rbd pool=volumes' -o /etc/ceph/local.client.local.keyring --cluster local
  • 在 remote 集群的 monitor 节点上, 创建 client.remote.
1
[ceph@ceph0 ~]$ ceph auth get-or-create client.remote mon 'profile rbd' osd 'profile rbd pool=volumes' -o /etc/ceph/local.client.remote.keyring --cluster remote
  1. 拷贝双方的 Ceph 配置文件和生成的 keyring 拷贝到对方的 monitor 节点上.
  • 拷贝 local.conflocal.client.local.keyring 到 remote 集群的 monitor 节点上.
1
2
[ceph@ceph-local ~]$ scp /etc/ceph/local.conf ceph@ceph-remote:/etc/ceph
[ceph@ceph-local ~]$ scp /etc/ceph/local.client.local.keyring ceph@ceph-remote:/etc/ceph
  • 拷贝 remote.confremote.client.remote.conf 到 local 集群的 monitor 节点上.
1
2
[ceph@ceph-local ~]$ scp ceph@ceph-remote:/etc/ceph/remote.conf /etc/ceph/
[ceph@ceph-local ~]$ scp ceph@ceph-remote:/etc/ceph/remote.client.remote.keyring /etc/ceph/
  1. 如果 local 集群上 monitor 跟 mirroring 守护进程不在=同一个节点上, 需要 拷贝 local.client.local.keyring 到运行 rbd-mirroring 的节点上. remote 集群也一样.
1
2
[ceph@ceph-local ~]$ scp /etc/ceph/local.client.local.keyring ceph@ceph-local-mirror:/etc/ceph/
[ceph@ceph-remote ~]$ scp /etc/ceph/remote.client.remote.keyring ceph@ceph-remote-mirror:/etc/ceph/
  1. 在双方客户端节点上, 启用并启动 rbd-mirror守护进程.
1
2
[ceph@ceph0 ~]$ sudo systemctl enable ceph-rbd-mirror.target
[ceph@ceph0 ~]$ sudo systemctl enable --now ceph-rbd-mirror@<client-id>

<client-id> 这里即 local, remote.
7. 启用两个集群 volumes 上的 pool mirroring, 并确保启用成功.

1
2
3
4
[ceph@ceph0 ~]$ rbd mirror pool enable volumes pool --cluster local
[ceph@ceph0 ~]$ rbd mirror pool enable volumes pool --cluster remote
[ceph@ceph0 ~]$ rbd mirror pool status volumes --cluster local
[ceph@ceph0 ~]$ rbd mirror pool status volumes --cluster remote
  1. 将双方互相加为 peer, 并确保添加成功.
1
2
3
4
5
[ceph@ceph0 ~]$ rbd mirror pool peer add volumes client.local@local --cluster remote
[ceph@ceph0 ~]$ rbd mirror pool peer add volumes client.remote@remote --cluster local
[ceph@ceph0 ~]$ rbd mirror pool info volumes --cluster local
...
[ceph@ceph0 ~]$ rbd mirror pool info volumes --cluster remote

配置 Image 镜像模式

  1. 依循 配置 Pool 镜像模式 中的1-5 步.
  2. 在双方的 volumes pool 上启用 image 镜像模式, 并确保成功.
1
2
3
4
[ceph@ceph0 ~]$ rbd --cluster local mirror pool enable volumes image
[ceph@ceph0 ~]$ rbd --cluster remote mirror pool enable volumes image
[ceph@ceph0 ~]$ rbd --cluster local mirror pool status volumes
[ceph@ceph0 ~]$ rbd --cluster remote mirror pool status volumes.
  1. 互相添加为 peer, 并确保成功.
1
2
3
4
[ceph@ceph0 ~]$ rbd mirror pool peer add volumes client.local@local --cluster remote
[ceph@ceph0 ~]$ rbd mirror pool peer add volumes client.remote@remote --cluster local
[ceph@ceph0 ~]$ rbd mirror pool info --cluster local
[ceph@ceph0 ~]@ rbd mirror pool info --cluster remote
  1. 在主集群上, 显示启用 images image1 的 image 镜像功能.
1
2
3
4
5
[ceph@ceph0 ~]$ rbd --cluster local mirror image enable volumes/image1
[ceph@ceph0 ~]$ rbd --cluster local mirror image status volumes/image1
...
[ceph@ceph0 ~]$ rbd --cluster remote mirror image status volumes/image1
...

在相同名字的集群之间配置镜像

有时候集群管理者会使用相同的名字,一般是 ceph 创建集群. 当两个集群名字相同时, 目前要执行如下的步骤.

  1. rbd-mirror 执行一端的集群上的 /etc/sysconfig/ceph 中更改集群的名字如 master.
  2. 同时建立一个指向 ceph.conf 的符号链接.
1
[ceph@ceph0 ~]$ ln -sf /etc/ceph/ceph.conf /etc/ceph/master.conf
  1. 使用每次 rbd-mirror 配置过程中都使用 符号链接文件 master.conf.
1
2
[ceph@ceph0 ~]$ ceph -s
[ceph@ceph0 ~]$ ceph -s --cluster master

现在两个命令都指向同一个集群.

延迟副本模式

无论使用单向还是双向副本模式, 我们都可以在 RBD image 镜像时设置延迟,这样我们就有一个时间窗口来撤销一些作用在主要 iamge 上的并不想要的改变。要实现这样的延迟副本, 目标集群上的 rbd-mirror 守护进程需要设置 rbd mirroring replay delay = {minimum delay in seconds}。这可以通过 ceph.conf 作用在所有 Pools 上, 也可以单独作用在 一些 images 上。

1
2
3
4
## Usage
[ceph@ceph0 ~]$ rbd image-meta set {pool-name}/{image-name} conf_rbd_mirroring_replay_delay {minimum delay in seconds}
## e.g.
[ceph@ceph0 ~]$ rbd image-meta set volumes/data conf_rbd_mirroring_replay_delay 600

利用 Ceph 集群镜像进行灾难数据恢复

从一次正常关机进行故障转移

  1. 关掉所有正在使用 主 image 的客户端. 这取决于哪种客户端在使用 image.
  2. 将 local集群上的 主 image 降级.
1
[ceph@ceph0 ~]$ rbd mirror image demote {pool-name}/{image-name} --cluster local
  1. 将 remote 集群的 非主 image 升级.
1
[ceph@ceph0 ~]$ rbd mirror image promote {pool-name}/{image-name} --cluster remote
  1. 重新让客户端连接新的 主 image. 同样取决于使用的客户端.

从一次非正常关机进行故障转移

  1. 确认主集群(local cluster) 已经关闭.
  2. 停止所有使用主 image 的客户端. 这取决于哪种客户端在使用 image.
  3. 将远端的 非主状态的 image 升级为主 image, 使用 --force选项.
1
[ceph@ceph0 ~]$ rbd mirror image promote --force {pool-name}/{image-name} --cluster remote
  1. 重新让客户端连接新的 主 image. 同样取决于使用的客户端.

故障恢复

当以前的主集群恢复后, 需要行故障恢复.

  1. 如果是非正常关机, 将 local 集群上的旧的主 image 降级.
1
[ceph@ceph0 ~]$ rbd mirror image demote {pool-name}/{image-name} --cluster local
  1. 只有在非正常关机时才重新同步 image.
1
[ceph@ceph0 ~]$ rbd mirror image resync {pool-name}/{image-name} --cluster local
  1. 保证 重新同步 完成, 并处于 up+replaying 状态.
1
[ceph@ceph0 ~]$ rbd mirror image status {pool-name}/{image-name} --cluster local
  1. 将次级集群上的 image 降级.
1
[ceph@ceph0 ~]$ rbd mirror image demote {pool-name}/{image-name} --cluster remote
  1. 将主集群上的 image 升级.
1
[ceph@ceph0 ~]$ rbd mirror image promote {pool-name}{image-name} --cluster local

利用镜像更新实例

…to.be.continued…

OpenStack 实现

…to.be.continued…