为持久卷声明配置灾难恢复

要为 Application PVC 实现跨集群灾难恢复,请使用 Alauda Build of VolSync

概述

Alauda Build of VolSync 是一个 operator,用于在集群内或跨集群对持久卷进行异步复制。VolSync 提供的复制与底层存储系统无关,因此可以对通常不支持远程复制的存储类型进行双向复制。此外,它还可以在不同类型(以及不同厂商)的存储之间进行复制。

术语

术语说明
Primary Cluster活跃的生产站点。
Secondary Cluster备用恢复站点;保持待命状态,随时准备在发生灾难时接管。
Stateful Application使用 PVC 进行数据持久化的应用。
ReplicationSourceReplicationSource 是一个 VolSync 资源,可用于定义源 PVC 和复制 mover 类型,从而使你能够将 PVC 数据复制或同步到远程位置。
ReplicationDestinationReplicationDestination 是一个 VolSync 资源,可用于定义 VolSync 复制或同步的目标位置。
Data MoversVolSync 的 data mover 负责将数据从一个位置复制到另一个位置。

支持的 mover:
  • Rclone
  • Restic
  • Rsync

前提条件

  • 下载与你的平台架构对应的 Alauda Build of VolSync 安装包。
  • 使用上架软件包机制将 Alauda Build of VolSync 安装包上传到 Primary 和 Secondary 两个集群。
  • 两个集群都已部署 快照管理
  • PVC 所使用的存储必须由 CSI 提供,并支持 snapshot 功能。

部署 Alauda Build of VolSync

  1. 登录后,进入 管理员 页面。

  2. 单击 Marketplace > OperatorHub,进入 OperatorHub 页面。

  3. 找到 Alauda Build of VolSync,单击 Install,进入 Install Alauda Build of VolSync 页面。

    配置参数:

    参数推荐配置
    Channel默认 channel 为 stable
    Installation ModeCluster:集群中所有 namespace 共享一个单独的 Operator 实例进行创建和管理,因此资源占用更低。
    Installation Place选择 Recommended,Namespace 仅支持 volsync-system
    Upgrade StrategyManual:当 Operator Hub 中有新版本时,需要手动确认才能将 Operator 升级到最新版本。

配置定时同步

完成 PVC 的定时同步配置后,VolSync 会按照指定的间隔,自动将数据从 ReplicationSource 同步到 ReplicationDestination

下面配置的是从 Primary 集群到 Secondary 集群的同步。如果需要从 Secondary 集群同步到 Primary 集群,请通过交换集群角色来调整下面的示例。

创建 rsync-tls Data Mover Secret

PrimarySecondary 两个集群上都创建该 Secret;如果 Secret 已存在,则跳过此步骤。

Command
Example
apiVersion: v1
data:
  psk.txt: <psk>
kind: Secret
metadata:
  name: <name>
  namespace: <namespace>
type: Opaque

参数

参数说明
namesecret 的名称
namespacesecret 的 namespace,应与应用相同
psk该字段遵循 stunnel 期望的格式:<id>:<至少 32 位十六进制数字>
例如:1:23b7395fafc3e842bd8ac0fe142e6ad1

创建 ReplicationDestination 资源

Secondary 集群上创建 ReplicationDestination

Command
Example
cat << EOF | kubectl create -f -
apiVersion: volsync.backube/v1alpha1
kind: ReplicationDestination
metadata:
  name: rd-<pvc-name>
  namespace: <namespace>
spec:
  rsyncTLS:
    copyMethod: Snapshot
    destinationPVC: <pvc-name>
    keySecret: <key-secret>
    serviceType: <service-type>
    storageClassName: <storageclass-name>
    volumeSnapshotClassName: <volumesnapshotclass-name>
    moverSecurityContext:
      fsGroup: 65534
      runAsGroup: 65534
      runAsNonRoot: true
      runAsUser: 65534
      seccompProfile:
        type: RuntimeDefault
EOF

参数

参数说明
namespace与应用相同的 Namespace
pvc-name应用使用的已存在 PVC 的名称
key-secret包含用于认证与源端连接的 TLS-PSK 密钥的 Secret 名称,请在 步骤 1 中创建
service-typeVolSync 会创建一个 Service,以允许源端连接到目标端。该字段决定该 Service 的类型。允许的值为 ClusterIPLoadBalancerNodePort
storageclass-name应用 PVC 所使用的 storageclass 名称
volumesnapshotclass-name与应用 PVC 对应的 volumesnapshotclass 名称
NOTE

关于 service type

如果指定 ClusterIP,Service 将接收从“集群网络”地址池分配的 IP 地址。默认情况下,这组地址无法从集群外部访问,因此不太适合跨集群复制。不过,诸如 Submariner 之类的网络附加组件可以打通集群网络,因此这是一个不错的选择。

