Velero(Heptio Ark)Backup Hooks 完全指南:用 pre/post Hooks 实现备份前后自定义命令
2026/9/17 20:27:15 网站建设 项目流程

Velero(Heptio Ark)Backup Hooks 完全指南:用 pre/post Hooks 实现备份前后自定义命令

【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero

导读

本文基于 Velero 项目早期版本(v0.8.0,彼时项目名为 Heptio Ark)的官方文档 hooks.md 编写,系统讲解备份(Backup)过程中如何让 Velero 在被备份的 Pod 容器内执行自定义命令。你将掌握两种 hooks 声明方式(Pod 注解与 Backup spec)、pre/post 两类执行时机,以及以fsfreeze冻结文件系统为代表的真实生产场景,并结合 backup_types.go 源码理解 hooks 的底层数据模型与错误处理语义。

Backup Hooks 是什么

Heptio Ark(现 Velero)在执行备份时,支持在被备份的 Pod 的容器中执行一条或多条命令,这类命令称为Backup Hooks。核心价值在于:你可以在"对象被序列化进备份"这一时刻的前后插入自定义动作,为那些需要一致性保证的应用(如数据库、文件系统)提供数据固化能力。

两类执行时机:pre 与 post

  • pre hooks(备份前钩子):在 Pod 被备份、且任何自定义 action(item action)处理之前执行。Ark v0.7.0 之前的版本只支持这一种 hooks。
  • post hooks(备份后钩子):在所有自定义 action 完成、且自定义 action 所产生的所有附加对象(additional items)都已被备份之后执行。该能力自 v0.7.0 起引入。

当前版本(main 分支)的文档 backup-hooks.md 补充了一个重要细节:hooks 不会在容器的 shell 中被执行(not executed within a shell)。因此如果你的命令需要 shell 语法(管道、环境变量、&&连接),必须在 command 数组开头显式放入容器支持的 shell 解释器,如/bin/sh

典型场景:冻结文件系统

文档给出的经典示例是文件系统冻结。如果你希望在磁盘快照前确保所有待处理的磁盘 I/O 已完成:

  1. pre hook执行fsfreeze --freeze冻结文件系统;
  2. Ark 对磁盘拍摄快照;
  3. post hook执行fsfreeze --unfreeze解冻文件系统。

方式一:通过 Pod 注解指定 Hooks

在 Pod 上声明注解即可让 Ark 备份该 Pod 时执行 hook。v0.8.0 文档中的注解域名为backup.ark.heptio.com(在后续版本中更名为backup.velero.io,见 backup-hooks.md)。

Pre hooks 注解

注解名称说明
pre.hook.backup.ark.heptio.com/container命令执行的容器。默认使用 Pod 中的第一个容器。可选。
pre.hook.backup.ark.heptio.com/command要执行的命令。如需多个参数,请将命令写成 JSON 数组,例如["/usr/bin/uname", "-a"]
pre.hook.backup.ark.heptio.com/on-error命令返回非零退出码时的处理策略。默认Fail,合法值为FailContinue。可选。
pre.hook.backup.ark.heptio.com/timeout命令执行的最大等待时间,超时即视为 hook 出错。默认30s。可选。

Post hooks 注解(v0.7.0+)

注解名称说明
post.hook.backup.ark.heptio.com/container命令执行的容器。默认使用 Pod 中的第一个容器。可选。
post.hook.backup.ark.heptio.com/command要执行的命令。如需多个参数,请将命令写成 JSON 数组,例如["/usr/bin/uname", "-a"]
post.hook.backup.ark.heptio.com/on-error命令返回非零退出码时的处理策略。默认Fail,合法值为FailContinue。可选。
post.hook.backup.ark.heptio.com/timeout命令执行的最大等待时间,超时即视为 hook 出错。默认30s。可选。

兼容性说明(重要)

Ark v0.7.0+继续支持旧式的 pre hook 写法——即注解名不带pre.前缀(例如hook.backup.ark.heptio.com/container),但该写法已被标记为deprecated(已弃用)

实战:给已有 Pod 打上 fsfreeze 注解

仓库中的 examples/nginx-app/with-pv.yaml 就是一个完整的声明式示例:Deployment 的 Pod 模板通过注解声明了 pre/post 两组 fsfreeze 命令,并专门部署了一个名为fsfreezeprivileged: true辅助容器(Ubuntu 镜像、挂载/var/log/nginx)来执行冻结/解冻操作。

如果要对一个已运行的 Pod 原地添加注解,可参考 backup-hooks.md 中的命令(注意新版注解域名):

kubectl annotate pod -n nginx-example -l app=nginx \ pre.hook.backup.velero.io/command='["/sbin/fsfreeze", "--freeze", "/var/log/nginx"]' \ pre.hook.backup.velero.io/container=fsfreeze \ post.hook.backup.velero.io/command='["/sbin/fsfreeze", "--unfreeze", "/var/log/nginx"]' \ post.hook.backup.velero.io/container=fsfreeze

方式二:在 Backup spec 中指定 Hooks

对于更精细的控制(如按 namespace / resource / label 筛选 hook 的生效范围),应在 Backup 自定义资源对象的spec.hooks字段中声明。v0.8.0 的 Backup API 完整示例见 site/content/docs/v0.8.0/api-types/backup.md,其中 hooks 部分的骨架如下:

