Velero 备份钩子(Backup Hooks)完全指南:通过 Pod 注解与 Backup Spec 在备份前后执行容器命令

📅 发布时间:2026/9/17 14:03:29
Velero 备份钩子(Backup Hooks)完全指南:通过 Pod 注解与 Backup Spec 在备份前后执行容器命令
Velero 备份钩子Backup Hooks完全指南通过 Pod 注解与 Backup Spec 在备份前后执行容器命令【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero本篇技术指南围绕 Velero其前身为 Heptio Ark的 Backup Hooks 机制展开系统讲解如何在备份过程中、以 Pod 注解Annotation或 Backup 资源规格Spec两种方式在 Pod 容器内执行自定义命令Exec Hook。读完本文你将掌握 pre/post 钩子的执行时机与适用场景、全部注解键与字段的参数含义、基于fsfreeze冻结文件系统的实战示例以及钩子在备份主流程中的底层调用链与错误处理策略。Backup Hooks 是什么Backup Hooks 是 Velero 提供的一项能力用于在备份 Pod 时在 Pod 容器内执行命令。在 site/content/docs/v0.9.0/hooks.md 中该能力最初以 Heptio Ark 的名义提出执行备份时你可以为正在被备份的 Pod 指定一条或多条要执行的命令。钩子分为两类按执行时机区分Pre Hook在自定义动作custom actions处理之前执行。Ark v0.7.0 之前的版本只支持这一类钩子。Post Hook在 v0.7.0 及以后版本引入在所有自定义动作完成后、并且自定义动作指定的所有附加资源additional items也完成备份之后执行。一个典型的双钩子场景是冻结文件系统如果你想确保在快照前所有挂起的磁盘 I/O 操作都已落盘可以用 pre hook 执行fsfreeze --freezeArk/Velero 随后对磁盘打快照最后用 post hook 执行fsfreeze --unfreeze解冻。当前源码中Post Hook 还会额外等待该 Pod 相关的 PodVolumeBackupPVB处理完毕后才执行详见下文源码视角一节。指定钩子的两种方式在 v0.9.0 文档中钩子有两种指定途径Pod 自身的注解Annotations直接作用于单个 Pod粒度最细Backup 资源规格Backup Spec通过spec.hooks声明可结合命名空间、资源类型和标签选择器批量命中多个 Pod。两种方式并存且优先级明确源码 internal/hook/item_hook_handler.go 中Pod 注解中声明的钩子优先于Backup Spec 中定义的钩子被执行仅当 Pod 上没有相应注解时才会去匹配 Backup Spec 中定义的资源钩子。方式一以 Pod 注解指定钩子在 Pod 上添加注解即可让备份时执行钩子。v0.9.0 文档给出的是 Heptio Ark 时代的注解键前缀ark.heptio.com而在当前仓库源码中注解键前缀已随项目更名演变为velero.io见 internal/hook/item_hook_handler.go// Backup hook annotations podBackupHookContainerAnnotationKey hook.backup.velero.io/container podBackupHookCommandAnnotationKey hook.backup.velero.io/command podBackupHookOnErrorAnnotationKey hook.backup.velero.io/on-error podBackupHookTimeoutAnnotationKey hook.backup.velero.io/timeoutPre Hooks备份前执行注解名说明pre.hook.backup.前缀/container命令执行的容器名。默认使用 Pod 中第一个容器。可选。pre.hook.backup.前缀/command要执行的命令。如果需要多个参数以 JSON 数组形式给出如[/usr/bin/uname, -a]。必填。pre.hook.backup.前缀/on-error命令返回非零退出码时的处理策略。默认为Fail。合法值为Fail和Continue。可选。pre.hook.backup.前缀/timeout等待命令执行完成的最长时间超时即视为钩子执行出错。默认为30s。可选。其中前缀在 v0.9.0 时代为ark.heptio.com即完整注解形如pre.hook.backup.ark.heptio.com/command。Post Hooks备份后执行v0.7.0注解名说明post.hook.backup.前缀/container命令执行的容器名。默认使用 Pod 中第一个容器。可选。post.hook.backup.前缀/command要执行的命令。多参数时以 JSON 数组给出如[/usr/bin/uname, -a]。必填。post.hook.backup.前缀/on-error命令返回非零退出码时的处理策略。默认为Fail。合法值为Fail和Continue。可选。post.hook.backup.前缀/timeout等待命令执行完成的最长时间超时即视为钩子执行出错。默认为30s。可选。遗留Legacy注解兼容v0.7.0 及以后版本继续支持早期已废弃的 pre hook 指定方式——注解名中不带pre.前缀例如hook.backup.ark.heptio.com/container。这一兼容逻辑在当前源码中依然保留getPodExecHookFromAnnotations在 pre 阶段未找到带阶段前缀的注解时会退回查找不带阶段前缀的键见 internal/hook/item_hook_handler.go。注解解析细节command注解是钩子是否生效的开关源码getPodExecHookFromAnnotations中只有command注解存在时才会构造 ExecHook否则直接返回 nil见 internal/hook/item_hook_handler.go。command支持两种写法以[开头的 JSON 数组会被反序列化为多参数命令否则整串作为一个参数追加见parseStringToCommandinternal/hook/item_hook_handler.go。on-error注解值如果不是Continue或Fail会被置空最终在ExecutePodCommand中回退到默认值Fail。timeout注解通过time.ParseDuration解析支持30s、5m等格式解析失败时记录告警日志并使用默认值。方式二在 Backup Spec 中指定钩子在 Backup 资源规格中通过spec.hooks声明钩子可以按命名空间、资源类型、标签选择器批量匹配是生产环境最常用的方式。完整的 Backup API 字段说明见 Backup API 类型文档其核心结构在 pkg/apis/velero/v1/backup_types.go 中有对应实现。以下是文档中给出的、带 hooks 的完整 Backup 示例# Standard Kubernetes API Version declaration. Required. apiVersion: ark.heptio.com/v1 # Standard Kubernetes Kind declaration. Required. kind: Backup # Standard Kubernetes metadata. Required. metadata: # Backup name. May be any valid Kubernetes object name. Required. name: a # Backup namespace. Required. In version 0.7.0 and later, can be any string. Must be the namespace of the Ark server. namespace: heptio-ark # Parameters about the backup. Required. spec: # Array of namespaces to include in the backup. If unspecified, all namespaces are included. # Optional. includedNamespaces: - * # Array of namespaces to exclude from the backup. Optional. excludedNamespaces: - some-namespace # Array of resources to include in the backup. Resources may be shortcuts (e.g. po for pods) # or fully-qualified. If unspecified, all resources are included. Optional. includedResources: - * # Array of resources to exclude from the backup. Resources may be shortcuts (e.g. po for pods) # or fully-qualified. Optional. excludedResources: - storageclasses.storage.k8s.io # Whether or not to include cluster-scoped resources. Valid values are true, false, and # null/unset. If true, all cluster-scoped resources are included (subject to included/excluded # resources and the label selector). If false, no cluster-scoped resources are included. If unset, # all cluster-scoped resources are included if and only if all namespaces are included and there are # no excluded namespaces. Otherwise, if there is at least one namespace specified in either # includedNamespaces or excludedNamespaces, then the only cluster-scoped resources that are backed # up are those associated with namespace-scoped resources included in the backup. includeClusterResources: null # Individual objects must match this label selector to be included in the backup. Optional. labelSelector: matchLabels: app: ark component: server # Whether or not to snapshot volumes. This only applies to PersistentVolumes for Azure, GCE, and # AWS. Valid values are true, false, and null/unset. If unset, Ark performs snapshots as long as # a persistent volume provider is configured for Ark. snapshotVolumes: null # The amount of time before this backup is eligible for garbage collection. ttl: 24h0m0s # Actions to perform at different times during a backup. The only hook currently supported is # executing a command in a container in a pod using the pod exec API. Optional. hooks: # Array of hooks that are applicable to specific resources. Optional. resources: - # Name of the hook. Will be displayed in backup log. name: my-hook # Array of namespaces to which this hook applies. If unspecified, the hook applies to all # namespaces. Optional. includedNamespaces: - * # Array of namespaces to which this hook does not apply. Optional. excludedNamespaces: - some-namespace # Array of resources to which this hook applies. The only resource supported at this time is # pods. includedResources: - pods # Array of resources to which this hook does not apply. Optional. excludedResources: [] # This hook only applies to objects matching this label selector. Optional. labelSelector: matchLabels: app: ark component: server # An array of hooks to run before executing custom actions. Currently only exec hooks are supported. # DEPRECATED. Use pre instead. hooks: # Same content as pre below. # An array of hooks to run before executing custom actions. Currently only exec hooks are supported. pre: - # The type of hook. This must be exec. exec: # The name of the container where the command will be executed. If unspecified, the # first container in the pod will be used. Optional. container: my-container # The command to execute, specified as an array. Required. command: - /bin/uname - -a # How to handle an error executing the command. Valid values are Fail and Continue. # Defaults to Fail. Optional. onError: Fail # How long to wait for the command to finish executing. Defaults to 30 seconds. Optional. timeout: 10s # An array of hooks to run after all custom actions and additional items have been # processed. Currently only exec hooks are supported. post: # Same content as pre above.需要特别说明的是顶层hooks字段对应BackupResourceHookSpec中不区分 pre/post 的旧式hooks数组已标记为DEPRECATED文档明确建议改用pre字段post字段则存放自定义动作及其附加项全部处理完毕后执行的钩子。Spec 钩子的匹配规则从 pkg/apis/velero/v1/backup_types.go 的类型定义可以看到每个resources条目BackupResourceHookSpec通过以下规则决定是否命中某个对象includedNamespaces/excludedNamespaces指定钩子适用的命名空间白名单/黑名单两者都为空时对所有命名空间生效includedResources/excludedResources指定适用的资源类型当前版本仅支持podslabelSelector仅对匹配该标签选择器的对象生效name钩子名称会显示在备份日志中便于排查。对应的匹配实现在ResourceHookSelector.applicableTointernal/hook/item_hook_handler.go命名空间、资源类型、标签三者全部通过才命中。源码视角钩子的执行时机与调用链执行入口pre 先于自定义动作post 等待卷备份完成钩子由kubernetesBackupper在处理备份项item block时调用。在 pkg/backup/backup.go 中可以看到两条明确的执行路径handleItemBlockPreHooks遍历需要执行钩子的 Pod 列表逐个调用itemHookHandler.HandleHooks(..., hook.PhasePre, ...)执行失败的 Pod 被归入失败列表并收集错误handleItemBlockPostHooks先调用waitUntilPVBsProcessed等待该 Pod 相关的所有 PodVolumeBackup 处理完毕再逐个执行hook.PhasePost钩子——这正是文档所说post 钩子在所有自定义动作及附加项备份完成后执行的代码级保证。而DefaultItemHookHandler.HandleHooksinternal/hook/item_hook_handler.go是最终的钩子分派逻辑仅对 Pod 资源生效先检查 Pod 注解注解缺失时才遍历 Backup Spec 中的资源钩子并依据选择器匹配对于onError: Fail的钩子一旦失败会记录modeFailError并停止执行同阶段后续钩子。命令执行基于 Pod Exec API钩子命令通过 Pod Exec API 在容器内执行实现在 pkg/podexec/pod_command_executor.gocontainer未指定时自动使用 Pod 中第一个容器setDefaultHookContainer指定了container但容器不存在时直接报错ensureContainerExistscommand为空报错command is requiredonError非Fail/Continue时默认回退为Failtimeout不大于 0 时使用默认值defaultTimeout30s且存在上限maxHookTimeout防止异常配置导致命令无限期挂起。同时该实现明确提示超时发生时命令并不保证被终止它可能继续在后台运行见 pkg/podexec/pod_command_executor.go设计上应当把钩子命令做成幂等、可重入的。错误语义Fail 与 ContinueHookErrorMode定义了两种错误语义pkg/apis/velero/v1/backup_types.goContinue钩子出错可接受继续执行其余钩子Fail钩子出错即停止执行后续钩子并向备份流程返回错误。需要留意的是无论Fail还是Continue出错钩子都会被HookTracker记录并最终体现在备份/恢复的状态中PartiallyFailed等因此钩子失败不会轻易让整个备份静默失败而是可观测的。实战建议优先使用 Backup Spec 声明钩子相比逐个 Pod 打注解spec.hooks支持按命名空间/资源/标签批量命中且字段结构化、可审计。用fsfreeze冻结文件系统时务必成对配置pre 冻结fsfreeze --freeze post 解冻fsfreeze --unfreeze且解冻钩子的onError应保持默认Fail避免冻结状态残留。合理设置timeout默认 30s对启动慢的容器或大数据量同步场景可适当调大但注意存在上限约束超时后命令不保证被终止命令本身应具备幂等性。command 的多参数写法多个参数务必写成 JSON 数组如[/usr/bin/uname, -a]单字符串写法会把整串当作单一参数传递。利用钩子名称与日志排查Spec 中每个 hook 的name会随hookName、hookContainer、hookCommand、hookTimeout等字段一起出现在备份日志中见 pkg/podexec/pod_command_executor.go失败定位一目了然。相关资源钩子文档原文site/content/docs/v0.9.0/hooks.mdBackup API 类型完整字段site/content/docs/v0.9.0/api-types/backup.mdAPI 类型定义BackupHooks / BackupResourceHookSpec / ExecHook / HookErrorModepkg/apis/velero/v1/backup_types.go钩子分派与注解解析实现internal/hook/item_hook_handler.go备份主流程中 pre/post 钩子的调用点pkg/backup/backup.goPod Exec 命令执行器pkg/podexec/pod_command_executor.go【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考