如果指定 LoadBalancer,将分配一个可从外部访问的 IP 地址。这需要集群支持负载均衡器,例如云厂商提供的负载均衡器,或者在物理集群场景下使用 MetalLB。虽然这是在云环境中分配可访问地址的最简单方式,但负载均衡器通常会产生额外成本,并且数量有限。

创建 ReplicationSource 资源

Primary 集群上创建 ReplicationSource

Command
Example
cat << EOF | kubectl create -f -
apiVersion: volsync.backube/v1alpha1
kind: ReplicationSource
metadata:
  name: rs-<pvc-name>
  namespace: <namespace>
spec:
  rsyncTLS:
    address: <address>
    copyMethod: Snapshot
    keySecret: <key-secret>
    port: <port>
    storageClassName: <storageclass-name>
    volumeSnapshotClassName: <volumesnapshotclass-name>
    moverSecurityContext:
      fsGroup: 65534
      runAsGroup: 65534
      runAsNonRoot: true
      runAsUser: 65534
      seccompProfile:
        type: RuntimeDefault
  sourcePVC: <pvc-name>
  trigger:
    schedule: <schedule>
EOF

参数

参数说明
namespaceNamespace 名称,与应用相同
pvc-name应用 PVC 的名称
key-secret步骤 1 中创建的 volsync secret 名称
address指定复制目标的 ssh server 地址。可直接从 ReplicationDestination.status.rsync.address 字段获取。
port连接目标端的 service port
storageclass-name应用 PVC 所使用的 storageclass 名称
volumesnapshotclass-name与应用 PVC 对应的 volumesnapshotclass 名称
schedule同步计划,由 cronspec 定义,因此非常灵活。既可以指定时间间隔,也可以指定具体时间和/或日期。

检查同步状态

检查来自 ReplicationSource 的同步状态

Command
Example
kubectl -n <namespace> get ReplicationSource <rs-name> -o jsonpath='{.status}'

上一次同步完成于 .status.lastSyncTime,耗时 .status.lastSyncDuration 秒。

下一次计划同步时间为 .status.nextSyncTime

配置一次性同步

一次性同步由手动触发。通过在 ReplicationSource 资源的 trigger 规范下为 manual 字段设置一个唯一字符串来控制。应用该配置后,同步任务会立即运行一次。

创建一次性 ReplicationSource 资源

Command
Example
cat << EOF | kubectl create -f -
apiVersion: volsync.backube/v1alpha1
kind: ReplicationSource
metadata:
  name: rs-<pvc-name>-latest
  namespace: <namespace>
spec:
  rsyncTLS:
    address: <address>
    copyMethod: Snapshot
    keySecret: <key-secret>
    port: <port>
    storageClassName: <storageclass-name>
    volumeSnapshotClassName: <volumesnapshotclass-name>
    moverSecurityContext:
      fsGroup: 65534
      runAsGroup: 65534
      runAsNonRoot: true
      runAsUser: 65534
      seccompProfile:
        type: RuntimeDefault
  sourcePVC: <pvc-name>
  trigger:
    manual: <manual-id>
EOF

定时同步 的唯一区别是 .spec.trigger 应设置为 manual

检查同步状态

Command
Example
kubectl -n <namespace> get ReplicationSource <rs-name> -o jsonpath='{.status.lastManualSync}'

如果输出与 <manual-id> 匹配,则表示同步已完成。

为应用 PVC 启用灾难恢复

部署有状态应用

  1. Primary 集群上部署有状态应用
单击查看
cat << EOF | kubectl create -f -
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-01
  namespace: default
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
  storageClassName: sc-cephfs
  volumeMode: Filesystem

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ubuntu
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: ubuntu
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: ubuntu
    spec:
      affinity: {}
      containers:
        - command:
            - sleep
            - infinity
          image: registry.alauda.cn:60070/ops/ubuntu:latest
          imagePullPolicy: Always
          name: ubuntu
          resources: {}
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          volumeMounts:
            - mountPath: /data
              name: data
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      terminationGracePeriodSeconds: 30
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: pvc-01
EOF
  1. Secondary 集群上创建应用 PVC

    cat << EOF | kubectl create -f -
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-01
      namespace: default
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 10Gi
      storageClassName: sc-cephfs
      volumeMode: Filesystem
    EOF

配置 PVC 灾难恢复

设置 Primary-to-Secondary 同步

参见 配置定时同步

计划迁移

用户场景

在两个集群都正常运行时,将业务服务从 Primary 集群迁移到 Secondary 集群。

