ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Velero(原 Ark)备份删除与命名空间卡在 Terminating 状态:finalizer 冲突的完整排查与修复指南

Velero(原 Ark)备份删除与命名空间卡在 Terminating 状态:finalizer 冲突的完整排查与修复指南 Velero原 Ark备份删除与命名空间卡在 Terminating 状态finalizer 冲突的完整排查与修复指南【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero本文围绕 ArkVelero 的前身0.7.0/0.7.1 版本中一个典型故障场景展开当你删除部署 Ark 的heptio-ark命名空间时命名空间会长期卡在Terminating状态且其中的 Backup 资源无法被删除。文章将给出可直接复制的 jq 一键修复命令、CRD 被误删后的兜底方案、0.7.1 起官方推荐的架构性预防措施并结合当前 Velero 仓库源码剖析 finalizer 在备份删除链路中的真实工作机制。读完本文你将掌握 对象卡在删除中 这类 Kubernetes 问题的通用排查思路并能安全地在自己的集群中解除 Ark/Velero 资源的删除阻塞。背景0.7.0 引入备份删除能力也引入了 finalizer在 Ark 0.7.0 之前Backup 对象一旦创建就无法通过 Kubernetes API 删除。0.7.0 版本为每个 Backup 对象添加了一个名为gc.ark.heptio.com的finalizer终结器从而打通了删除备份这条链路。这是 Kubernetes 删除语义的标准实现方式当对象上存在至少一个 finalizer 时删除请求不会真正移除对象而是先给对象打上 deletionTimestamp删除时间戳等待相关控制器完成清理工作后自行移除 finalizer对象才会被真正删除。因此备份能否被成功删除取决于一个前提负责处理该 Backup 的控制器进程必须存活。在 Ark 0.7.x 架构下这个处理者就是运行在 Ark server Pod 中的垃圾回收控制器GC controller。在当前 Velero 仓库的 pkg/constant/constant.go 中仍能见到ControllerGarbageCollection gc这样的常量定义印证了这条控制链路从 Ark 时代延续至今。问题现象删除 heptio-ark 命名空间后一切卡住在 Ark 0.7.0 中官方默认部署方式见 site/content/docs/v0.7.1/namespace.md把 Ark server Pod、备份、调度、恢复、配置等全部放在同一个heptio-ark命名空间中。当你执行kubectl delete namespace/heptio-arkKubernetes 会开始删除该命名空间内的所有对象但各对象的删除顺序是任意的。如果 Ark server Pod 先于 Backup 对象被销毁那么负责移除gc.ark.heptio.comfinalizer 的 GC 控制器就随之消失剩余的 Backup 对象便永远停留在带 deletionTimestamp 的待删除状态最终导致整个命名空间卡在Terminating状态备份既删不掉命名空间也清理不干净。快速修复一行 jq 命令批量剥离 finalizer官方给出的修复思路是手动把卡住的 Backup 对象上的gc.ark.heptio.comfinalizer 移除让 Kubernetes 能继续推进删除。前提是本机安装了jqJSON 命令行处理工具Linux/macOS 各发行版均可通过包管理器安装。在 Ark 根目录下执行以下命令bash (kubectl -n heptio-ark get backup -o json | jq -c -r $.items[] | kubectl -n heptio-ark patch backup/ .metadata.name -p \ (({metadata: {finalizers: ( (.metadata.finalizers // []) - [gc.ark.heptio.com]), resourceVersion: .metadata.resourceVersion}}) | tostring) \ --typemerge)这条命令的执行过程分两步kubectl -n heptio-ark get backup -o json拉取命名空间下所有 Backup 对象的完整 JSONjq对每个 backup 生成一条kubectl patch指令并通过进程替换( ... )交给bash逐条执行。jq表达式中有三个关键点值得拆解.metadata.finalizers // []若某 Backup 没有 finalizers 字段则回退为空数组避免报错- [gc.ark.heptio.com]从数组中剔除 Ark 的 GC finalizer其余 finalizer 原样保留.metadata.resourceVersion在 patch 中带上资源版本号确保补丁基于最新版本避免并发冲突。最终生成的命令形如kubectl -n heptio-ark patch backup/my-backup -p {metadata:{finalizers:[],resourceVersion:461343}} --typemerge kubectl -n heptio-ark patch backup/some-other-backup -p {metadata:{finalizers:[],resourceVersion:461718}} --typemerge使用--typemergeJSON Merge Patch而非--typestrategic是为了让finalizers字段被整体覆盖为空数组实现剥离 finalizer的语义。命令执行完毕后这些 Backup 对象不再有任何阻塞删除的 finalizerKubernetes 会将其彻底清除命名空间也会随之退出Terminating状态。兜底修复CRD 被删导致 patch 报错如果执行上述 patch 命令时遇到 patching backups is not allowed不允许修补 backup 资源之类的权限/资源错误通常意味着Ark 的 CustomResourceDefinitionsCRD已经被提前删除——命名空间删除过程中 CRD 同样可能先于 Backup 对象被清理导致 Backup 对象类型不复存在Kubernetes 无法对其执行 patch。此时需要先重建 CRD。在 Ark 时代官方提供的资源定义文件位于examples/common/00-prereqs.yaml它同时定义了 Ark 各类对象的 CRDbackups、schedules、restores、configs、downloadrequests、server 与数据所在命名空间、ServiceAccount 及 RBAC 规则见 site/content/docs/v0.7.1/namespace.md。执行kubectl apply -f examples/common/00-prereqs.yaml重建 CRD 后再按上一节的 jq 命令重新执行一遍即可完成 finalizer 的剥离。注当前仓库已演进为 Veleroexamples/common目录不复存在Backup 等 CRD 的当前定义统一维护在 config/crd/v1 与 config/crd/v2alpha1 目录下。架构性预防0.7.1 起 server 与数据分离命名空间0.7.0 的教训直接催生了 0.7.1 的默认配置变更Ark server 运行在与 backups、schedules、restores 及 Ark config 不同的命名空间中。官方文档强烈建议保留这一配置因为只要 GC 控制器所在的 server Pod 与数据对象不在同一个命名空间删除任何一个命名空间时都不会同时误伤另一侧从而从根本上规避控制器先死、finalizer 无人清理的死锁。具体部署时将 server 放入heptio-ark-server命名空间将备份数据放入heptio-ark命名空间并编辑examples/common/00-prereqs.yaml中的命名空间字段所有 Ark 客户端命令通过ark client config set namespaceNAMESPACE_VALUE指定目标命名空间详见 site/content/docs/v0.7.1/namespace.md。这一控制面与数据面隔离的思想此后一直延续——当前 Velero 的velero uninstall命令在卸载时也会先处理命名空间中的 finalizer 资源再删除命名空间避免重蹈 0.7.0 的覆辙。原理深入finalizer 与删除时序的因果链为什么问题恰好表现为命名空间 Terminating 备份删不掉可以把 Kubernetes 的删除流程拆成四步理解用户发起删除请求对象带有 finalizergc.ark.heptio.comKubernetes 不立即删除对象而是设置metadata.deletionTimestamp标记已请求删除负责该 finalizer 的控制器Ark 的 GC 控制器观察到 deletionTimestamp 后处理备份的清理逻辑随后移除 finalizer当对象的 finalizers 列表为空时Kubernetes 才真正将其删除。Ark 0.7.0 之前 server 与数据同命名空间kubectl delete namespace/heptio-ark时 Pod 与 Backup 的删除顺序任意——一旦 server Pod 先消失第 3 步永远无人执行第 4 步便永远不会发生。这正是文档中 the Ark server pod might be deleted before the backups 描述的场景。在 Velero 时代finalizer 处理链路的源码印证虽然当前仓库Velero已不再使用gc.ark.heptio.com这个 finalizerchangelogs/CHANGELOG-1.0.md 记录了 remove code that strips the gc.ark.heptio.com finalizer from backups但用 finalizer 保护备份/恢复对象的删除清理这一设计被完整保留并演进可以从源码中看到它的现代形态pkg/controller/backup_finalizer_controller.go负责备份的 finalizing 阶段将处于Finalizing/FinalizingPartiallyFailed状态的备份推进到Completed/PartiallyFailed并同步备份元数据到对象存储——它是备份生命周期善后的核心控制器pkg/controller/backup_deletion_controller.go删除备份时按顺序执行删除插件动作InvokeDeleteActions、移除 PV 快照与 Pod 卷快照、清理数据移动产生的 DataUpload最后从备份存储中移除备份并级联删除引用该备份的 Restorepkg/cmd/cli/uninstall/uninstall.govelero uninstall在删除命名空间前先删除带 finalizer 的资源并显式等待命名空间真正删除——代码注释直接引用了当年由同类问题引发的 issue #3974说明删除顺序导致卡死的教训已沉淀为卸载逻辑的硬性约束pkg/constant/constant.go集中定义了backup-finalizer、gc、restore-finalizer等控制器名称常量是追踪各类 finalizer 处理控制器的入口。从代码结构可以推断现代 Velero 把备份数据处理与finalizer 清理拆成了独立的控制器与独立的卸载流程配合默认的分离命名空间部署正是对 0.7.0 故障的长期系统性修复。总结Ark 0.7.0 的删除功能是好的设计但所有东西挤在一个命名空间 删除顺序任意的组合制造了死锁finalizer 要求控制器在对象删除前存活而命名空间删除并不保证这个顺序。修复手段有三层急救jq 批量剥离gc.ark.heptio.comfinalizer、兜底重建 CRD 后重试、预防0.7.1 起 server 与数据分离命名空间并沿用至今。理解 finalizer 的删除语义不仅能解决 Ark/Velero 的历史故障也能帮助你诊断任何资源卡在 Terminating的 Kubernetes 疑难杂症。【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表