第 11 章 在 OpenShift Data Foundation 中恢复 monitor pod

如果所有三个 Pod 都停机,并且 OpenShift Data Foundation 无法自动恢复 monitor pod,则恢复 monitor pod。

流程

  1. 缩减 rook-ceph-operatorocs operator 部署。

    # oc scale deployment rook-ceph-operator --replicas=0 -n openshift-storage
    # oc scale deployment ocs-operator --replicas=0 -n openshift-storage
  2. openshift-storage 命名空间中创建所有部署的备份。

    # mkdir backup
    # cd backup
    # oc project openshift-storage
    # for d in $(oc get deployment|awk -F' ' '{print $1}'|grep -v NAME); do echo $d;oc get deployment $d -o yaml > oc_get_deployment.${d}.yaml; done
  3. 修补 OSD 部署以移除 livenessProbe 参数,再以 命令参数作为 sleep 状态运行它。

    # for i in $(oc get deployment -l app=rook-ceph-osd -oname);do oc patch ${i} -n openshift-storage --type='json' -p '[{"op":"remove", "path":"/spec/template/spec/containers/0/livenessProbe"}]' ; oc patch ${i} -n openshift-storage -p '{"spec": {"template": {"spec": {"containers": [{"name": "osd", "command": ["sleep", "infinity"], "args": []}]}}}}' ; done
  4. 从所有 OSD 检索 monstore 集群映射。

    1. 创建 restore_mon.sh 脚本。

      #!/bin/bash
      ms=/tmp/monstore
      
      rm -rf $ms
      mkdir $ms
      
      for osd_pod in $(oc get po -l app=rook-ceph-osd -oname -n openshift-storage); do
      
        echo "Starting with pod: $osd_pod"
      
        podname=$(echo $osd_pod|sed 's/pod\///g')
        oc exec $osd_pod -- rm -rf $ms
        oc cp $ms $podname:$ms
      
        rm -rf $ms
        mkdir $ms
      
        echo "pod in loop: $osd_pod ; done deleting local dirs"
      
        oc exec $osd_pod -- ceph-objectstore-tool --type bluestore --data-path /var/lib/ceph/osd/ceph-$(oc get $osd_pod -ojsonpath='{ .metadata.labels.ceph_daemon_id }') --op update-mon-db --no-mon-config --mon-store-path $ms
        echo "Done with COT on pod: $osd_pod"
      
        oc cp $podname:$ms $ms
      
        echo "Finished pulling COT data from pod: $osd_pod"
      done
    2. 运行 restore_mon.sh 脚本。

      # chmod +x recover_mon.sh
      # ./recover_mon.sh
  5. 修补 MON 部署,并使用命令参数作为 sleep 状态运行它。

    1. 编辑 MON 部署。

      # for i in $(oc get deployment -l app=rook-ceph-mon -oname);do oc patch ${i} -n openshift-storage -p '{"spec": {"template": {"spec": {"containers": [{"name": "mon", "command": ["sleep", "infinity"], "args": []}]}}}}'; done
    2. 修补 MON 部署,以增加 initialDelaySeconds

      # oc get deployment rook-ceph-mon-a -o yaml | sed "s/initialDelaySeconds: 10/initialDelaySeconds: 2000/g" | oc replace -f -
      # oc get deployment rook-ceph-mon-b -o yaml | sed "s/initialDelaySeconds: 10/initialDelaySeconds: 2000/g" | oc replace -f -
      # oc get deployment rook-ceph-mon-c -o yaml | sed "s/initialDelaySeconds: 10/initialDelaySeconds: 2000/g" | oc replace -f -
  6. 将之前检索到的 monstore 复制到 mon-a pod。

    # oc cp /tmp/monstore/ $(oc get po -l app=rook-ceph-mon,mon=a -oname |sed 's/pod\///g'):/tmp/
  7. 导航到 MON 容器集,再更改检索到的 monstore 的所有权。

    # oc rsh $(oc get po -l app=rook-ceph-mon,mon=a -oname)
    # chown -R ceph:ceph /tmp/monstore
  8. 在重建 mon db 之前复制密钥环模板文件。

    # oc rsh $(oc get po -l app=rook-ceph-mon,mon=a -oname)
    # cp /etc/ceph/keyring-store/keyring /tmp/keyring
    # cat /tmp/keyring
      [mon.]
        key = AQCleqldWqm5IhAAgZQbEzoShkZV42RiQVffnA==
        caps mon = "allow *"
      [client.admin]
        key = AQCmAKld8J05KxAArOWeRAw63gAwwZO5o75ZNQ==
        auid = 0
        caps mds = "allow *"
        caps mgr = "allow *"
        caps mon = "allow *"
        caps osd = "allow *”
  9. 从对应的机密中识别所有其他 Ceph 守护进程(MGR、MDS、RGW、Crash、CSI 和 CSI 置备程序)的密钥环。

    # oc get secret rook-ceph-mds-ocs-storagecluster-cephfilesystem-a-keyring -ojson  | jq .data.keyring | xargs echo | base64 -d
    
    [mds.ocs-storagecluster-cephfilesystem-a]
    key = AQB3r8VgAtr6OhAAVhhXpNKqRTuEVdRoxG4uRA==
    caps mon = "allow profile mds"
    caps osd = "allow *"
    caps mds = "allow"

    keyring 文件示例: /etc/ceph/ceph.client.admin.keyring:

    [mon.]
    	key = AQDxTF1hNgLTNxAAi51cCojs01b4I5E6v2H8Uw==
    	caps mon = "allow "
    [client.admin]
            key = AQDxTF1hpzguOxAA0sS8nN4udoO35OEbt3bqMQ==
            caps mds = "allow " caps mgr = "allow *" caps mon = "allow *" caps osd = "allow *" [mds.ocs-storagecluster-cephfilesystem-a] key = AQCKTV1horgjARAA8aF/BDh/4+eG4RCNBCl+aw== caps mds = "allow" caps mon = "allow profile mds" caps osd = "allow *" [mds.ocs-storagecluster-cephfilesystem-b] key = AQCKTV1hN4gKLBAA5emIVq3ncV7AMEM1c1RmGA== caps mds = "allow" caps mon = "allow profile mds" caps osd = "allow *" [client.rgw.ocs.storagecluster.cephobjectstore.a] key = AQCOkdBixmpiAxAA4X7zjn6SGTI9c1MBflszYA== caps mon = "allow rw" caps osd = "allow rwx" [mgr.a] key = AQBOTV1hGYOEORAA87471+eIZLZtptfkcHvTRg== caps mds = "allow *" caps mon = "allow profile mgr" caps osd = "allow *" [client.crash] key = AQBOTV1htO1aGRAAe2MPYcGdiAT+Oo4CNPSF1g== caps mgr = "allow rw" caps mon = "allow profile crash" [client.csi-cephfs-node] key = AQBOTV1hiAtuBBAAaPPBVgh1AqZJlDeHWdoFLw== caps mds = "allow rw" caps mgr = "allow rw" caps mon = "allow r" caps osd = "allow rw tag cephfs *=" [client.csi-cephfs-provisioner] key = AQBNTV1hHu6wMBAAzNXZv36aZJuE1iz7S7GfeQ== caps mgr = "allow rw" caps mon = "allow r" caps osd = "allow rw tag cephfs metadata="
    [client.csi-rbd-node]
    	key = AQBNTV1h+LnkIRAAWnpIN9bUAmSHOvJ0EJXHRw==
    	caps mgr = "allow rw"
    	caps mon = "profile rbd"
    	caps osd = "profile rbd"
    [client.csi-rbd-provisioner]
    	key = AQBNTV1hMNcsExAAvA3gHB2qaY33LOdWCvHG/A==
    	caps mgr = "allow rw"
    	caps mon = "profile rbd"
    	caps osd = "profile rbd"
    重要
    • 对于 client.csi 相关的密钥环,请参阅前面的密钥环文件输出,并在从其相应的 OpenShift Data Foundation secret 获取密钥后添加默认 大写字母
    • OSD 密钥环会在恢复后自动添加。
  10. 进入 mon-a pod,验证 monstore 具有 monmap

    1. 进入到 mon-a 容器集。

      # oc rsh $(oc get po -l app=rook-ceph-mon,mon=a -oname)
    2. 验证 monstoremonmap

      # ceph-monstore-tool /tmp/monstore get monmap -- --out /tmp/monmap
      # monmaptool /tmp/monmap --print
  11. 可选:如果缺少 monmap,则创建新的 monmap

    # monmaptool --create --add <mon-a-id> <mon-a-ip> --add <mon-b-id> <mon-b-ip> --add <mon-c-id> <mon-c-ip> --enable-all-features --clobber /root/monmap --fsid <fsid>
    <mon-a-id>
    mon-a pod 的 ID。
    <mon-a-ip>
    mon-a pod 的 IP 地址。
    <mon-b-id>
    mon-b pod 的 ID。
    <mon-b-ip>
    mon-b pod 的 IP 地址。
    <mon-c-id>
    mon-c pod 的 ID。
    <mon-c-ip>
    mon-c pod 的 IP 地址。
    <fsid>
    是文件系统 ID。
  12. 验证 monmap

    # monmaptool /root/monmap --print
  13. 导入 monmap

    重要

    使用之前创建的 keyring 文件。

    # ceph-monstore-tool /tmp/monstore rebuild -- --keyring /tmp/keyring --monmap /root/monmap
    # chown -R ceph:ceph /tmp/monstore
  14. 创建旧 store.db 文件的备份。

    # mv /var/lib/ceph/mon/ceph-a/store.db /var/lib/ceph/mon/ceph-a/store.db.corrupted
    # mv /var/lib/ceph/mon/ceph-b/store.db /var/lib/ceph/mon/ceph-b/store.db.corrupted
    # mv /var/lib/ceph/mon/ceph-c/store.db /var/lib/ceph/mon/ceph-c/store.db.corrupted
  15. 将重新构建 store.db 文件复制到 monstore 目录。

    # mv /tmp/monstore/store.db /var/lib/ceph/mon/ceph-a/store.db
    # chown -R ceph:ceph /var/lib/ceph/mon/ceph-a/store.db
  16. 在重建了 monstore 目录后,将 store.db 文件从本地 复制到 MON 容器集的其余部分。

    # oc cp $(oc get po -l app=rook-ceph-mon,mon=a -oname | sed 's/pod\///g'):/var/lib/ceph/mon/ceph-a/store.db /tmp/store.db
    # oc cp /tmp/store.db $(oc get po -l app=rook-ceph-mon,mon=<id> -oname | sed 's/pod\///g'):/var/lib/ceph/mon/ceph-<id>
    <id>
    是 MON Pod 的 ID
  17. 前往 MON 容器集的其余部分,再更改复制的 monstore 的所有权。

    # oc rsh $(oc get po -l app=rook-ceph-mon,mon=<id> -oname)
    # chown -R ceph:ceph /var/lib/ceph/mon/ceph-<id>/store.db
    <id>
    是 MON Pod 的 ID
  18. 恢复补丁的更改。

    • 对于 MON 部署:

      # oc replace --force -f <mon-deployment.yaml>
      <mon-deployment.yaml>
      是 MON 部署 yaml 文件
    • 对于 OSD 部署:

      # oc replace --force -f <osd-deployment.yaml>
      <osd-deployment.yaml>
      是 OSD 部署 yaml 文件
    • 对于 MGR 部署:

      # oc replace --force -f <mgr-deployment.yaml>
      <mgr-deployment.yaml>

      是 MGR 部署 yaml 文件

      重要

      确保 MON、MGR 和 OSD 容器集已启动并在运行。

  19. 扩展 rook-ceph-operatorocs-operator 部署。

    # oc -n openshift-storage scale deployment ocs-operator --replicas=1

