利用Kubernetes卷快照实现高效的备份和恢复
推荐超级课程:
@TOC
介绍
对于像公司这样的组织来说,数据是其核心和灵魂,确保可靠的备份和恢复对于保护数据和维护业务连续性至关重要。随着Kubernetes在公司的服务和数据库中的采用日益增多,管理动态、容器化应用程序中的持久数据为传统的备份策略带来了新的挑战。确保数据的保护和可恢复性对于可用性、灾难恢复和合规性至关重要。
为了备份部署在Kubernetes上并将数据存储在持久卷中的数据库,我们探索了一些传统的备份方法,例如使用边车容器的手动转储或外部备份代理,但发现它们效率低下、复杂且非通用。然后,我们探索了一些Kubernetes原生的方法来备份底层卷中的数据,并发现了Kubernetes卷快照。这个Kubernetes原生解决方案可以帮助创建一致的、特定时间点的持久卷备份。它得到了各种CSI驱动程序的支持,提供了自动化的备份和恢复,使其成为保护有状态应用程序免受灾难或错误影响的理想选择。随着文章的深入,我们将进一步讨论更多细节。
关键术语
- 容器存储接口(CSI) — 一个标准,允许用户在Kubernetes集群中添加和配置存储提供程序。CSI是作为一个标准开发的,用于将任意块和文件存储系统暴露给Kubernetes等容器编排系统(COs)上的容器化工作负载。
- 有状态应用程序 — 随时间保留数据或状态的应用程序。例如:数据库、分布式系统和消息队列。
- 无状态应用程序 — 不在集群或持久存储中存储数据或应用程序状态的应用程序。
- 持久卷(PV) — 表示使用存储类别预配的实际存储资源。
- 持久卷声明(PVC) — Pod对持久存储的请求。
- 存储类别 — 存储类别提供了一种方式,供管理员描述他们提供的存储类别。
- 卷快照 — 存储系统上的卷的快照。
- 服务账户 — 一个非人类用户身份,用于验证并访问K8s apiserver。
- 恢复点目标(RPO) — 在发生灾难的情况下,在规定时间内可容忍的数据丢失量的度量。换句话说,在丢失数据量超过最大允许阈值之前的时间间隔。
- 恢复时间目标(RTO) — 在计划外中断后恢复备份并重新获得数据访问权的最大可接受时间。换句话说,从灾难中恢复的速度有多快。
- 全备份 — 全备份备份集群的所有数据。带有卷快照的全备份会捕获整个卷的即时点副本,包括所有数据。
- 增量备份 — 另一方面,增量备份只存储自上次快照以来所做的更改,显著减少了存储需求并加快了备份过程。在公司,我们正在利用增量备份的优点,只要底层数据存储支持它。
使用卷快照的备份过程
在公司,我们为应用程序数据库和备份控制器设置了不同的命名空间,以使用基于角色的访问控制(RBAC)维护适当的数据隔离和访问控制级别。应用程序DB命名空间中有DB服务Pod,底层数据存储在PVC中。
备份控制器是一个自定义控制器,旨在自动化和管理在Kubernetes上部署的数据库集群的备份。它监控与备份和恢复相关的自定义资源,并编排诸如触发卷快照、将数据导出到远程存储或维护备份计划等任务。这个备份控制器是使用Operator SDK构建的,Operator SDK是一个开源工具包,用于管理Kubernetes原生应用程序,以下简称备份操作符。这个备份操作符部署在一个专用的命名空间中,并根据为应用程序DB集群配置的计划负责调度和编排备份。
让我们深入了解使用卷快照的端到端备份过程的细节。
自动化备份和恢复服务的入门
不同应用程序数据库的恢复点目标(RPO)根据其业务和监管要求而有所不同。因此,通用的备份计划并不适用于所有数据库。为了使用自动化备份和恢复服务,各个数据库所有者创建一个备份配置。这个配置包含了他们的业务RPO,基于此备份操作符创建一个Kubernetes CronJob,代表该数据库的备份计划。例如,如果一个应用程序DB的RPO是2小时,这意味着他们最多可以承受丢失2小时的数据,这意味着备份至少应该每2小时发生一次。这被表示为一个Kubernetes CronJob,作为该DB的计划备份。
现在,让我们谈谈启用备份操作符访问数据库所有者命名空间中所需Kubernetes资源以进行数据备份的一些先决条件。
备份先决条件
- 源PVC — 应该存在一个PVC,它包含您想要备份的应用程序数据。
- 在备份操作符命名空间中创建一个ServiceAccount,该账户将用于访问DB应用程序命名空间中的资源。
- 授予上述备份操作符使用的Service Account在DB应用程序命名空间中创建和访问相关资源的基于角色的访问控制(RBAC)权限。
备份过程细节
- 我们的备份操作符在DB应用程序命名空间中创建上述PVC的即时点快照,即一个卷快照,源PVC所在的位置。
卷快照清单如下:
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: backup-snapshot
namespace: …
spec:
source:
persistentVolumeClaimName: pvc-test
volumeSnapshotClassName: …
- 使用上述快照,备份操作符在DB应用程序命名空间中创建一个PVC。这个PVC在快照拍摄时保存源pvc的数据。
PVC清单片段如下:
kind: PersistentVolumeClaim
metadata:
name: pvc-using-snapshot
spec:
storageClassName: …
volumeMode: Filesystem
dataSource:
apiGroup: snapshot.storage.k8s.io
kind: VolumeSnapshot
name: backup-snapshot
accessModes:
- ReadWriteOnce
resources:
requests:
storage: <source pvc size>
- 为了能够访问这个PVC中的数据,备份操作符现在创建一个Pod,该Pod挂载这个副本PVC。这个备份Pod现在将底层数据分块并备份到云存储。
Pod清单如下:
kind: Pod
metadata:
name: backup-pod
namespace: playground
spec:
volumes:
- name: data
persistentVolumeClaim:
claimName: pvc-using-snapshot
containers:
- name: backup-pod
image: …
volumeMounts:
- name: data
mountPath: /data
readOnly: true
- 关于这次备份的元数据存储在我们的数据库中,数据库中有关于这次备份的所有细节——备份名称、备份配置详情、备份大小、备份的云位置等。这些通过API和UI仪表板向客户公开。
预备份和后备份命令
我们还可以在备份配置中添加预备份和后备份命令,以在备份前后启用自动化操作,并为租户提供对其备份过程更多的控制。这些命令提供了以下额外的好处,使备份过程更加高效和定制:* 数据一致性:预备份命令可以用来暂停或静默应用程序,确保所有内存中的数据被刷新到磁盘,这对于数据库和事务性系统的一致性备份至关重要。例如,像MySQL这样的数据库可以使用FLUSH TABLES WITH READ LOCK
作为预备份命令,以确保在数据快照之前数据的一致性。
- 自定义清理:后备份命令可以触发删除临时文件或快照等操作,优化存储并保持备份环境整洁。它还可以用来还原备份前的操作,比如在备份完成后释放READ LOCK等。
此功能使通用的备份过程可定制,并通过允许数据库应用程序所有者定义增强其用例备份过程效率和可用性的操作,从而给他们更多的控制权。
使用Kubernetes卷快照恢复备份
恢复工作流程
- 为了能够恢复备份,数据库所有者应在他们的命名空间中创建一个空的PVC。
- 然后,数据库所有者将创建一个恢复作业清单,其中包含他们想要恢复的备份的详细信息(数据库应用程序所有者可以从使用备份配置的API或UI仪表板获取)以及他们想要恢复数据到的PVC。示例恢复作业清单:
name: <恢复作业名称>
spec:
template:
spec:
serviceAccountName: backup-sa
containers:
- name: restore-controller
image: restore-operator:<VERSION>
env:
- name: OPERATION
value: "restore"
- name: BACKUP_NAME
value: <备份名称>
- name: RESTORE_PVC_NAME
value: <恢复-pvc-名称>
resources:
…
volumeMounts:
- name: my-pvc
mountPath: "/mnt”
volumes:
- name: my-pvc
persistentVolumeClaim:
claimName: my-pvc-claim
上述恢复作业清单应用后,它将在数据库应用程序命名空间中创建一个恢复Pod。
恢复服务流程从云中获取所需的备份并将其恢复到PVC挂载路径。
目标PVC现在已准备好使用,可以根据需要挂载到适当的数据库服务Pod。
性能开销和挑战
由于写时复制导致的存储开销
当从源PVC创建快照时,它不会立即复制数据。相反,它使用写时复制机制,这意味着只有在快照之后对源PVC所做的更改被单独存储。最初,快照消耗最小的存储空间,但随着更改的累积,它可能需要显著额外的空间。随着时间的推移,如果保留多个快照,它们可能会集体消耗大量存储,并可能影响性能。例如:
源PVC分配大小:8 GB
源PVC实际数据大小:1 GB
卷快照大小:最初接近0 GB,根据创建快照后的更改使用额外存储。
新PVC的额外配额要求
当从快照创建新的PVC时,它消耗的存储空间等于源PVC的分配大小,无论实际数据大小如何。这意味着即使源PVC的实际数据很少,新的PVC仍然会保留原始源PVC的全部容量。例如:
源PVC分配大小:8 GB
源PVC实际数据大小:1 GB
新PVC大小:8 GB(保留整个分配大小)
为了确保存储开销保持在可控范围内,并且没有快照和PVC的积累,备份过程会在备份成功上传到云后删除它创建的所有资源。
磁盘类型约束
并非Kubernetes中的所有存储类都支持快照,因为快照功能仅限于由CSI驱动程序管理的块存储。不支持快照的存储类型包括本地或临时存储类型、网络文件系统等。因此,使用卷快照进行备份的这种解决方案依赖于底层存储类的CSI驱动程序提供的功能。
调试、监控和告警
此备份设置在不同的命名空间中具有多个故障点,因此强大的监控和告警至关重要。由于跨命名空间调试故障可能相当复杂,无论是在技术上还是在定义所有权和行动项目以解决问题方面,我们已经分离了备份失败告警以简化调试过程。使用我们的内部告警平台,有针对性的备份失败告警被发送到适当的团队:平台相关的问题发送到中央备份和恢复团队,而特定于数据库的告警则传达给数据库所有者团队。这种结构化的方法确保了及时确认和解决故障根本原因,确保配置的数据库没有RPO违规。
结论
在公司,使用Kubernetes卷快照作为捕获存储在持久卷中的数据的时间点副本以及根据需要恢复数据的有效解决方案。通过使用卷快照,我们实现了对实时应用程序影响最小的可靠备份。将卷快照与备份工作流程集成确保了数据一致性和快速恢复,这使得它成为公司备份和恢复平台的又一有益补充。