• 在Kubernetes中手动恢复Rook存储集群

    Rook介绍

     

    Rook将文件、数据块和对象存储系统引入到Kubernetes集群,与其他正在使用存储的应用程序和服务一起无缝运行。
    通过这种方式,云原生集群可以在公有云和本地部署中自给自足并且具备可移植性。该项目的开发目的是使企业能够通过动态应用编排,为在本地和公有云环境中运行的分布式存储系统实现数据中心现代化
    Rook 将存储软件转变成自我管理、自我扩展和自我修复的存储服务,通过自动化部署、启动、配置、供应、扩展、升级、迁移、灾难恢复、监控和资源管理来实现。Rook 底层使用云原生容器管理、调度和编排平台提供的能力来提供这些功能。
    Rook由Operator和Cluster两部分组成:
    • Operator:由一些CRD和一个All in one镜像构成,包含包含启动和监控存储系统的所有功能。
    • Cluster:负责创建CRD对象,指定相关参数,包括ceph镜像、元数据持久化位置、磁盘位置、dashboard等等…
    Rook使Kubernetes集群中的存储工作变得轻松了许多。但是,这种简单性同时也带来了一些复杂性。我们希望本文能帮助您避免其中的一些复杂性从而使它们简单化。
    为了让本文更加有趣,让我们假设我们刚刚遇到了集群的一个问题……

    故障场景

    想象一下,您已经在K8s集群中配置并启动了Rook。当前的所有任务操作都很正常,然后在某些时候出现了以下状况:
    • 新的Pod无法从Ceph挂载RBD镜像;
    • 诸如lsblkdf之类的命令在Kubernetes节点上不起作用。这表明挂载在节点上的RBD镜像出了点问题。您无法读取它们,这意味着Ceph Mon不可用。
    • Ceph Mon和OSD/MGR Pod都无法在集群中运行。
    现在是时候回答这个问题了,rook-ceph-operator Pod是什么时候开始启动的?事实证明,这是最近才发生的。为什么?菜鸟运维人员可能会突然决定创建一个新的集群!那么,我们又该如何还原旧群集及其数据?
    让我们从一个更长更有趣的地方开始,一步一步地研究Rook的内部机制并手动恢复其组件。显然,有一种更简短、更恰当的方法:使用备份。如您所知,有两种类型的管理员:一种是还没有使用备份的管理员,另一种是已经痛苦地学会始终使用备份的管理员(我们稍后再讨论)。

    Rook的手工恢复历程

     

    恢复Ceph Monitor节点

    首先,我们必须检查ConfigMap的列表:rook-ceph-configrook-config-override。它们是在部署集群成功后创建的。
    注意:在新版本的Rook中,ConfigMaps不再是部署群集成功的唯一标志。
    为了继续下去,我们必须对所有安装了RBD镜像(ls/dev/RBD*)的服务器进行硬重启。您可以使用sysrq。此步骤对于卸载所有已挂载的RBD镜像是必须的,因为在这种情况下,常规重新启动将不起作用(系统无法正常的卸载镜像)。
    如您所知,Ceph Monitor守护程序的正常运行是所有Ceph集群的先决条件。下面,让我们来确认一下它。
    Rook将以下组件安装到Monitor的Pod中:
    Volumes:
    rook-ceph-config:
      Type:     ConfigMap (a volume populated by a ConfigMap)
      Name:     rook-ceph-config
    rook-ceph-mons-keyring:
      Type:       Secret (a volume populated by a Secret)
      SecretName: rook-ceph-mons-keyring
    rook-ceph-log:
      Type:         HostPath (bare host directory volume)
      Path:         /var/lib/rook/kube-rook/log
    ceph-daemon-data:
      Type:         HostPath (bare host directory volume)
      Path:         /var/lib/rook/mon-a/data
    Mounts:
    /etc/ceph from rook-ceph-config (ro)
    /etc/ceph/keyring-store/ from rook-ceph-mons-keyring (ro)
    /var/lib/ceph/mon/ceph-a from ceph-daemon-data (rw)
    /var/log/ceph from rook-ceph-log (rw)
    让我们仔细看看这个rook-ceph-mons-keyring secret的内容:
    kind: Secret
    data:
    keyring: LongBase64EncodedString=
    解码后,我们将获得具有管理员和Ceph Monitor权限的常规密钥keyring:
    [mon.]
          key = AQAhT19dlUz0LhBBINv5M5G4YyBswyU43RsLxA==
          caps mon = “allow *”
    [client.admin]
          key = AQAhT19d9MMEMRGG+wxIwDqWO1aZiZGcGlSMKp==
          caps mds = “allow *”
          caps mon = “allow *”
          caps osd = “allow *”
          caps mgr = “allow *”
    现在让我们分析rook-ceph-admin-keyring secret的内容:
    kind: Secret
    data:
    keyring: anotherBase64EncodedString=
    我们发现了啥?
    [client.admin]
          key = AQAhT19d9MMEMRGG+wxIwDqWO1aZiZGcGlSMKp==
          caps mds = “allow *”
          caps mon = “allow *”
          caps osd = “allow *”
          caps mgr = “allow *”
    继续查找……例如,以下的这个rook-ceph-mgr-a-keyring secret
    [mgr.a]
          key = AQBZR19dbVeaIhBBXFYyxGyusGf8x1bNQunuew==
          caps mon = “allow *”
          caps mds = “allow *”
          caps osd = “allow *”
    最终,我们在rook-ceph-monConfigMap中发现了更多secret
    kind: Secret
    data:
    admin-secret: AQAhT19d9MMEMRGG+wxIwDqWO1aZiZGcGlSMKp==
    cluster-name: a3ViZS1yb29r
    fsid: ZmZiYjliZDMtODRkOS00ZDk1LTczNTItYWY4MzZhOGJkNDJhCg==
    mon-secret: AQAhT19dlUz0LhBBINv5M5G4YyBswyU43RsLxA==
    它包含原始的keyrings列表,并且是上述所有keyrings的来源。
    如你所知,Rook存储在两个不同的地方存储这个数据。因此,让我们看一下主机目录中的keyring,这些keyring已安装到包含Ceph Monitor和OSD的Pod中。为此,我们必须在/var/lib/rook/mon-a/data/keyring节点上找到相应的目录并检查其内容:
    # cat /var/lib/rook/mon-a/data/keyring
    [mon.]
          key = AXAbS19d8NNUXOBB+XyYwXqXI1asIzGcGlzMGg==
          caps mon = “allow *”
    这里的secret不同于ConfigMap中的secret
    管理员keyring又是怎么的呢?它也是存在的:
    # cat /var/lib/rook/kube-rook/client.admin.keyring
    [client.admin]
          key = AXAbR19d8GGSMUBN+FyYwEqGI1aZizGcJlHMLgx=
          caps mds = “allow *”
          caps mon = “allow *”
          caps osd = “allow *”
          caps mgr = “allow *”
    这也是当前问题所在。当发生了故障时:一切看起来都像是在重新创建集群,而实际上却没有
    显然,secret包含新的keyring,并且与我们的旧群集不匹配。这就是为什么我们必须:
    • 使用/var/lib/rook/mon-a/data/keyring文件(或备份)中的Ceph Monitorkeyring
    • 更换rook-ceph-mons-keyring secret中的keyring;
    • rook-ceph-monConfigMap中指定admin和monitorkeyring
    • 删除Ceph Monitor的Pod。
    在短暂的等待之后,Ceph Monitor再次启动并运行。这是一个比较好的开始!

    还原OSD

     

    现在我们需要进入rook-operatorPod。执行ceph mon dump后显示所有Ceph Monitor均已就位,ceph -s表示它们已达到法定人数。但是,如果我们查看OSD Tree(ceph osd tree),则会发现一些奇怪的现象:OSD开始出现,但它们为空。看来我们必须以某种方式还原它们。但是如何做?
    同时,在我们的ConfigMaps中,我们终于得到了我们所需要的rook-ceph-configrook-config-override(以及其他比如名称为rook-ceph osd-$nodename-config的ConfigMaps):
    kind: ConfigMap
    data:
    osd-dirs: ‘{“/mnt/osd1″:16,”/mnt/osd2”:18}’
    如上,我们可以看到,osd挂载目录与osd id都已经混乱!
    让我们将operator Pod的数量缩小到零,删除OSD容器生成的Deployment文件,并修复这些ConfigMap。但是,我们从何处获得节点之间OSD分布的正确映射关系?
    • 如果我们深入研究节点上的/mnt/osd[1–2]目录,也许,在那里可以找到一些东西。
    • /mnt/osd1中有两个子目录,它们是osd0osd16。第二个子文件夹与ConfigMap(16)中定义的子文件夹相同。
    • 查看它们的大小,我们看到osd0osd16更大。
    我们得出结论,osd0是我们需要的“旧”OSD。它在ConfigMap中被定义为/mnt/osd1(因为我们使用基于目录的osd)。
    我们一步一步地深入研究节点并修复ConfigMap。完成后,我们可以运行rook-operator pod并分析其日志,会发现以下的流程:
    • “我是集群的管理员”;
    • “我在节点上找到物理磁盘”;
    • “我发现了Ceph Monitor”;
    • “好的,Ceph Monitor已达到法定人数;”
    • “我正在开始OSD部署……”。
    让我们通过进入Rook operator的pod来检查集群的状况。好吧,看起来我们在几个节点的OSD名称上犯了一些错误!这没什么大不了的:我们修复了ConfigMaps,删除了新osd的冗余目录,等等,最后,我们的集群状态终于变成了HEALTH_OK
    让我们检查一下存储池中的镜像:

    # rbd ls -p kube
    pvc-9cfa2a98-b878-437e-8d57-acb26c7118fb
    pvc-9fcc4308-0343-434c-a65f-9fd181ab103e
    pvc-a6466fea-bded-4ac7-8935-7c347cff0d43
    pvc-b284d098-f0fc-420c-8ef1-7d60e330af67
    pvc-b6d02124-143d-4ce3-810f-3326cfa180ae
    pvc-c0800871-0749-40ab-8545-b900b83eeee9
    pvc-c274dbe9-1566-4a33-bada-aabeb4c76c32

    现在一切就绪,集群已恢复!

    快速偷懒的恢复方法

     

    对于已经做好备份的场景,恢复过程更简单,归结为以下几点:
    1. 将Rook-operator的部署规模缩小到零;
    2. 删除除Rook operator之外的所有部署;
    3. 从备份还原所有secret和ConfigMap;
    4. 恢复/var/lib/rook/mon-*节点上目录的内容;
    5. 还原CephClusterCephFilesystemCephBlockPoolCephNFSCephObjectStoreCRD(如果他们不知何故丢失);
    6. 将Rook-operator的部署扩展回1。

     

    提示和技巧

    始终进行备份!
    以下是一些技巧,可避免在急需这些备份时避免这些情况:
    • 如果您打算对集群进行一些涉及服务器重启的大规模操作,我们建议将rook-operator部署缩减为零,以防止它“触发故障”。
    • 预先为Ceph Monitor指定nodeAffinity;
    • 密切注意预配置 ROOK_MON_HEALTHCHECK_INTERVALROOK_MON_OUT_TIMEOUT值。

     

    结论

    毫无疑问,Rook作为Kubernetes存储的整体结构中的附加层简化了基础架构中的存储管理,但是也使某些事情变得很复杂。你的每一个操作以及选择都必须是经过深思熟虑的。
    顺便说一下,最近官方在Rook文档(https://github.com/rook/rook/commit/b651239d3f9a793c95b5c06668b7f28771254082#diff-8c0c983d538cce2b49678395777c3cb9)中增加了“将现有Rook Ceph群集纳入新的Kubernetes群集” 部分。
    您可以在其中找到将现有Rook Ceph群集引入新的Kubernetes群集所需的步骤的详细说明,以及如何恢复由于某种原因而失败的集群。

    原文:https://blog.flant.com/manual-recovery-of-a-rook-cluster-in-kubernetes/

     

    云管理服务专家新钛云服 祝祥翻译

    «
    »
以专业成就每一位客户,让企业IT只为效果和安全买单

以专业成就每一位客户,让企业IT只为效果和安全买单