当您在 Google Kubernetes Engine 集群中启用 Backup for GKE 代理时,Backup for GKE 会提供引入一种新的 Kubernetes 资源 ProtectedApplication
的 CustomResourceDefinition
。
编写 ProtectedApplication
涉及两个活动:
为其中一部分资源详细信息定义详细的编排规则。
在应用级层自定义备份和恢复逻辑时,ProtectedApplication
资源为您提供以下功能:
更精细的备份和恢复操作。如果没有
ProtectedApplications
,您必须在Namespace
级层定义备份范围(通过选择 allNamespace 或 selectNamespace)。类似的逻辑适用于命名空间型资源恢复。通过创建ProtectedApplication
资源,您可以为Namespace
中的部分资源提供名称。然后,您可以在备份范围内列出 SelectedApplications,以备份和恢复该子集(对于恢复也是如此)。编排备份或恢复过程的精细详细信息,包括:
在备份期间跳过选定的卷。
将应用拓扑整合到备份和恢复中(例如,仅备份复制数据库的一个实例并使用它来恢复多个实例)。
在截取卷快照之前和之后,执行用户定义的钩子。例如,这些钩子可用于在截取快照前刷入工作负载并使其静默,并在之后取消静默。
与其他 Kubernetes 资源一样,您可以通过 kubectl
创建 ProtectedApplication
。它们是完全可选的。如果 ProtectedApplication
资源不存在,Backup for GKE 会为备份范围内的所有卷创建卷备份,生成的卷备份将具有崩溃一致性,即特定时间点刷入磁盘的所有写入都将被捕获(即没有部分写入)。但是,某些应用可能会将数据保留在未刷入磁盘的内存中,因此应用是否可以从崩溃一致的备份成功恢复取决于应用逻辑。
选择资源
构建 ProtectedApplication
资源的第一步是确定同一 Namespace
中要包含在应用中的其他资源。如果您在 BackupPlan
配置中提供了 selectedApplications 范围选项,那么这是将会备份或恢复的一组资源。
你可以使用标签选择器来识别资源。这要求您使用相同标签为所有资源加标签(使用每个资源中的 metadata.label 字段)。请注意,这也适用于控制器自动创建的资源。这些自动创建的资源通过其对应的模板来加标签。请注意,常见做法是重复使用已用于将生成的 Pods
和 PersistentVolumeClaims
与其父资源关联的同一标签。以下示例展示了如何将 app: nginx
标签应用于除 Deployment
之外的其他资源。
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-vars
namespace: webserver
labels:
app: nginx
data:
...
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-logs
namespace: webserver
labels:
app: nginx
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Mi
storageClassName: standard-rwo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: webserver
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
volumes:
- name: nginx-logs
persistentVolumeClaim:
claimName: nginx-logs
containers:
...
将所选标签应用于所有目标资源(以及生成其他资源的模板)后,您就可以从 ProtectedApplication
引用这些资源。例如:
kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1alpha2
metadata:
name: nginx
namespace: webserver
spec:
resourceSelection:
type: Selector
selector:
matchLabels:
app: nginx
...
定义编排规则
确定 ProtectedApplication
中的所有资源后,您可以选择为这一资源子集定义详细的编排规则。这些规则仅适用于这两种资源:Deployment 和 StatefulSet,并在 components
部分 ProtectedApplication
中引用。
组件概览
配置组件涉及以下任务:
选择此组件的备份和恢复的基本策略。有三种可用的策略:
BackupAllRestoreAll
- 备份与组件的所有实例关联的卷,并从备份恢复所有卷BackupOneRestoreAll
- 仅从组件的一个实例备份卷,并使用这些备份恢复所有实例DumpAndLoad
- 备份时将数据从应用导出到单个卷,并在恢复时将这些数据导入应用
定义在备份期间运行的执行钩子(也可能在恢复期间运行,具体取决于策略)。钩子是在特定容器中执行的命令。
执行钩子
钩子是 Backup for GKE 在备份或恢复过程的特定阶段在容器中执行的 shell 命令。
钩子有四种不同的类型:
pre hooks
- 这些命令在备份卷之前执行,通常用于将内存中的所有数据刷入磁盘,然后让应用处于静默状态,以避免发生新的磁盘写入。这些钩子在BackupAllRestoreAll
和BackupOneRestoreAll
策略中使用。post hooks
- 这些命令在卷备份过程中的截取快照步骤之后以及上传步骤之前执行。通常,截取快照步骤只需几秒钟时间。这些钩子通常用于取消应用静默(即允许继续执行正常处理和磁盘写入)。这些钩子在BackupAllRestoreAll
、BackupOneRestoreAll
和DumpAndLoad
策略中使用。dump hooks
- 这些命令在DumpAndLoad
策略中的备份卷步骤之前执行,通常用于将数据从应用导入指定的备份卷。load hooks
- 采用DumpAndLoad
策略时,这些命令在恢复备份卷后执行。它们通常用于将备份卷中的数据导入应用。
您可以为每个类型提供多个钩子,Backup for GKE 将按照您定义的顺序执行这些钩子。
您可以在 ProtectedApplication
规范的组件部分中定义钩子。所有钩子定义都具有相同的可用字段:
name
- 分配给钩子的名称。container
-(可选)要在其中运行命令的容器的名称。如果您未提供容器,Backup for GKE 会在为目标Pod
定义的第一个容器中运行钩子。command
- 这是发送到容器的实际命令,以字词数组的形式构建。数组中的第一个字词是该命令的路径,后续字词是要传递给该命令的参数。timeoutSeconds
-(可选)取消钩子执行之前的时间。如果未提供值,则默认为 30 秒。onError
-(可选)钩子失败时采取的行为。可以设置为Ignore
或Fail
(默认)。如果将此字段设置为Fail
,则当钩子失败时,卷备份将失败。如果将此字段设置为Ignore
,则此钩子的失败将被忽略。
将 ProtectedApplication
钩子应用于您的应用之前,您应使用 kubectl exec
测试该命令,以确保钩子的行为符合预期:
kubectl exec POD_NAME -- COMMAND
请替换以下内容:
POD_NAME
:包含ProtectedApplication
资源的 Pod 的名称。COMMAND
:包含要在容器中运行的命令的数组,例如/sbin/fsfreeze, -f, /var/log/nginx
。
选择要备份的卷子集
有时,应用会写入不需要恢复的卷(例如,某些日志或暂存卷)。您可以使用卷选择器阻止备份这些卷。
要使用此功能,您必须先将一个常用标签应用于要备份的卷,然后对于不想备份的卷则不应用该标签。然后,您可以在组件定义中添加 volumeSelector
子句,如下所示:
spec:
...
components:
...
strategy:
...
volumeSelector:
matchLabels:
label_name: label_value
如果您为组件提供 volumeSelector
,则只会备份和恢复具有给定标签的卷。恢复时,任何其他卷将预配为空,而不是从卷备份中恢复。
策略:BackupAllRestoreAll
这是最简单的策略,它会在备份时备份组件的所有卷,并在恢复时从其卷备份中恢复所有卷。如果您的应用在 Pods
之间没有复制,那么这是最佳选择。
此策略支持以下参数:
backupPreHooks
:(可选)在备份卷之前执行的钩子的有序列表。这些命令在组件中的所有Pods
上执行。backupPostHooks
-(可选)在卷备份到达上传阶段后执行的钩子的有序列表。这些命令在组件中的所有Pods
上执行。volumeSelector
-(可选)用于匹配要备份的卷子集的逻辑。
此示例会创建一项 ProtectedApplication
资源,以在备份日志卷之前将文件系统设为静默状态,并在备份后取消静默状态:
kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1alpha2
metadata:
name: nginx
namespace: sales
spec:
resourceSelection:
type: Selector
selector:
matchLabels:
app: nginx
components:
- name: nginx-app
resourceKind: Deployment
resourceNames: ["nginx"]
strategy:
type: BackupAllRestoreAll
backupAllRestoreAll:
backupPreHooks:
- name: fsfreeze
container: nginx
command: [ /sbin/fsfreeze, -f, /var/log/nginx ]
backupPostHooks:
- name: fsunfreeze
container: nginx
command: [ /sbin/fsfreeze, -u, /var/log/nginx ]
策略:BackupOneAndRestoreAll
此策略会备份所选 Pod 的一个副本。该单个副本是恢复期间用于恢复所有 Pod 的来源。这种方法可以帮助降低存储费用和缩短备份时间。此策略适合高可用性配置,此时使用一个主要 PersistentVolumeClaim
和多个辅助 PersistentVolumeClaims
部署组件。
此策略支持以下参数:
backupTargetName
:(必需)指定要用于备份数据的 Deployment 或 StatefulSet。系统会自动选择最适合用于备份的 Pod。在高可用性配置中,我们建议您将其设置为一个应用副本。backupPreHooks
:(可选)在备份卷之前执行的钩子的有序列表。这些命令仅在选定的备份Pod
上执行。backupPostHooks
-(可选)在卷备份到达上传阶段后执行的钩子的有序列表。这些命令仅在选定的备份Pod
上执行。volumeSelector
-(可选)用于匹配要备份的卷子集的逻辑。
如果某个组件配置了多个 Deployment 或 StatefulSet,则所有资源都必须具有相同的 PersistentVolume 结构,这意味着它们必须遵循以下规则:
- 所有 Deployment 或 StatefulSet 使用的
PersistentVolumeClaims
数量必须相同。 - 同一索引中
PersistentVolumeClaims
的用途必须相同。对于 StatefulSet,索引在volumeClaimTemplate
中定义。对于 Deployment,索引在Volumes
中定义,且所有非永久性卷都会被跳过。 - 如果应用组件由 Deployment 组成,则每个 Deployment 必须只有一个副本。
鉴于这些注意事项,您可以选择多个卷集进行备份,但只会从每个卷集中选择一个卷。
以下示例假设存在一个架构,它包含一个主要 StatefulSet 和一个辅助 StatefulSet,其中显示了对辅助 StatefulSet 中的一个 Pod 的卷进行备份,然后对所有其他卷进行恢复:
kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1alpha2
metadata:
name: mariadb
namespace: mariadb
spec:
resourceSelection:
type: Selector
selector:
matchLabels:
app: mariadb
components:
- name: mariadb
resourceKind: StatefulSet
resourceNames: ["mariadb-primary", "mariadb-secondary"]
strategy:
type: BackupOneRestoreAll
backupOneRestoreAll:
backupTargetName: mariadb-secondary
backupPreHooks:
- name: quiesce
container: mariadb
command: [...]
backupPostHooks:
- name: unquiesce
container: mariadb
command: [...]
策略:DumpAndLoad
此策略使用专用卷进行备份和恢复过程,并且需要将专用的 PersistentVolumeClaim
挂接到存储转储数据的组件。
此策略支持以下参数:
dumpTarget
:(必需)指定要用于备份数据的 Deployment 或 StatefulSet。系统会自动选择最适合用于备份的 Pod。在高可用性配置中,我们建议您将其设置为一个应用副本。loadTarget
:(必需)指定应使用哪个 Deployment 或 StatefulSet 来加载数据。系统会自动选择最适合用于备份的 Pod。加载目标不必与转储目标相同。dumpHooks
:(必需)为填充专用备份卷而执行的钩子的有序列表。这些命令仅在选定的转储Pod
上执行。backupPostHooks
-(可选)在卷备份到达上传阶段后执行的钩子的有序列表。这些命令仅在选定的转储Pod
上执行。loadHooks
:(必需)为了在应用启动后从恢复的卷加载数据而执行的钩子的有序列表。这些命令仅在选定的加载Pod
上执行。volumeSelector
:(必需)用于将单个卷与备份和恢复(“转储”卷)匹配的逻辑。虽然它必需只匹配单个卷,但您可以采用与其他策略使用的要备份的卷子集相同的方式配置此参数。
如果应用由 Deployment 组成,则每个 Deployment 必须只有一个副本。
以下示例假设了这样一个架构,它包含一个主要 StatefulSet 和一个辅助 StatefulSet,且具有同时用于主要和辅助 StatefulSet 的专用 PersistentVolumeClaims
。该示例显示了 DumpAndLoad
策略:
kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1alpha2
metadata:
name: mariadb
namespace: mariadb
spec:
resourceSelection:
type: Selector
selector:
matchLabels:
app: mariadb
components:
- name: mariadb-dump
resourceKind: StatefulSet
resourceNames: ["mariadb-primary", "mariadb-secondary"]
strategy:
type: DumpAndLoad
dumpAndLoad:
loadTarget: mariadb-primary
dumpTarget: mariadb-secondary
dumpHooks:
- name: db_dump
container: mariadb
command:
- bash
- "-c"
- |
mysqldump -u root --all-databases > /backup/mysql_backup.dump
loadHooks:
- name: db_load
container: mariadb
command:
- bash
- "-c"
- |
mysql -u root < /backup/mysql_backup.sql
volumeSelector:
matchLabels:
gkebackup.gke.io/backup: dedicated-volume
检查 ProtectedApplication
是否已准备好进行备份
您可运行以下命令来检查 ProtectedApplication
是否已准备好进行备份:
kubectl describe protectedapplication APPLICATION_NAME
将 APPLICATION_NAME
替换为应用的名称。
准备就绪后,应用说明会将 Ready to backup
状态显示为 true
,如以下示例所示:
% kubectl describe protectedapplication nginx
Name: nginx
Namespace: default
API Version: gkebackup.gke.io/v1alpha2
Kind: ProtectedApplication
Metadata:
UID: 90c04a86-9dcd-48f2-abbf-5d84f979b2c2
Spec:
Components:
Name: nginx
Resource Kind: Deployment
Resource Names:
nginx
Strategy:
Backup All Restore All:
Backup Pre Hooks:
Command:
/sbin/fsfreeze
-f
/var/log/nginx
Container: nginx
Name: freeze
Backup Post Hooks:
Command:
/sbin/fsfreeze
-u
/var/log/nginx
Container: nginx
Name: unfreeze
Type: BackupAllRestoreAll
Resource Selection:
Selector:
Match Labels:
app: nginx
Type: Selector
Status:
Ready To Backup: true
Events: <none>
后续步骤
- 详细了解如何规划一组备份。