首先说备份etcd快照数据很重要,因为如果机器断电导致etcd突然中断,它自身是无法恢复的。
之前出现了两次这种情况,每次都是重置kubernetes,但现在部署的应用越来越多就比较麻烦了,所以不得不搞定通过快照备份来快速恢复。
https://blog.csdn.net/u013958257/article/details/106978416
首先参考的是这篇文章,所说明的问题是一样的。
按照其所指备份方法成功备份后,恢复遇到了问题。
他是通过在kubernetes之外单独安装etcd,通过etcdctl恢复成功,我想的是通过etcd容器进行恢复,这样就不用单独安装etcd了。
进入到etcd容器执行他说明的恢复命令时,提示/var/lib/etcd目录已经存在。
那好再按照他的说明先将这个目录重命名下,当执行重命名时mv命令时出现了错误,说是“Device or resource busy”.
现在就麻烦了,麻烦在哪呢?
由于我所有的操作都是在容器中执行的,而/var/lib/etcd是加载的外部主机的,所以不能删除,而它的存在又会导致恢复操作不会成功,因为恢复需要一个空的目录。
PS: 其实现在想来出现这个问题,是因为执行恢复命令时通过—data-dir选项指定了恢复目录,如果不指定的话会存放到默认目录/default.etcd/下,在恢复完成后可以将恢复结果复制到/var/lib/etcd下。之所以参考文章没有问题,是因为他是在主机上操作,可以对/var/lib/etcd做任何操作。
在这种进退两难的情况下,有找了另一篇关于etcd恢复的文章。
https://elastisys.com/backup-kubernetes-how-and-why/
它的思路和我一样,也是通过容器恢复,而不是单据安装etcd。
通过etcd镜像重新创建一个容器,而是复用现有容器,并且将/var/lib/etcd也加载到容器内,但执行恢复操作时并没有指定要恢复到的目录,这样恢复的数据就到了默认目录/default.etcd/下,恢复完成后再通过mv命令把其下member目录移动到/var/lib/etcd。
这样主机的/var/lib/etcd目录下也有了已经恢复完成的数据。
最后删除kubernetes的etcd容器,它自动重建后果然数据都回来了。
但通过kubectl查看pod时发现有些是终止状态,查看其日志发现都是相同的错误:“Authorization error (user=kube-apiserver-kubelet-client, verb=create, resource=nodes, subresource=proxy)”,开始以为是恢复数据导致连接apiserver的客户端证书丢失,但通过查看/etc/kubernetes/pki目录,发现证书都是存在的。
对比发现处于终止状态的pod都在非主节点上,再查看节点状态,发现除了主节点其它都是unreachable状态,尝试重启其中一个非主节点后问题不再,就将剩余节点全部重启,至此所有应用全部恢复正常 。
这里记录的是解决问题的步骤,但通过两边参考文章的内容可以得出etcdctl恢复快照数据的操作纯粹是一个本地操作,无需像第一篇文章一样需要通过选项指定证书、地址及恢复目录。指定了恢复目录反而导致无法在现有容器中完成恢复。
PS: 不能在etcd容器中直接将/var/lib/etcd/下的member目录删除,因为etcd是基于其运行的,如果直接删除会导致etcd进程中断,从而导致kubernetes的etcd容器终止并重启。