Velero(Ark)插件管理实战:`ark plugin` 命令的 add/remove 机制与源码级解析
2026/9/16 23:05:57 网站建设 项目流程

Velero(Ark)插件管理实战:ark plugin命令的 add/remove 机制与源码级解析

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

本指南以 Velero 仓库site/content/docs/v0.8.1/cli-reference/ark_plugin.md为核心,完整讲解ark plugin命令组(add/remove)的用法、参数、父命令继承选项,并结合当前仓库源码(pkg/cmd/cli/plugin/pkg/install/deployment.gopkg/builder/container_builder.go)揭示插件是如何以 init container 形式注入 Velero server Deployment 的底层原理。读完你将能熟练地增删 Velero 插件镜像,理解每次操作背后的 Pod 重启风险,并能够排查插件容器命名、镜像拉取策略等常见问题。

一、ark plugin命令概览:它解决什么问题

在 v0.8.1 时代(即 Velero 前身 Heptio Ark 时代),Velero 的核心二进制是一个"插件宿主":对象存储(S3/GCS/Azure Blob)、卷快照(AWS EBS/GCE PD/Azure Disk)等能力都以 gRPC 插件的形式动态加载。因此,管理员需要一条 CLI 命令来管理运行在 Velero server 中的插件集合,这就是ark plugin的职责。

参考文档 ark_plugin.md 给出的命令结构如下:

ark plugin [command] Available Commands: add Add a plugin remove Remove a plugin

从源码看,插件命令组实际由 plugin.go 定义,它通过NewCommand(f client.Factory)挂载了三个子命令:addremove,以及文档未单独收录的get(用于查询 server 上已注册的插件信息):

func NewCommand(f client.Factory) *cobra.Command { c := &cobra.Command{ Use: "plugin", Short: "Work with plugins", Long: "Work with plugins", } c.AddCommand( NewAddCommand(f), NewRemoveCommand(f), NewGetCommand(f, "get"), ) return c }

也就是说,这一命令族解决的核心问题是:在不手动编辑 Deployment YAML 的前提下,用一行命令把插件镜像注入或移出 Velero server

二、ark plugin add:向 Velero server 添加插件

ark plugin add的完整用法与参数如下(出自 ark_plugin_add.md):

ark plugin add IMAGE [flags]

子命令独有选项:

选项说明默认值
-h, --help显示 add 命令帮助-
--image-pull-policy插件容器(init container)的 imagePullPolicy,合法值:AlwaysIfNotPresentNeverIfNotPresent

例如向默认命名空间添加 AWS 对象存储插件:

ark plugin add heptio/ark-plugin-aws:latest

add 的执行流程:源码级拆解

从 add.go 可以看到,ark plugin add并非简单地"写一行配置",而是对 Velero server 的 Deployment 做一次合并补丁(MergePatch),完整流程如下:

  1. 危险操作确认:命令会弹出确认提示,警告"add 会导致 Velero server Pod 重启并使所有进行中的任务失败"(对应confirm.NewConfirmOptionsWithDescription,见 add.go 与 add.go)。
  2. 定位 Deployment:通过f.KubeClient()获取 Kubernetes 客户端,再调用veleroDeployment(...)按标签与容器名找到 Velero Deployment(详见下文"定位 Velero Deployment")。
  3. 序列化原状:将当前 Deployment 序列化为 JSON 作为补丁基线(original)。
  4. 确保plugins卷与挂载存在:遍历spec.template.spec.volumes,若不存在名为plugins的卷,则创建一个emptyDir卷并挂载到容器velero/plugins路径(见 add.go)。
  5. 以 init container 形式注入插件:调用builder.ForPluginContainer(image, pullPolicy, initContainers)构造插件 init container 并追加到spec.template.spec.initContainers(见 add.go)。
  6. 生成并应用 MergePatch:序列化修改后的 Deployment(updated),用jsonpatch.CreateMergePatch(original, updated)生成补丁,再以MergePatchType提交到Deployments(veleroDeploy.Namespace).Patch(...)(见 add.go)。

补丁应用后 Deployment 触发滚动更新,Velero server Pod 随之重启,这正是命令确认提示中所警告的风险来源。

插件容器是如何构造的:ForPluginContainer

插件容器由 container_builder.go 中的ForPluginContainer构造:

