我们的双手并非无聊:在K8s中恢复Rook集群



我们已经讨论过我们如何/为什么喜欢Rook:在很大程度上,它简化了Kubernetes集群中的存储工作。 但是,通过这种简单性,会遇到一些困难。 我们希望新材料即使在这些困难显现出来之前也将有助于更好地理解这些困难。

为了使阅读更有趣,我们从集群中一个假设问题的后果开始。

“一切都消失了!”


想象一下,您曾经在K8s集群中配置并启动Rook,他对他的工作感到满意,但是在某个“奇妙”的时刻,发生了以下事情:

  • 新的Pod无法安装Ceph RBD。
  • 诸如lsblkdf类的命令在Kubernetes主机上不起作用。 这自动表示节点安装的RBD映像“有问题”。 我看不懂它们,这表明显示器无法访问...
  • 是的,集群中没有操作监视器。 而且,甚至没有带有OSD的豆荚,也没有MGR豆荚。

pod rook-ceph-operator什么时候推出的? 不久之前,他已被部署。 怎么了 Rook-operator决定建立一个新的集群...现在如何恢复该集群及其中的数据?

首先,让我们走一条有趣的路,对Rook的“内部”进行了周到的研究,并逐步恢复了其组成部分。 当然,有一种较短的正确方法:使用备份。 如您所知,管理员分为两种:一种是不执行备份的管理员,另一种是已经进行备份的管理员。

一点练习或长途跋涉


看一下并还原显示器


因此,让我们看一下ConfigMap的列表:备份需要rook-ceph-configrook-config-override 。 它们在成功部署集群后出现。

注意 :在新版本中,通过此PR后 ,ConfigMaps不再是集群部署成功的指示。

要执行进一步的操作,我们需要重新启动所有已安装RBD映像( ls /dev/rbd* )的服务器。 必须通过sysrq(或“步行”到达数据中心)完成。 此要求是由于断开已安装的RBD的任务而导致的,因此无法进行常规的重新引导(它将无法正常尝试将其卸载)。

剧院从衣架开始,而Ceph集群从监视器开始。 让我们看看它们。

Rook在监视器窗格中安装了以下实体:

 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的秘密是什么:

 kind: Secret data: keyring: LongBase64EncodedString= 

