扩展机制:Backup Hooks 与插件架构完全指南)
深入 ArkVelero 前身扩展机制Backup Hooks 与插件架构完全指南【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero导读本文围绕 ArkHeptio Ark即 Velero 的前身v0.7.0 时代项目代号官方文档中关于扩展核心能力的篇章展开系统讲解 Ark 提供的两套扩展机制Hooks钩子与Plugins插件。读完本文你将掌握如何在备份过程中通过 Pod 注解或 Backup Spec 注入自定义命令pre/post 钩子以配合数据库冻结、磁盘缓冲刷新等工作负载特定操作以及如何通过插件体系开发自定义对象存储后端、块存储后端与逐项per-item备份/恢复动作而无需重新编译 Ark 核心二进制。说明v0.7.0 文档仍使用项目旧名 Ark 与旧 API 组ark.heptio.com/v1。随着项目更名为 Velero当前仓库中对应实现已演进为velero.io/v1API 与新的注解前缀文中将同时给出历史与现状的对应关系并标注源码证据路径。一、为什么需要扩展机制ArkVelero是一个 Kubernetes 应用备份与迁移工具其核心备份/恢复流程是通用的收集资源、执行自定义动作、写入对象存储、恢复时回放。但真实业务场景中单一通用流程无法覆盖所有需求备份一个正在运行数据库 Pod 时可能需要先冻结文件系统fsfreeze --freeze确保磁盘 I/O 全部落盘后再做快照不同云厂商的对象存储AWS S3、Azure Blob、GCP GCS与块存储快照 API 各不相同某些业务资源在备份前需要临时改写例如移除指向集群内地址的引用恢复时又需要还原。Ark 通过两大机制解决上述问题见 extend.mdHooks钩子在备份过程中于正在运行的 Pod 容器内执行指定命令适合工作负载特定的命令例如刷新磁盘缓冲、冻结数据库。Plugins插件允许开发者实现自定义的对象存储/块存储后端或逐项per-item备份/恢复动作执行任意逻辑包括修改被备份/恢复的对象且无需编译进 Ark 核心二进制即可被 Ark 使用。二、Backup Hooks在备份中执行 Pod 内命令Ark 在备份时支持在 Pod 的容器内执行一条或多条命令。Ark v0.7.0 引入两个阶段的钩子详见 hooks.mdpre 钩子在任何自定义动作custom action处理之前执行。v0.7.0 之前仅支持 pre 钩子。post 钩子v0.7.0在所有自定义动作完成之后、且自定义动作所产生的所有附加资源additional items也都备份完毕之后执行。pre 与 post 最典型的配合场景是冻结文件系统先通过 pre 钩子执行fsfreeze --freeze确保所有待处理的磁盘 I/O 已完成再让 Ark 对磁盘做快照最后用 post 钩子执行fsfreeze --unfreeze解冻。钩子可通过两种方式指定Pod 上的注解annotations与Backup Spec备份定义。2.1 通过 Pod 注解指定钩子在 Pod 上使用以下注解即可让 Ark 备份该 Pod 时执行钩子。Pre 钩子注解注解名称说明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。合法值为Fail和Continue。可选。pre.hook.backup.ark.heptio.com/timeout等待命令执行的最长时间超时即视为钩子执行出错。默认30s。可选。Post 钩子注解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。合法值为Fail和Continue。可选。post.hook.backup.ark.heptio.com/timeout等待命令执行的最长时间超时视为出错。默认30s。可选。兼容性说明Ark v0.7.0 仍然支持旧版已弃用的 pre 钩子写法——即注解名不带pre.前缀如hook.backup.ark.heptio.com/container。在项目演进为 Velero 后注解前缀相应变更为pre.hook.backup.velero.io/与post.hook.backup.velero.io/。从当前仓库的 内部钩子处理器实现 可以看到这一演进处理器DefaultItemHookHandler.HandleHooks首先从注解中解析钩子pre 阶段若找不到带阶段的注解还会回退检查不带阶段前缀的遗留注解键legacy hook annotation keys以兼容旧写法注解中解析出的钩子优先级最高If the pod has the hook specified via annotations, that takes priority.随后才检查 Backup Spec 中定义的钩子钩子目前只支持 Pod 资源We only support hooks on pods right now对非 Pod 资源直接跳过命令的解析由 parseStringToCommand 完成——单个字符串按空格拆分JSON 数组则解析为多参数命令执行阶段由PodCommandExecutor.ExecutePodCommand通过 Kubernetes Pod Exec API 在容器内运行命令若onError为Fail且执行出错pre/post 阶段会立即返回错误从而终止该备份项的处理详见 item_hook_handler.go。2.2 在 Backup Spec 中指定钩子除注解外还可以在 Backup 定义中按资源选择器 钩子列表的方式声明钩子。完整的字段注释可参考 Backup API Type 文档示例结构如下apiVersion: ark.heptio.com/v1 kind: Backup metadata: name: a namespace: heptio-ark spec: includedNamespaces: - * # ... 其他备份字段 ... hooks: resources: - name: my-hook includedNamespaces: - * excludedNamespaces: - some-namespace includedResources: - pods excludedResources: [] labelSelector: matchLabels: app: ark component: server # DEPRECATED. 旧写法等价于下面的 pre。 hooks: # 内容与 pre 相同 pre: - exec: container: my-container command: - /bin/uname - -a onError: Fail timeout: 10s post: # 内容与 pre 相同各字段语义hooks.resources适用于特定资源的钩子数组name钩子名称会显示在备份日志中includedNamespaces/excludedNamespaces钩子适用的命名空间范围未指定则作用于全部命名空间includedResources钩子适用的资源类型当前仅支持podslabelSelector钩子仅作用于匹配该标签选择器的对象hooks旧字段已弃用含义与pre相同pre在自定义动作执行之前运行的钩子数组目前仅支持exec类型exec.container命令执行容器缺省用 Pod 第一个容器exec.command命令数组必填如[/bin/uname, -a]exec.onError错误处理方式Fail默认或Continueexec.timeout执行超时时间默认 30 秒post在所有自定义动作及附加资源处理完成之后运行的钩子数组内容与pre相同。当前仓库中的类型定义佐证上述结构在现版本中对应 backup_types.go 中的BackupHooks、BackupResourceHookSpec、BackupResourceHook与ExecHook。其中字段注释直接沿用了文档语义PreHooks在将条目存入备份之前执行且先于 item action 产生的 additional items 处理PostHooks在所有 additional items 处理完之后执行。ExecHook的OnError由HookErrorMode类型约束Command有kubebuilder:validation:MinItems1校验至少一项Timeout使用metav1.Duration类型。选择器匹配逻辑命名空间/资源/标签对应 ResourceHookSelector.applicableTo。参考在 Backup Spec 中指定钩子时Ark 服务器侧的处理同样复用DefaultItemHookHandler先按选择器过滤出适用的resourceHookspre 阶段取resourceHook.Pre、post 阶段取resourceHook.Post逐个执行exec钩子并记录到HookTracker任一Fail模式钩子出错即中止该资源的后续钩子执行item_hook_handler.go。三、Plugins无需重编译的插件架构Ark 的插件架构让用户无需修改/重新编译核心二进制即可向备份与恢复流程添加自定义功能。开发者只需编写一个包含某种插件类型实现的小型二进制再配合少量样板代码将实现暴露给 Ark随后把这个二进制打入一个用作Ark server Pod 的 init container的容器镜像中由 init container 将二进制拷贝到 Ark server 共享的 emptyDir 卷中供其访问。官方提供了一个功能完整的[示例插件仓库]作为插件开发者的起点v0.7.0 时代为 heptio/ark-plugin-example即后续 velero-plugin-example 的前身。3.1 插件类型Plugin KindsArk 当前支持以下四种插件类型插件类型职责Object Store持久化与检索备份文件、备份日志、恢复日志Block Store备份时创建卷快照恢复时从快照还原卷Backup Item Action在单个条目存入备份文件之前对其执行任意逻辑Restore Item Action在单个条目恢复到集群之前对其执行任意逻辑在项目更名后Block Store 在现版本代码中对应VolumeSnapshotter接口见 manager.go 中的GetVolumeSnapshotter。现版本的插件体系通过 plugin 目录 组织接口定义位于 pkg/plugin/velero例如ObjectStore接口object_store.go、BackupItemAction接口backupitemaction/v1/backup_item_action.go、RestoreItemAction接口restoreitemaction/v1/restore_item_action.go插件客户端管理由 pkg/plugin/clientmgmt 实现Manager统一负责各类型插件的获取与生命周期管理插件间通信协议定义在 pkg/plugin/proto 的 gRPC.proto文件中例如ObjectStore.proto定义了PutObjectRequest、GetObjectRequest、DeleteObjectRequest、ListObjectsRequest、CreateSignedURLRequest等消息与ObjectStore服务BackupItemAction.proto定义了ExecuteRequest/ExecuteResponse与BackupItemAction服务每个插件进程通过独立的子进程restartable process加载并提供RestartableXxx包装层如 restartable_object_store.go保证插件崩溃后可重启恢复。3.2 插件命名规范Ark 依靠命名约定来识别插件。每个插件二进制应命名为ark-plugin-kind-name其中plugin-kind是objectstore、blockstore、backupitemaction、restoreitemaction之一name在该插件类型内唯一。该命名约定确保了 Ark 服务器启动扫描插件目录时能够将二进制正确归类到对应插件类型。3.3 插件日志Ark 为插件提供了[日志器]插件可用它向主 Ark server 日志或每个备份/恢复专属日志输出结构化信息。示例插件仓库中演示了如何在插件内实例化并使用该日志器。在现版本仓库中插件日志能力由 pkg/plugin/framework 与 pkg/plugin/clientmgmt 共同承载插件通过日志服务把结构化日志回传至主进程统一写入 Ark server 日志与对应备份/恢复的日志文件便于排障时按备份粒度检索插件输出。四、Hook 与 Plugin 的执行时序配合理解两者的配合顺序有助于设计正确的扩展逻辑。以一次备份中的单个资源Pod为例结合 hooks.md 与源码处理流程执行顺序为pre 钩子执行来自注解或 Backup Spec注解优先级更高Ark 执行该资源的自定义动作Backup Item Action动作可能对资源做修改并声明附加资源additional itemsArk 备份动作产生的所有附加资源post 钩子执行同样支持注解或 Spec 两种来源。这也正是冻结文件系统示例能成立的原因pre 冻结 → 快照落盘 → post 解冻整个过程钩子只影响单个 Pod 的容器不阻塞其他资源的并行备份。同时需要注意onError: Fail的钩子一旦失败会立即终止对应备份项的处理流程并记录错误因此在生产环境建议先以Continue模式验证命令与超时设置再切换为Fail。五、实战指引何时用 Hooks、何时用 Plugins根据 extend.md 的定位两类机制面向不同层次的需求Hooks 适合命令级需求在业务容器内跑一段命令如fsfreeze冻结文件系统、刷新数据库缓存、优雅停服。无需写代码仅需注解或 Backup Spec 配置且要求目标 Pod 内的容器存在可执行该命令的环境。Plugins 适合代码级需求需要自定义存储后端对象存储、块存储/快照、或需要在备份/恢复单个条目前后执行任意逻辑如修改对象内容、注入删除动作、改写引用。要求编写 Go 代码并按照命名规范构建插件二进制。两者可以并存例如用插件做资源改写用钩子做数据库冻结共同作用于同一次备份。六、当前仓库中的实现对照文档描述的是 Ark v0.7.0 时代的能力当前仓库已更名 Velero在继承的基础上做了演进可对照以下路径深入学习钩子注解解析与执行internal/hook/item_hook_handler.go含getHookAnnotation、getPodExecHookFromAnnotations、parseStringToCommand、DefaultItemHookHandler.HandleHooks钩子类型定义pkg/apis/velero/v1/backup_types.goBackupHooks/BackupResourceHookSpec/ExecHook钩子执行器抽象pkg/podexec/pod_command_executor.go基于 Pod Exec API 执行命令含超时控制插件接口定义pkg/plugin/veleroObjectStore、VolumeSnapshotter、BackupItemAction、RestoreItemAction插件管理客户端pkg/plugin/clientmgmt/manager.go插件生命周期管理与获取插件协议pkg/plugin/protogRPC 服务定义插件注册与进程管理pkg/plugin/clientmgmt/process/registry.go按命名规范扫描、注册与拉起插件进程。总结ArkVelero的扩展机制设计理念至今仍是其核心竞争力Hooks 用最低成本解决容器内命令类需求Plugins 用二进制隔离解决深度定制类需求二者共同构成了一条从轻量配置到全功能开发的能力阶梯。理解了 extend.md 所统领的这两条主线再对照 hooks.md、plugins.md 与 Backup API Type 文档即可在任意版本Ark v0.7.0 或 Velero 主线中快速定位并实现自己的扩展需求。【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考