当前位置:首页 > 问答 > 正文

备份Kubernetes时那些容易忽略但又特别管用的方法和技巧分享

很多人一想到备份Kubernetes,可能立刻会去研究如何用Velero这样的专业工具来备份Etcd或者整个命名空间,这当然没错,但备份的完整性远不止于此,有些东西,如果你忘了备份,等到灾难发生时,可能会发现即使恢复了集群,应用也无法正常运行。

第一点,也是最容易被忽略的:备份应用配置,而不仅仅是数据。

很多人只记得备份持久化卷里的应用数据(比如数据库里的记录),却忘了备份那些让应用能正确访问这些数据的“钥匙”,这包括:

  • 存储类名称: 你的PVC会指定一个storageClassName,如果这个存储类在恢复的新集群中不存在或名称不匹配,即使你成功恢复了PVC的声明,也无法自动绑定到正确的存储上,务必备份StorageClass的定义,甚至需要备份底层云供应商的存储快照策略。
  • 镜像拉取密钥: 你的Deployment或Pod定义中,很可能引用了名为imagePullSecrets的密钥,用于从私有镜像仓库拉取镜像,如果只恢复了工作负载定义,但没有恢复这个密钥,新集群会因为拉不到镜像而无法启动Pod,记得用kubectl get secret <secret-name> -o yaml把这些密钥也备份下来。
  • ConfigMap和Secret: 这是重灾区,应用的配置文件、环境变量、TLS证书、密码等几乎都存放在ConfigMap和Secret中,Velero等工具默认会备份命名空间内的这些资源,但如果你是自己写脚本备份YAML文件,极有可能漏掉它们,务必确保它们和应用的工作负载一起备份,特别是那些通过环境变量注入的敏感信息,一旦丢失,很难凭记忆重建。

第二点,备份集群的“入口”和“网络”规则。

你的应用能被外界访问,靠的是Ingress、Service这些资源,但有时候,一些关键的配置容易被忽略:

  • Ingress Controller的配置: 如果你使用的是Nginx Ingress Controller等,你可能对它进行过自定义配置,例如通过ConfigMap设置了全局参数,或者为特定服务配置了注解,这些配置决定了流量如何路由、是否启用SSL等,备份应用Ingress的同时,别忘了备份Ingress Controller自身的配置。
  • LoadBalancer的注解: 在云环境下,创建Service类型为LoadBalancer时,经常会用注解来配置负载均衡器的特定行为,比如健康检查路径、超时时间、SSL策略等,如果只备份了Service的YAML,这些注解可能因为云厂商插件的默认行为而在新集群中产生不同的配置,导致网络访问异常。

第三点,考虑“应用一致性”备份,而不是简单的“崩溃一致性”备份。

这对于有状态应用(尤其是数据库)至关重要,简单粗暴地对持久化卷做快照,就像在电脑运行时直接拔掉电源然后做硬盘镜像,数据可能能恢复,但数据库文件很可能处于损坏状态,因为内存中的数据还没刷写到磁盘。

  • 正确做法: 在备份前,需要让应用进入一个“静止”状态,对于数据库,这意味着要么先将其优雅关闭,要么通过命令让其进入备份模式(例如MySQL的FLUSH TABLES WITH READ LOCK),Velero等工具支持通过“预备份钩子”来执行这些命令,在备份作业开始前,在Pod内执行一个脚本将数据库锁定或切换到只读模式;备份完成后,再通过“后备份钩子”解除锁定,虽然操作起来比直接快照麻烦,但这能确保恢复出来的数据是100%可用的。

第四点,备份的元数据:标签和注解。

Kubernetes的强大之处在于标签选择器,你的Service通过标签选择Pod,你的Deployment通过标签管理ReplicaSet,如果你只备份了资源的主体YAML,但丢失了这些标签,整个系统的服务发现和负载均衡就会失灵,确保你的备份工具或方法能够完整地保留资源的元数据。

第五点,定期验证备份的有效性,这是最容易被说但最难被坚持的。

备份了不代表能恢复,一个无法恢复的备份比没有备份更可怕,因为它给你制造了安全的假象。

  • 定期进行恢复演练: 理想情况下,应该建立一个隔离的测试集群,定期(比如每季度)用你的备份文件进行全流程恢复演练,验证的步骤包括:
    1. 应用是否能正常启动?
    2. 服务是否能被正确访问?
    3. 数据是否完整,能否进行读写操作?
    4. 所有配置(如密码、证书)是否生效?
  • 记录恢复SOP: 将成功的恢复步骤详细记录下来,形成标准操作程序,在真正的紧急情况下,紧张情绪容易导致操作失误,一份清晰的检查清单是无价的。

第六点,不要忘记集群层面的资源。

除了命名空间内的资源,还有一些集群级别的资源,如果你用了,也必须备份:

  • RBAC配置: 包括ClusterRole、ClusterRoleBinding、Role、RoleBinding,如果你的应用或运维流程依赖特定的权限设置,这些资源的丢失会导致权限错误。
  • 自定义资源定义: 如果你使用了像Prometheus Operator、Istio等扩展了Kubernetes API的工具,那么CRD就是核心,不先恢复CRD,你根本无法恢复依赖于这些CRD创建的自定义资源,Velero在备份时会默认处理命名空间内的资源,但集群范围的资源需要特别关注。

一个实用的技巧:使用kubectlget --export命令已经过时且不可靠。

在早期Kubernetes版本中,人们喜欢用kubectl get deployment -o yaml --export来获取一个“干净”的、不带集群特定信息的YAML,但这个标志已被弃用,且其行为不保证,更可靠的方法是直接使用kubectl get -o yaml,然后手动或通过脚本清理掉statusmetadata.uidmetadata.resourceVersion等集群状态字段,使用Velero这样的工具会自动处理这些问题。

备份Kubernetes的本质是备份应用的完整状态,而不仅仅是数据文件,它包括了应用代码(镜像)、应用配置(ConfigMap/Secret)、应用依赖(网络、存储配置)以及应用的权限和定义(RBAC/CRD),建立一个覆盖所有这些方面的、并经过定期验证的备份策略,才能真正做到高枕无忧。

备份Kubernetes时那些容易忽略但又特别管用的方法和技巧分享