
Velero 插件架构深度解析从 Ark 插件体系到自定义扩展实战【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero本篇技术指南以 Velero前身 Heptio Ark的插件架构为核心主题系统讲解插件体系的设计理念、四种核心插件类型、基于 go-plugin 与 gRPC 的插件通信机制、插件日志规范以及如何将自定义插件以 init container 方式接入 Velero Server 的完整实战流程。读者读完本文后将掌握 Velero 插件的种类划分与职责边界、插件二进制的编写与注册方式并能够基于仓库源码理解插件在备份/恢复生命周期中的真实调用位置。一、插件架构的设计初衷不改核心、不重编译Velero原 Heptio Ark采用插件架构的核心目的是允许用户在不修改、不重新编译 Velero 核心二进制的前提下为备份Backup与恢复Restore流程注入自定义功能。这一设计理念由 site/content/docs/v0.10.0/plugins.md 明确阐述并在当前仓库中得到了完整的代码级落地。实现方式可概括为三步编写独立二进制用户创建一个自己的二进制程序内部实现 Velero 支持的若干种插件类型Plugin Kind下文详述并附带少量样板代码boilerplate将插件实现暴露给 Velero。打包为 init container 镜像将该二进制放入一个容器镜像中作为 Velero Server Pod 的init container运行。共享 emptyDir 卷交付init container 将二进制复制进一个共享的emptyDir卷Velero Server 主容器从该卷加载并调用插件。同一个二进制中可以同时实现多个插件、且插件类型不限例如一个插件二进制既可以实现 Object Store也可以实现 Backup Item Action这为云厂商插件如 AWS/GCP/Azure 插件提供了高度聚合的打包形态。需要特别说明的是原文档中的插件类型名称Object Store、Block Store、Backup Item Action、Restore Item Action属于 Heptio Ark 时代v0.10.0的命名。当前仓库已将其演进为 Velero 的标准插件体系其中Block Store 演变为 VolumeSnapshotter并新增了 Delete Item Action、Item Block Action 等类型见 pkg/plugin/framework/common/plugin_kinds.go。下文将以当前仓库源码为准展开。二、插件类型Plugin Kinds全景原文档列出了 Ark 时代支持的四种插件类型我们逐一对照当前仓库的实现进行解读插件类型原文档当前仓库对应 Kind职责Object StoreObjectStore持久化与检索备份文件、备份日志、恢复日志Block StoreVolumeSnapshotter备份时创建卷快照恢复时从快照还原卷Backup Item ActionBackupItemAction含 v2在单个 item 被写入备份文件之前对其执行任意逻辑Restore Item ActionRestoreItemAction含 v2在单个 item 被恢复到集群之前对其执行任意逻辑在 pkg/plugin/framework/common/plugin_kinds.go 中Velero 完整定义了如下插件 Kind 常量PluginKindObjectStore—— 对象存储插件PluginKindVolumeSnapshotter—— 卷快照插件即原 Block StorePluginKindBackupItemAction/PluginKindBackupItemActionV2—— 备份 item 动作插件及其 v2 版本PluginKindRestoreItemAction/PluginKindRestoreItemActionV2—— 恢复 item 动作插件及其 v2 版本PluginKindDeleteItemAction—— 删除 item 动作插件PluginKindItemBlockAction—— ItemBlock 动作插件PluginKindPluginLister—— 插件列举器开发者无需实现由 Velero 与插件库代码内部处理见 plugin_kinds.go 中AllPluginKinds()的注释说明。同时源码通过PluginKindsAdaptableTo映射表plugin_kinds.go支持版本自适应v1 版本的 Backup/Restore Item Action 可以被 v2 版本插件兼容这保证了插件生态的向后兼容性。2.1 各插件类型的职责细节Object Store对象存储负责备份数据落地与读取是所有备份/恢复流程的存储底座。它承担三类数据的持久化与检索备份文件backup tarball、备份日志backup logs与恢复日志restore logs。其 gRPC 服务端实现位于 pkg/plugin/framework/object_store.go通过proto.RegisterObjectStoreServer注册。VolumeSnapshotter卷快照原 Block Store对接云厂商卷快照能力——备份阶段创建持久卷快照恢复阶段从快照创建新卷。对应实现见 pkg/plugin/framework/volume_snapshotter.go。Backup Item Action备份 item 动作在备份过程中对**每个 Kubernetes 资源对象item**在写入备份文件之前执行自定义逻辑。典型场景包括加密/脱敏 Secret 数据、改写资源字段、注入自定义注解、处理特定资源类型的额外数据等。该插件的执行时机是逐 item 回调因此可以实现非常细粒度的备份前处理对应实现见 pkg/plugin/framework/backup_item_action.gov1与 pkg/plugin/framework/backupitemaction/v2/backup_item_action.gov2。Restore Item Action恢复 item 动作与 Backup Item Action 对称在恢复流程中每个 item 被应用到集群之前执行任意逻辑。典型场景包括修改恢复后的资源命名空间、改写存储类StorageClass、注入集群特定配置、调整资源配额字段等对应实现见 pkg/plugin/framework/restore_item_action.gov1与 pkg/plugin/framework/restoreitemaction/v2/restore_item_action.gov2。三、插件运行机制go-plugin 与 gRPC 进程模型当前仓库中Velero 的插件体系建立在HashiCorp go-plugin框架之上并采用gRPC作为进程间通信协议。这一点可以从插件接口定义中直接证实pkg/plugin/framework/interface.go 中Interface接口内嵌了plugin.Plugin来自github.com/hashicorp/go-plugin并要求插件实现Names() []string方法——返回该插件注册的所有实现名称例如一个 Backup Item Action 插件可同时注册针对pod、pvc等多个资源类型的实现。从 pkg/plugin/framework/server.go 可以看到插件侧的Server接口提供了完整的注册能力RegisterBackupItemAction/RegisterBackupItemActionV2注册备份 item 动作插件RegisterRestoreItemAction/RegisterRestoreItemActionV2注册恢复 item 动作插件RegisterVolumeSnapshotter注册卷快照插件RegisterObjectStore注册对象存储插件RegisterDeleteItemAction注册删除 item 动作插件RegisterItemBlockAction注册 ItemBlock 动作插件。所有这些Register*方法均支持链式调用返回Server自身方便在main函数中一次性完成多个插件的注册。插件名称的合法格式为DNS subdomain/non-empty name见 server.go 的注释说明。最终Serve()方法server.go会将所有已注册的插件通过plugin.Serve暴露为 gRPC 服务并额外注册一个PluginLister服务供 Velero Server 侧枚举该插件二进制实际提供了哪些 Kind 与名称。3.1 为什么插件必须通过独立进程运行go-plugin 采用进程外插件模型每个插件二进制是独立进程Velero Server 通过 gRPC 与其通信。这样做的好处是插件崩溃不会拖垮 Velero Server插件可以用任何实现了 go-plugin 协议的编程语言编写不局限于 Go插件二进制与 Velero 核心解耦用户升级插件无需重新编译核心。3.2 插件二进制如何被打包进 Velero Server从 pkg/cmd/cli/plugin/add.go 的实现可以看到Velero 为插件专门定义了一个名为plugins的 volume 与挂载路径/plugins插件镜像作为init container被注入 Velero Server Podinit container 将插件二进制复制到共享的pluginsemptyDir 卷Velero Server 主容器通过MountPath: /plugins挂载该卷从中发现并启动插件进程。而在安装层面velero install命令提供了--plugins参数用于一次性注入插件镜像见 pkg/cmd/cli/install/install.go# 安装 Velero 时同时安装云厂商插件镜像 velero install --provider gcp \ --plugins velero/velero-plugin-for-gcp:v1.0.0 \ --bucket mybucket \ --secret-file ./gcp-service-account.json也可以使用velero plugin add image在部署后动态追加插件镜像并使用velero plugin get查看当前 Server 上已加载的插件信息命令定义见 pkg/cmd/cli/plugin/get.go 与velero get plugins子命令入口 pkg/cmd/cli/get/get.go。四、插件日志规范结构化日志如何汇入 Velero Server原文档特别强调VeleroArk为插件提供了一套日志记录器logger使插件能够输出结构化日志并使其汇入 Velero Server 主日志或按备份/恢复隔离的独立日志中。这一机制在当前仓库的实现位于 pkg/plugin/framework/logger.go其中有几个非常关键的工程细节绝不能将日志输出到 stdoutgo-plugin使用stdout 作为客户端与服务端之间的通信协议。插件日志必须走stderrVelero Server 侧会捕获 stderr 并将日志转发到自己的日志系统源码注释!!!DO NOT SET THE OUTPUT TO STDOUT!!!明确标注了这一约束。使用 JSON Formatter插件 logger 采用logrus.JSONFormatter并映射消息字段为messagehclog 兼容字段因为 Velero Server 侧的 go-plugin 会解析 stderr 上的 JSON 并生成结构化日志条目。禁用时间戳插件内不追加时间戳由 Velero Server 在最终输出日志时统一添加避免时间格式不一致。挂载日志 Hook通过LogLocationHook、ErrorLocationHook、HcLogLevelHook等 Hook分别标记日志位置、记录错误位置并将warning级别统一调整为 go-plugin 可解析的warn表示。对插件作者而言这意味着在插件代码中直接使用 Velero 提供的 logger 记录日志即可自动获得与 Velero Server 日志体系完全兼容的结构化输出无需自行处理日志格式化与传输问题。五、实战编写一个自定义插件的完整路径结合原文档的指引与当前仓库源码编写一个 Velero 自定义插件二进制需要经过以下步骤5.1 搭建插件骨架创建一个独立的 Go 模块引入 Velero 的插件框架代码当前仓库中可参考的框架入口为pkg/plugin/framework与pkg/plugin/velero目录。插件的main函数通常形如func main() { server : framework.NewServer() server. RegisterObjectStore(newMyObjectStore). RegisterBackupItemAction(myplugin/my-action, newMyBackupAction). RegisterRestoreItemAction(myplugin/my-restore, newMyRestoreAction) server.Serve() }其中framework.NewServer()见 pkg/plugin/framework/server.go会预置所有插件类型的处理器与 loggerRegister*系列方法接收插件名DNS subdomain/name格式与common.HandlerInitializer类型的初始化函数Serve()解析命令行参数、按注册内容构建PluginLister并启动 gRPC 服务等待 Velero Server 连接。5.2 实现插件接口每种插件类型都定义了各自必须实现的接口。以 Backup Item Action 为例v2 版本见 pkg/plugin/framework/backupitemaction/v2/backup_item_action.go需要实现备份时对单个 item 的处理方法Restore Item Action 则对应实现恢复时的处理方法。对象存储插件则需实现备份文件的读写、日志存取等能力gRPC 服务端定义见 pkg/plugin/framework/object_store.go。5.3 打包、部署与验证将插件二进制构建进一个容器镜像安装 Velero 时通过velero install --plugins 你的镜像注入或部署后执行velero plugin add 你的镜像用velero get plugins确认插件已被 Velero Server 发现并加载执行一次备份/恢复在 Velero Server 日志或备份/恢复专属日志中观察插件输出使用第四节所述的 logger。对于希望快速上手的插件作者原文档推荐从官方示例插件仓库ark-plugin-example出发——它演示了如何实例化与使用插件 logger、如何实现各插件类型的完整样板代码。在当前仓库中可以对照 pkg/plugin/velero 目录含各插件 Kind 的 v1/v2 接口定义与 mocks以及 pkg/plugin/framework/examples_test.go 理解接口的精确用法。六、小结Velero 的插件架构以独立二进制 init container emptyDir 共享卷 go-plugin/gRPC 进程通信为核心将对象存储、卷快照、备份/恢复 item 动作等能力完全开放给用户实现了核心与扩展解耦无需修改/重编译 Velero 核心即可扩展任意备份/恢复行为多插件聚合打包一个二进制可同时承载多种类型、多个名称的插件实现日志体系统一插件结构化日志自动汇入 Velero Server 日志与按备份/恢复隔离的日志版本平滑演进v1/v2 插件接口通过PluginKindsAdaptableTo映射保持兼容。无论是接入新对象存储后端、对接云厂商快照还是定制备份前的数据脱敏与恢复后的资源配置理解这套插件体系都是进行 Velero 二次开发的起点。【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考