事件发生

5月13日17:20左右,接到用户报告,应用的数据丢失,数据全部恢复到最初始的状态。
由于此应用是docker部署在K8S平台,首先查询了一下mongodb容器的日志,发现在17:10左右有一次容器重启。
mongodb容器采用了“有状态负载”的部署,所以有一块持久化的Volume,部署在A节点,当时不是很担心。
后来运维报告,此容器的亲和性忘记配置,造成mongo节点漂移到另外一个节点B上。
由于当时规划的时候,只在A节点配置了持久化Volume,所以当时想当然的解决办法就是把亲和性配置好。
让mongo回到了A节点,但是,用户报告依然无法找到新的数据,只有4月23日的数据!
诡异的事情就出现了。
理论上说,既然配置了持久化Volume,数据就不会丢失。

原因分析

但是为啥数据就丢失了呢?
是因为mongo版本的问题吗?不是,我们的是4.0以上的版本

经过无数次测试,涉及到开发方,机房方,搞了两天,如同一个悬疑剧。
最后终于定位问题所在。

还是一个细节引起了我们的注意,如前述,第一次用户说的是“数据全部恢复到最初始的状态”
第二次用户说的是“只有4月23日的数据”
当时没有在意这两句话的区别,后来才明白这两句话是关键点。

节点持久化Volume数据备份
A
B

解密时刻

原来,我们一直认为mongo是在A节点上运行着,所以一直纠结为什么数据没有写入到数据库?
跟着这个细节推测,当时mongo其实一直在B节点上运行着,由于B节点上是没有持久化Volume(单独的外盘),只写在B节点对应的虚机目录里。
结果由于内存占用的问题(当时没有考虑到mongo会占用超过256M内存),容器崩溃了,结果K8S就是自动重启了容器。

由于我们一直认为mongo是在A节点上运行着,所以当时看到B节点上也有mongo的目录(其实这份数据倒是最新的),就进行了mv操作。
结果mongo启动后,应用程序由于无法找到mongo的目录,自动初始化了一份数据出来,用户看到就是最初始的数据。
悲催的是,这个时候我们还认为是在A节点运行,运维人员根本没有去细看容器运行的节点,想当然的认为是在A节点。
最悲惨的是,运维人员后来又删除了那份被mv的数据,后来虽然尝试恢复,但是已无力回天!

第二次,我们发现mongo在B节点上,就配置了亲和性,强制在A节点启动,A节点上有持久化Volume,其中是有4月23日的数据。
造成了第二次用户反馈只有4月23日的数据。
至此,问题原因查明!

深刻教训

教训,经过此次事件,进一步理解运维工作中备份的重要性。
虽然这次只是UAT环境,但也影响整个项目进度。
另外,对于应用程序熟悉和K8S熟悉也是重要前提。
此文就作为一个留念,时刻提醒自己吧!

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