// ForPluginContainer is a helper builder specifically for plugin init containers func ForPluginContainer(image string, pullPolicy corev1api.PullPolicy, existingContainers []corev1api.Container) *ContainerBuilder { volumeMount := ForVolumeMount("plugins", "/target").Result() return ForContainer(getName(image, existingContainers), image).PullPolicy(pullPolicy).VolumeMounts(volumeMount) }

每个插件容器都:

  • 挂载名为plugins的卷到/target——插件二进制通过emptyDir卷共享给主容器(Velero server 在 deployment.go 中将plugins卷挂载到/plugins,并设置LD_LIBRARY_PATH=/plugins,使 gRPC 插件二进制可被加载);
  • 采用--image-pull-policy指定的拉取策略;
  • 容器名由getName(image, existingContainers)生成:去掉镜像 registry 前缀、去掉 tag 或 digest,再把/_.统一替换为-,最终转化为 DNS-1123 合法名称且不超过 63 字符限制;若与已有容器重名,则追加 5 位随机串(见 container_builder.go)。这意味着容器名并不是你传入的完整镜像名ark plugin remove时需按该规则推断容器名,或直接传镜像名。

install 侧的一致性印证

pkg/install中的 Deployment 构建逻辑与 add 命令保持完全一致:当通过WithPlugins(plugins)传入插件镜像时,同样以builder.ForPluginContainer(image, pullPolicy, ...)生成 init container(见 deployment.go)。因此,无论插件是安装时注入(velero install --plugins ...)还是运行时追加(ark plugin add),最终在 Pod 中的落地形态完全相同。

三、ark plugin remove:从 Velero server 移除插件

ark plugin remove的用法与参数如下(出自 ark_plugin_remove.md):

ark plugin remove [NAME | IMAGE] [flags]

该子命令没有独有选项(仅继承-h, --help与父命令选项)。它的独特之处在于参数既可以是容器名(NAME)也可以是镜像名(IMAGE)

从 remove.go 看,执行流程为:

  1. 定位 Velero Deployment(同样经veleroDeployment(...));
  2. 遍历spec.template.spec.initContainers,当某个 init container 的NameImage等于参数时命中(见 remove.go);
  3. 若未命中,报错init container %s not found in Velero server deployment(见 remove.go);
  4. 从 initContainers 切片中删除该容器(append(initContainers[0:index], initContainers[index+1:]...),见 remove.go);
  5. 生成 MergePatch 并应用到 Deployment(见 remove.go)。

例如按镜像名移除:

ark plugin remove heptio/ark-plugin-aws:latest

或按容器名移除(注意使用 add 后生成的规范化容器名):

ark plugin remove heptio-ark-plugin-aws

同样地,remove 会引发 Deployment 更新与 Pod 重启,进行中的任务可能失败,操作前应评估当前是否有正在运行的备份/恢复任务。

四、定位 Velero Deployment 的底层逻辑

addremove都依赖veleroDeployment(...)定位目标 Deployment。该函数定义在 helpers.go:

func veleroDeployment(ctx context.Context, kubeClient kubernetes.Interface, namespace string) (*appsv1api.Deployment, error) { veleroLabels := labels.FormatLabels(install.Labels()) deployList, err := kubeClient. AppsV1(). Deployments(namespace). List(ctx, metav1.ListOptions{ LabelSelector: veleroLabels, }) ... for _, deploy := range deployList.Items { for _, container := range deploy.Spec.Template.Spec.Containers { if container.Name == "velero" { return &deploy, nil } } } return nil, errors.New("Velero deployment not found") }

它按两步定位:

  1. 标签选择器:用install.Labels()(来自 pkg/install)生成的 Velero 标准标签过滤 Deployment;
  2. 容器名校验:在候选 Deployment 的容器列表中查找名为velero的容器,找到才返回,否则报Velero deployment not found

这意味着:

  • 命令作用于当前 kubeconfig 上下文与--namespace指定的命名空间
  • 若你的 Velero 以非标准命名部署(未打标准标签或主容器不叫velero),ark plugin add/remove将无法定位 Deployment 而失败。

五、ark plugin get:查看已注册插件(文档之外的补充能力)

虽然 v0.8.1 的参考文档只收录了addremove,但从源码可见当前仓库还提供了get子命令(get.go),用于"获取 Velero server 上所有插件的信息":

ark plugin get [flags]