验证步骤

  1. 检查 Ceph 状态,以确认 CephFS 正在运行。

    # ceph -s

    输出示例:

    cluster:
       id:     f111402f-84d1-4e06-9fdb-c27607676e55
       health: HEALTH_ERR
                1 filesystem is offline
                1 filesystem is online with fewer MDS than max_mds
                3 daemons have recently crashed
    
       services:
         mon: 3 daemons, quorum b,c,a (age 15m)
         mgr: a(active, since 14m)
         mds: ocs-storagecluster-cephfilesystem:0
         osd: 3 osds: 3 up (since 15m), 3 in (since 2h)
    
       data:
         pools:   3 pools, 96 pgs
         objects: 500 objects, 1.1 GiB
         usage:   5.5 GiB used, 295 GiB / 300 GiB avail
         pgs:     96 active+clean
  2. 检查 Multicloud 对象网关(MCG)状态。它应该处于活跃状态,后备存储和 bucketclass 应为 Ready 状态。

    noobaa status -n openshift-storage
    重要

    如果 MCG 不在活跃状态,且后备存储和存储桶类没有处于 Ready 状态,则需要重启所有 MCG 相关 pod。如需更多信息,请参阅 第 11.1 节 “恢复 Multicloud 对象网关”

11.1. 恢复 Multicloud 对象网关

如果 Multicloud Object Gateway(MCG)没有处于活跃状态,且后备store 和 bucketclass 不在 Ready 状态,您需要重启所有 MCG 相关 pod,并检查 MCG 状态以确认 MCG 是否恢复并正在运行。

流程

  1. 重启与 MCG 相关的所有 pod。

    # oc delete pods <noobaa-operator> -n openshift-storage
    # oc delete pods <noobaa-core> -n openshift-storage
    # oc delete pods <noobaa-endpoint> -n openshift-storage
    # oc delete pods <noobaa-db> -n openshift-storage
    <noobaa-operator>
    是 MCG operator 的名称
    <noobaa-core>
    是 MCG 内核 pod 的名称
    <noobaa-endpoint>
    是 MCG 端点的名称
    <noobaa-db>
    是 MCG db pod 的名称
  2. 如果配置了 RADOS 对象网关(RGW),请重新启动容器集。

    # oc delete pods <rgw-pod> -n openshift-storage
    <rgw-pod>
    是 RGW pod 的名称