我们解码并获得具有管理员和监视器权限的常规密钥环:

 [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

 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的秘密:

 [mgr.a] key = AQBZR19dbVeaIhBBXFYyxGyusGf8x1bNQunuew== caps mon = "allow *" caps mds = "allow *" caps osd = "allow *" 

最后,我们在ConfigMap rook-ceph-mon发现了更多秘密:

 kind: Secret data: admin-secret: AQAhT19d9MMEMRGG+wxIwDqWO1aZiZGcGlSMKp== cluster-name: a3ViZS1yb29r fsid: ZmZiYjliZDMtODRkOS00ZDk1LTczNTItYWY4MzZhOGJkNDJhCg== mon-secret: AQAhT19dlUz0LhBBINv5M5G4YyBswyU43RsLxA== 

这是带有钥匙圈的初始列表,上面描述的所有秘密均来自此。

如您所知(请参阅dataDirHostPath中的dataDirHostPath ),Rook将此数据存储在两个位置。 因此,让我们转到节点来查看位于带有监视器和OSD的Pod中安装的目录中的keyring'y。 为此,请找到节点/var/lib/rook/mon-a/data/keyring然后查看:

 # cat /var/lib/rook/mon-a/data/keyring [mon.] key = AXAbS19d8NNUXOBB+XyYwXqXI1asIzGcGlzMGg== caps mon = "allow *" 

突然之间,秘密变得不一样了-不同于ConfigMap中秘密。

管理员密钥环又如何呢? 我们也有:

 # 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 *" 

这是问题所在。 发生了故障:重新创建了集群...但实际上不是。

很明显,新生成的密钥环存储在秘密中,而不是来自我们的旧集群。 因此:

  • 我们从监视器/var/lib/rook/mon-a/data/keyring文件/var/lib/rook/mon-a/data/keyring (或从备份)中获取/var/lib/rook/mon-a/data/keyring
  • 更改密钥rook-ceph-mons-keyring
  • 从管理员注册密钥环并在ConfigMap'e rook-ceph-mon监视;
  • 卸下带有显示器的吊舱控制器。

奇迹不会持续很长时间:监视器将出现并启动。 万岁,一个开始!

还原OSD


我们进入pod rook-operator :调用ceph mon dump表示所有监视器都已安装到位,而ceph -s它们已达到法定人数。 但是,如果您查看OSD树( ceph osd tree ),您会发现其中有些奇怪:OSD开始出现,但它们为空。 事实证明,还需要以某种方式恢复它们。 但是如何?

同时, rook-ceph-configrook-config-override以及许多其他名称为rook-ceph-osd-$nodename-config ConfigMap出现在ConfigMap中,因此需要。 让我们看看它们:

 kind: ConfigMap data: osd-dirs: '{"/mnt/osd1":16,"/mnt/osd2":18}' 

一切都错了,一切都混了!

将操作员窗格缩放为零,从OSD删除生成的Deployment Pod,然后修复这些ConfigMap。 但是,从哪里获得正确的 OSD映射图呢?

  • 让我们尝试再次探究节点上的/mnt/osd[1-2]目录-希望我们可以在那里找到一些东西。
  • /mnt/osd1目录中有2个子目录: osd0osd16 。 最后一个只是在ConfigMap(16)中指定的ID?
  • 让我们osd0大小,看看osd0osd16

我们得出结论, osd0是必需的OSD,在ConfigMap /mnt/osd1其指定为/mnt/osd1 (因为我们使用基于目录的osd 。)

逐步,我们检查所有节点并编辑ConfigMap。 完成所有说明后,您可以运行Rook运算符的pod并读取其日志。 在他们身上一切都很棒:

  • 我是集群运营商;
  • 我在节点上发现了驱动器;
  • 我找到了监视器;
  • 监控者成为朋友,即 形成法定人数
  • 正在运行OSD部署...

让我们回到Rook运算符的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 … 

一切就绪-群集已保存!

我很懒惰做备份,还是快速方法


如果为Rook完成了备份,那么恢复过程将变得更加简单,并归结为以下内容:

  1. 扩展到零部署Rook运算符;
  2. 我们除去Rook运算符之外的所有部署;
  3. 我们从备份中还原所有机密和ConfigMap。
  4. 恢复节点上/var/lib/rook/mon-*的内容;
  5. 恢复(如果突然丢失)CRD CephClusterCephFilesystemCephBlockPoolCephNFSCephObjectStore
  6. 将Rook运算符的部署扩展回1。

有用的提示


做备份!

并避免需要从其中恢复的情况:

  1. 在大规模重启群集(包括重新引导服务器)之前,请将Rook运算符缩放为零,以使其作用不大。
  2. 在监视器上,预先添加nodeAffinity
  3. 注意预先设置超时时间 ROOK_MON_HEALTHCHECK_INTERVALROOK_MON_OUT_TIMEOUT

而不是结论


毫无疑问地认为,Rook是一个额外的“层”(在Kubernetes中组织存储的一般方案中),它大大简化了,它也增加了基础架构中的新困难和潜在问题。 事情仍然“微不足道”:一方面,在这些风险与解决方案为您的特定案例带来的收益之间做出平衡,明智的选择。

顺便说一下,最近 Rook文档中添加了 “将现有Rook Ceph群集纳入新的Kubernetes群集”部分。 它更详细地描述了将现有数据移动到新的Kubernetes集群或恢复由于某种原因而崩溃的集群所需执行的操作。

聚苯乙烯


另请参阅我们的博客:

Source: https://habr.com/ru/post/zh-CN477680/


All Articles