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.go、pkg/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)挂载了三个子命令:add、remove,以及文档未单独收录的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,合法值:Always、IfNotPresent、Never | IfNotPresent |
例如向默认命名空间添加 AWS 对象存储插件:
ark plugin add heptio/ark-plugin-aws:latestadd 的执行流程:源码级拆解
从 add.go 可以看到,ark plugin add并非简单地"写一行配置",而是对 Velero server 的 Deployment 做一次合并补丁(MergePatch),完整流程如下:
- 危险操作确认:命令会弹出确认提示,警告"add 会导致 Velero server Pod 重启并使所有进行中的任务失败"(对应
confirm.NewConfirmOptionsWithDescription,见 add.go 与 add.go)。 - 定位 Deployment:通过
f.KubeClient()获取 Kubernetes 客户端,再调用veleroDeployment(...)按标签与容器名找到 Velero Deployment(详见下文"定位 Velero Deployment")。 - 序列化原状:将当前 Deployment 序列化为 JSON 作为补丁基线(
original)。 - 确保
plugins卷与挂载存在:遍历spec.template.spec.volumes,若不存在名为plugins的卷,则创建一个emptyDir卷并挂载到容器velero的/plugins路径(见 add.go)。 - 以 init container 形式注入插件:调用
builder.ForPluginContainer(image, pullPolicy, initContainers)构造插件 init container 并追加到spec.template.spec.initContainers(见 add.go)。 - 生成并应用 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 看,执行流程为:
- 定位 Velero Deployment(同样经
veleroDeployment(...)); - 遍历
spec.template.spec.initContainers,当某个 init container 的Name或Image等于参数时命中(见 remove.go); - 若未命中,报错
init container %s not found in Velero server deployment(见 remove.go); - 从 initContainers 切片中删除该容器(
append(initContainers[0:index], initContainers[index+1:]...),见 remove.go); - 生成 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 的底层逻辑
add与remove都依赖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") }它按两步定位:
- 标签选择器:用
install.Labels()(来自 pkg/install)生成的 Velero 标准标签过滤 Deployment; - 容器名校验:在候选 Deployment 的容器列表中查找名为
velero的容器,找到才返回,否则报Velero deployment not found。
这意味着:
- 命令作用于当前 kubeconfig 上下文与
--namespace指定的命名空间; - 若你的 Velero 以非标准命名部署(未打标准标签或主容器不叫
velero),ark plugin add/remove将无法定位 Deployment 而失败。
五、ark plugin get:查看已注册插件(文档之外的补充能力)
虽然 v0.8.1 的参考文档只收录了add与remove,但从源码可见当前仓库还提供了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" 部分),完整清单如下:
| 选项 | 类型/默认值 | 作用 |
|---|---|---|
--alsologtostderr | bool | 同时将日志写到标准错误与日志文件 |
--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 | 空 | 若指定则把日志文件写入该目录 |
--logtostderr | bool | 将日志写到标准错误而非文件 |
-n, --namespace string | "heptio-ark" | Ark/Velero 操作所作用的命名空间 |
--stderrthreshold severity | 2 | 达到或超过该级别的日志转到标准错误 |
-v, --v Level | 未设置 | V 级别日志的详细程度 |
--vmodule moduleSpec | 空 | pattern=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 重启风险:
add与remove都会修改 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),仅供参考