apiVersion: ark.heptio.com/v1 kind: Backup metadata: name: a namespace: heptio-ark spec: # ... 其他备份参数(includedNamespaces 等) hooks: # 适用于特定资源的 hooks 数组。可选。 resources: - # hook 名称,会显示在备份日志中。 name: my-hook # 该 hook 生效的 namespace 数组。不指定则应用于所有 namespace。可选。 includedNamespaces: - '*' # 该 hook 不生效的 namespace 数组。可选。 excludedNamespaces: - some-namespace # 该 hook 生效的资源类型数组。当前仅支持 pods。可选。 includedResources: - pods # 该 hook 不生效的资源类型数组。可选。 excludedResources: [] # 只有匹配该 label selector 的对象才生效。可选。 labelSelector: matchLabels: app: ark component: server # 在自定义 actions 执行前运行的 hooks 数组。当前仅支持 "exec" 类型。 # 已弃用,请改用 pre。 hooks: # 内容与下面的 pre 相同。 # 在自定义 actions 执行前运行的 hooks 数组。当前仅支持 "exec" 类型。 pre: - # hook 类型,必须为 "exec"。 exec: # 执行命令的容器名。不指定则使用 Pod 中的第一个容器。可选。 container: my-container # 要执行的命令,以数组形式给出。必填。 command: - /bin/uname - -a # 命令执行出错时的处理方式。合法值为 Fail 和 Continue,默认 Fail。可选。 onError: Fail # 等待命令执行完成的最长时间。默认 30 秒。可选。 timeout: 10s # 在所有自定义 actions 及附加对象处理完毕后运行的 hooks 数组。当前仅支持 "exec" 类型。 post: # 内容与上面的 pre 相同。

在 spec 中使用 shell 与环境变量

由于 hook 命令默认不经过 shell,若需要多条命令或读取容器环境变量,需要显式包装 shell。例如,要对名为mysql的 Pod 使用其MYSQL_ROOT_PASSWORD环境变量执行FLUSH TABLES WITH READ LOCK(该写法来自 backup-hooks.md,注意当前版本使用velero.io资源):

pre: - exec: container: mysql command: - /bin/sh - -c - mysql --password=$MYSQL_ROOT_PASSWORD -e "FLUSH TABLES WITH READ LOCK" onError: Fail

使用多条命令时,可以把目标命令包进 shell,用;&&等连接,例如:

pre.hook.backup.velero.io/command='["/bin/bash", "-c", "echo hello > hello.txt && echo goodbye > goodbye.txt"]'

注意:容器内必须存在你所引用的 shell 解释器。

源码级解析:Hooks 的数据模型与错误语义

从 pkg/apis/velero/v1/backup_types.go 可以看到 hooks 在 Velero API 中的完整类型定义,与上面 YAML 一一对应:

  • BackupHooks仅包含Resources []BackupResourceHookSpec一个字段,即"针对具体资源的 hooks 数组";
  • BackupResourceHookSpec承载筛选规则includedNamespacesexcludedNamespacesincludedResourcesexcludedResourceslabelSelector)以及两类执行序列PreHooksPostHooks
  • BackupResourceHook目前只封装Exec *ExecHook一种实现(即通过 Kubernetes Pod Exec API 在容器内执行命令,这一点与 v0.8.0 文档中"当前仅支持 exec 类型"的描述一致);
  • ExecHook字段:Container(默认第一个容器)、Command+kubebuilder:validation:MinItems=1,即命令数组至少一项)、OnErrorTimeoutmetav1.Duration)。

HookErrorMode:Fail 与 Continue 的真实语义

HookErrorMode是 hooks 错误处理的核心枚举,源码注释给出了精确语义:

  • HookErrorModeContinue:hook 出错可接受,备份/恢复继续执行其余 hooks,最终备份状态为PartiallyFailed
  • HookErrorModeFail:hook 出错是严重问题,Velero 会停止执行后续 hooks,备份状态同样为PartiallyFailed

可见FailContinue的区别在于"是否继续执行后续 hooks",而非"整个备份是否失败"——两者最终都表现为PartiallyFailed,这与很多使用者的直觉不同。

Hook 执行结果的统计

在 pkg/backup/backup.go 中,备份完成时 Velero 会将itemBackupper.hookTracker统计的HooksAttempted(尝试执行的 hook 数)与HooksFailed(失败的 hook 数)写入备份状态:

updated.Status.HookStatus.HooksAttempted, updated.Status.HookStatus.HooksFailed = itemBackupper.hookTracker.Stat()

相应地,用户可通过velero backup describe <backup name>查看这两项统计;若存在失败,详细原因会出现在Errors部分:

HooksAttempted: 1 HooksFailed: 0

验证与排障

  1. 创建备份并观察:按上面的注解或 spec 配置好 hooks 后创建备份:
    velero backup create nginx-hook-test
  2. 查看备份状态velero backup get nginx-hook-test确认备份未进入PartiallyFailed/Failed状态。
  3. 检查 hook 执行日志velero backup logs nginx-hook-test | grep hookCommand,用于确认 pre/post hook 是否被触发且正常退出(在 v0.8.0 时代日志中可通过hookCommand关键字过滤;当前版本已升级为通过velero backup describe查看 HooksAttempted/HooksFailed 统计)。
  4. 关注状态字段:备份处于PartiallyFailed时,优先在备份描述与日志的 Errors 段中定位具体是哪个 hook、哪条命令出错,再依据onError语义决定是修复命令还是改为Continue放行。

小结

Backup Hooks 是 Velero 实现应用一致性备份的关键机制:pre hook 在对象备份前执行,post hook 在自定义 action 及其附加对象全部备份后执行,二者搭配即可覆盖"冻结—快照—解冻"这类完整时序。声明方式上,Pod 注解适合快速、单对象的钩子注入(注意ark.heptio.com旧域名及其不带pre.前缀的弃用写法);Backup spec 则提供按 namespace/resource/label 筛选的精细控制。理解Fail/ContinuePartiallyFailed状态的关系,以及HooksAttempted/HooksFailed统计,能帮助你更准确地解读备份结果并快速定位问题。

【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询