其实现通过DefaultServerStatusGetter.GetServerStatus(kbClient)读取 Velero 的ServerStatusRequest资源,并以output.PrintWithFormat格式化输出;默认超时 5 秒,可通过--timeout调整(见 get.go 与 get.go)。对于需要核对插件是否成功注册、排查加载失败的场景,ark plugin get是比直接查看 Deployment 更直接的手段。

六、父命令继承选项:连接 Kubernetes 与日志开关

ark plugin及其子命令均继承自根命令ark的全局选项(见 ark.md 与 ark_plugin.md 的 "Options inherited from parent commands" 部分),完整清单如下:

选项类型/默认值作用
--alsologtostderrbool同时将日志写到标准错误与日志文件
--kubeconfig string未设置指定与 Kubernetes apiserver 通信所用的 kubeconfig 路径;若未设置则依次尝试环境变量KUBECONFIG与集群内配置
--kubecontext string当前 context指定要使用的 kubeconfig context,默认取kubectl config current-context的当前上下文
--log_backtrace_at traceLocation:0当日志命中所给file:N位置时输出堆栈跟踪
--log_dir string若指定则把日志文件写入该目录
--logtostderrbool将日志写到标准错误而非文件
-n, --namespace string"heptio-ark"Ark/Velero 操作所作用的命名空间
--stderrthreshold severity2达到或超过该级别的日志转到标准错误
-v, --v Level未设置V 级别日志的详细程度
--vmodule moduleSpecpattern=N形式的逗号分隔列表,按文件过滤日志级别

实操中最常搭配的两个是-n/--namespace(若 Velero 安装在非默认命名空间,必须显式指定,否则ark plugin add/remove会在错误命名空间中找不到 Deployment)与--kubeconfig(多集群场景下指定目标集群)。

七、典型操作示例与注意事项

添加插件(以 AWS 为例):

ark plugin add heptio/ark-plugin-aws:latest ark plugin add heptio/ark-plugin-aws:latest --image-pull-policy Always

第二行强制Always拉取策略,适用于插件镜像 tag 可变、需要每次重启都拉取最新镜像的调试场景。

移除插件:

ark plugin remove heptio/ark-plugin-aws:latest # 按镜像名 ark plugin remove heptio-ark-plugin-aws # 按容器名

注意事项汇总:

  • Pod 重启风险addremove都会修改 Velero Deployment 并触发滚动更新,正在进行的备份/恢复任务将失败,请避开任务窗口执行,并留意命令的交互式确认提示。
  • 容器名 ≠ 镜像名:add 会按getName规则把镜像名规范化为容器名(registry 前缀与 tag 被剥离,特殊字符转-,超长截断、重名加随机后缀),remove 时传错容器名会报init container not found错误。
  • 命名空间必须正确:父命令-n/--namespace默认是heptio-ark(v0.8.1 时代的默认命名空间),若你的部署在其他命名空间,务必显式传入。
  • 插件落地形态:无论 add 还是 install 注入,插件最终都以 init container 形态出现,通过pluginsemptyDir 卷把二进制共享到 Velero 主容器的/plugins,配合LD_LIBRARY_PATH=/plugins被加载(见 deployment.go)。

八、源码文件速查

  • 命令定义与子命令挂载:pkg/cmd/cli/plugin/plugin.go
  • add 实现(MergePatch 注入 init container):pkg/cmd/cli/plugin/add.go
  • remove 实现(按 NAME 或 IMAGE 删除 init container):pkg/cmd/cli/plugin/remove.go
  • 插件信息查询:pkg/cmd/cli/plugin/get.go
  • Deployment 定位工具函数:pkg/cmd/cli/plugin/helpers.go
  • 插件容器构造与命名规则:pkg/builder/container_builder.go
  • 安装期插件注入与/plugins卷/LD_LIBRARY_PATH配置:pkg/install/deployment.go

九、与新版 Velero 的衔接

v0.8.1 是 Velero 仍以 "Ark" 命名的历史版本:默认命名空间是heptio-ark、CLI 前缀是ark、插件生态以对象存储与卷快照的 gRPC 插件为主。在新版 Velero 中,这一命令族已演进为velero plugin,但**"插件 = init container 注入 Deployment"的机制至今保留**:velero plugin add/remove/get依旧通过修改 Velero server Deployment 的 initContainers 来增删插件,源码位置与命名规则也与本文所述一脉相承。理解 v0.8.1 的ark plugin机制,即掌握了 Velero 插件管理的最小原理模型。

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

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

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

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

立即咨询