操作步骤

  1. 缩减应用 Pod

    Primary 集群上缩减所有使用 dr PVC 的应用 Pod。

  2. 删除 ReplicationSource 资源

    Primary 集群上删除 ReplicationSource

    Command
    Example
    kubectl -n <namespace> delete ReplicationSource <rs-name>
  3. 创建一次性同步

    Primary 集群发起一次同步任务,确保 Secondary 集群中的数据是 up-to-date

    Primary 集群上创建 ReplicationSource

    参见 配置一次性同步

  4. 删除一次性同步

    一次性同步完成后,删除一次性 ReplicationSource 资源

    Command
    Example
    kubectl -n <namespace> delete ReplicationSource <rs-name>
  5. 删除 ReplicationDestination 资源

    Secondary 集群上删除 ReplicationDestination

    Command
    Example
    kubectl -n <namespace> delete ReplicationDestination <rd-name>
  6. 扩容应用 Pod

    Secondary 集群上扩容所有使用 dr PVC 的应用 Pod。

  7. 建立 Secondary-to-Primary 同步

    通过在 Primary 集群上创建 ReplicationDestination,并在 Secondary 集群上创建 ReplicationSource,为 PVC 灾难恢复建立 Secondary-to-Primary 集群同步。

    参见 配置定时同步

故障切换

用户场景

Primary 集群突然关闭后,将服务切换到 Secondary 集群。

操作步骤

为确保数据完整性(以防 primary 集群在同步过程中发生故障),请在 Secondary 集群上执行本地同步。使用从应用 PVC 的最后一个 snapshot 恢复得到的 PVC 作为源端,使用应用当前的 PVC 作为目标端来执行数据同步。

  1. 恢复 PVC

    Secondary 集群上从 ReplicationDestination 恢复 PVC

    Command
    Example
    cat << EOF | kubectl create -f -
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: restored-<pvc-name>
      namespace: <namespace>
    spec:
      accessModes: [<access-modes>]
      dataSourceRef:
        kind: ReplicationDestination
        apiGroup: volsync.backube
        name: <rd-name>
      resources:
        requests:
          storage: <pvc-size>
      storageClassName: <storageclass-name>
    EOF
  2. 创建本地 ReplicationSource 资源

    Secondary 集群上创建 ReplicationSource 资源

    Command
    Example
    cat << EOF | kubectl create -f -    
    apiVersion: volsync.backube/v1alpha1
    kind: ReplicationSource
    metadata:
      name: rs-<pvc-name>-local
      namespace: <namespace>
    spec:
      rsyncTLS:
        address: <address>
        copyMethod: Snapshot
        keySecret: <key-secret>
        port: <port>
        storageClassName: <storageclass-name>
        volumeSnapshotClassName: <volumesnapshotclass-name>
        moverSecurityContext:
          fsGroup: 65534
          runAsGroup: 65534
          runAsNonRoot: true
          runAsUser: 65534
          seccompProfile:
            type: RuntimeDefault
      sourcePVC: restored-<pvc-name>
      trigger:
        manual: <manual-id>
    EOF

    参数参见 配置一次性同步

  3. 等待同步完成

    Command
    Example
    kubectl -n <namespace> get ReplicationSource <rs-name> -o jsonpath='{.status.lastManualSync}'

    如果输出与 <manual-id> 匹配,则表示同步已完成。

  4. 删除本地 ReplicationSource

    Secondary 集群上删除本地 ReplicationSource

    Command
    Example
    kubectl -n <namespace> delete ReplicationSource <rs-name>
  5. 删除 ReplicationDestination

    Secondary 集群上删除 ReplicationDestination

    Command
    Example
    kubectl -n <namespace> delete ReplicationDestination <rd-name>
  6. 扩容应用 Pod

    Secondary 集群上扩容所有应用 Pod。

故障恢复后回切

用户场景

Primary 集群现已恢复并可正常运行,因此需要将服务切回该集群。

操作步骤

  1. 缩减 Primary 集群上的应用 Pod

    当 primary 集群重新上线后,应用 Pod 会自动恢复。但是,必须先缩减服务以停止流量。在将 secondary 集群中的最新数据同步到 primary 集群后,再扩容应用以恢复正常运行。

  2. 删除 Primary 集群上的 ReplicationSource

    需要先删除在 Primary 集群故障前创建的 ReplicationSource

    Command
    Example
    kubectl -n <namespace> delete ReplicationSource <rs-name>
  3. 从 Secondary 集群同步最新数据

    建立 Secondary-to-Primary 一次性同步。

    Primary 集群上创建 ReplicationDestination,然后在 Secondary 集群上创建一次性 ReplicationSource

    参见 配置一次性同步

  4. 删除 ReplicationDestination 和 ReplicationSource

    数据同步完成后,删除一次性资源

    Secondary 集群上删除 ReplicationSource

    Command
    Example
    kubectl -n <namespace> delete ReplicationSource <rs-name>

    Primary 集群上删除 ReplicationDestination

    Command
    Example
    kubectl -n <namespace> delete ReplicationDestination <rd-name>
  5. 迁移应用

    Secondary 集群上缩减应用 Pod

    Primary 集群上扩容应用 Pod

  6. 建立 Primary-to-Secondary 同步

    参见 配置定时同步