尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Velero(原 Heptio Ark)FAQ 深度解读:etcd 备份替代与恢复保真度剖析

Velero(原 Heptio Ark)FAQ 深度解读:etcd 备份替代与恢复保真度剖析 Velero原 Heptio ArkFAQ 深度解读etcd 备份替代与恢复保真度剖析【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero导读本文围绕 Velero 仓库 site/content/docs/v0.6.0/faq.md 中两个最核心的经典问题展开什么场景下应该用 Velero 而不是 etcd 自带的备份/恢复工具以及Velero 能否把 Kubernetes 资源原样恢复出来。结合当前仓库中pkg/restore的恢复引擎与 RestoreItemAction 源码实现你将理解 Velero 跨集群迁移能力的底层机制以及恢复过程中 Pod、Service、Job、PV/PVC 等资源会被改写哪些字段、为什么必须改写。历史背景说明本文关联的 FAQ 出自 v0.6.0 时代当时项目名为Heptio Ark。如今该项目已更名为 Velero见 README.md 中的描述 Velero (formerly Heptio Ark)FAQ 中的 Ark 即今天的 Velero。一、什么时候该用 Velero而不是 etcd 自带的备份/恢复这是 Velero 用户最常问的第一个问题。FAQ 给出的核心结论是etcd 自带工具适合单 etcd 集群的数据丢失恢复而集群级的备份与恢复管理VeleroArk是更合适的选择。1. etcd 内置备份/恢复的适用边界FAQ 明确指出etcd 的 backup/restore 工具链擅长处理单个 etcd 集群内部的数据丢失一个典型场景就是在升级 etcd 本身之前先对 etcd 做一次备份。也就是说etcd 备份解决的是etcd 这个数据存储层自身的可用性问题它的恢复单位是 etcd 集群本身而不是整个 Kubernetes 集群的业务状态。2. Velero 的定位可以扔弃坏集群、在全新集群中恢复FAQ 给出了 VeleroArk相比 etcd 备份更合适的核心理由It gives you the ability to throw away an unstable cluster and restore your Kubernetes resources and data into a new cluster, which you cant do easily just by backing up and restoring etcd.即Velero 允许你直接丢弃一个不稳定的集群把 Kubernetes 资源与持久化数据恢复到另一个全新集群中——这是单纯备份/恢复 etcd 很难做到的事。这个能力在当前仓库的架构中可以得到印证。v0.6.0 的架构文档 site/content/docs/v0.6.0/_index.md 说明Ark 的 Backup、Schedule、Restore 本身都是基于 CRD 定义的自定义资源由对应的自定义控制器处理。一次ark backup create会触发如下流程ark 客户端调用 Kubernetes API Server创建Backup自定义资源BackupController发现新 Backup 并完成校验校验通过后控制器通过 API Server 聚合集群资源数据控制器把备份数据打包上传到对象存储如 Amazon S3默认情况下还会通过云厂商 API 对持久卷做磁盘快照可通过--snapshot-volumesfalse关闭。注意第 1 步中的一个精妙细节Ark 自己的 Backup CR 确实也存放在 etcd 里所有 Kubernetes 对象都存于 etcd但真正的备份数据——资源清单的 tarball 和 PV 快照——被放在了对象存储 云快照中与 etcd 完全解耦。这正是它能够脱离原集群、在新集群重建一切的根本原因。3. 适合使用 Velero 的典型场景FAQ 原列 5 类FAQ 列举了 5 个典型的 Ark/Velero 使用场景其中多个场景是 etcd 备份天然无法覆盖的场景为什么 etcd 备份难以胜任你无法访问 etcd例如运行在 GKE 上托管集群不开放 etcd 访问权只能从集群外部做应用层备份同时备份 Kubernetes 资源与持久卷状态etcd 只保存 API 对象不保存 PV 数据内容集群迁移需要在另一个全新集群中重建资源而非恢复原 etcd只备份 Kubernetes 资源的一个子集etcd 是全量 dump无法按命名空间/标签/资源类型做选择性备份资源分散存储在多个 etcd 集群例如自定义 apiserver单个 etcd 备份只能覆盖它自己承载的那部分资源其中备份子集的能力在实操中有直接体现v0.6.0 快速入门示例使用ark backup create nginx-backup --selector appnginx只备份带appnginx标签的对象恢复侧则支持更细粒度控制见 site/content/docs/v0.6.0/cli-reference/ark_create_restore.md包括--include-namespaces、--exclude-namespaces、--include-resources、--exclude-resources、--include-cluster-resources、--namespace-mappings、--selector等参数——这种按需圈定范围的灵活性正是 etcd 全量备份不具备的。二、Velero 能把我的 Kubernetes 资源原样恢复吗FAQ 的第二个问题直指恢复保真度Will Ark restore my Kubernetes resources exactly the way they were before? — Yes, with some exceptions.答案是**基本可以但有例外**。FAQ 给出的例子是恢复 Pod 时Velero 会删除 Pod 的nodeName字段以便它能在新节点上重新调度。文档引用了当时的pod_action.go对应到当前仓库的源码位于 pkg/restore/actions/pod_action.go。下面从当前仓库源码出发系统梳理恢复时被改写的字段——这些改写不是缺陷而是为了让对象能在新集群中合法、正确地重建所必需的。1. 可以原样恢复的部分通用元数据重置在恢复引擎层所有资源对象在落库前都会经过通用的元数据与状态重置。见 pkg/restore/restore.go 中的resetMetadata约 L2489-L2508与resetStatusL2510-L2512resetMetadata会删除generateName、selfLink、uid、resourceVersion、generation、creationTimestamp、deletionTimestamp、deletionGracePeriodSeconds、ownerReferences等字段resetStatus会删除整个status子对象例如 Pod 的运行阶段、IP 等运行时状态这些在新集群中毫无意义且可能干扰调度addRestoreLabels会给恢复对象打上velero.io/backup-name与velero.io/restore-name两个标签L2539-L2552用于追溯来源。这些字段都是集群级的唯一标识或运行时状态直接拷贝到新集群会导致冲突或误导控制器因此必须清除。这也是有例外的第一个层次Kubernetes 对象的存在性元数据不会被原样恢复。2. 例外之一Pod 的nodeName与调度FAQ 明确提到的 PodnodeName删除逻辑在 pkg/restore/actions/pod_action.go 的Execute方法中实现L46-L52pod.Spec.NodeName pod.Spec.Priority nilnodeName记录了 Pod 在原集群中被调度到哪个节点原节点在新集群中可能根本不存在若保留该字段调度器会认为 Pod 已被调度Pod 将卡在 Pending 状态无法运行。清空后由新集群的调度器重新分配节点。Priority是调度器计算出的优先级快照同样属于绑定旧集群状态的字段。对应的单测 pkg/restore/actions/pod_action_test.go 中有一个用例名称就叫nodeName (only) should be deleted from spec直接验证了该行为输入含NodeName: foo的 Pod输出中NodeName必须被清空、其余字段保持不变。3. 更多例外PodAction 还做了什么顺着同一个文件往下读可以发现Pod 的改写远不止nodeName。当前实现L52-L95还会清空pod.Spec.Priority如上所述删除 ServiceAccount Token 卷凡是卷名以serviceAccountName-token-前缀开头的 Volume以及容器、initContainer 中对应的 VolumeMount都会被移除——这些 token 卷是集群自动注入的恢复时应当由新集群重新注入否则恢复出的卷定义是失效的把 PriorityClass 加入AdditionalItems若 Pod 声明了PriorityClassName该 PriorityClass 会被登记为待恢复的附加资源确保依赖的优先级类也一并恢复L90-L94。pod_action_test.go的多个用例逐一验证了 token 卷删除、initContainer 卷挂载清理、PriorityClass 附加项等行为。这些都属于恢复后由新集群重建运行时状态的设计。4. 更多例外Service 的 ClusterIP 与 NodePortpkg/restore/actions/service_action.goServiceAction说明了另一类不能原样恢复的字段ClusterIP除非是 headless ServiceClusterIP None否则恢复时spec.clusterIP与spec.clusterIPs会被清空让新集群重新分配。因为原集群的 ClusterIP 在新集群中很可能已被占用或不再可用L57-L60。NodePort默认情况下自动分配的 NodePort 会被删除deleteNodePortsL145-L253避免端口冲突。其判断逻辑相当精细通过kubectl.kubernetes.io/last-applied-configuration注解或 ManagedFields 识别哪些 NodePort 是用户显式指定的显式指定的保留、自动分配的置 0。同时deleteHealthCheckNodePort会处理 LoadBalancer 类型的健康检查端口。如果用户在创建恢复时显式声明保留端口--preserve-nodeports对应 Restore 规格中的PreserveNodePorts则跳过 NodePort 删除逻辑L62-L72。相关测试见 pkg/restore/actions/service_action_test.go其中既有clusterIP/clusterIPs should be deleted from spec也有headless clusterIP should not be deleted from spec的用例。5. 更多例外Job 的controller-uid标签pkg/restore/actions/job_action.go 中的JobAction处理 Job 的选择器与模板标签它会从spec.selector.matchLabels和spec.template.metadata.labels中删除controller-uidKubernetes 1.27与旧版controller-uid兼容标签。原因在于这些标签携带的是原 Job 控制器生成的 UID 标识恢复后若保留会让新集群中的 Job 与无关的历史 Pod 产生错误的属主关联。6. 更多例外PV/PVC 的绑定信息在恢复引擎的通用逻辑中resetVolumeBindingInfopkg/restore/restore.go L2463-L2487会清理 PV 上的绑定信息删除spec.claimRef.uid与spec.claimRef.resourceVersion这些是高度唯一的绑定标识删除pv.kubernetes.io/bind-completed与pv.kubernetes.io/bound-by-controller两个注解。这样恢复出的 PV 看起来像一个静态供给、待手动绑定的卷PVC 与 PV 可以在新集群中由 PV(C) 控制器重新完成绑定而不是带着旧集群的绑定指纹直接落地。代码注释明确指出若不清除这些信息卷将无法被 Velero 重新绑定。7. 更多例外终态对象pkg/restore/restore.go 的isCompletedL2554-L2578还会识别已完结的对象状态为Failed/Succeeded的 Pod或带有status.completionTime的 Job。这类对象在备份时刻已经是终态恢复一个已完成的 Pod/Job 没有意义恢复引擎会据此决定是否跳过避免在新集群中恢复出陈旧的一次性工作负载。三、实操如何验证恢复后的集群状态FAQ 本身没有给出验证步骤但其结论all of the objects ... should be just as they were before可以在 v0.6.0 的快速入门 site/content/docs/v0.6.0/_index.md 中找到完整的验证路径这里补充为可操作的检查清单发起恢复ark restore create nginx-backup当前版本对应命令为velero restore create ...。查看恢复状态ark restore get关注STATUS、WARNINGS、ERRORS三列。判定标准当STATUS为Completed、且WARNINGS与ERRORS均为 0 时恢复成功。排查细节若有告警或错误用ark restore get RESTORE NAME -o yaml查看恢复对象的详细结果。预期差异提醒验证时请记住本文第二部分的内容——Pod 会被重新调度到新节点、Service 会拿到新的 ClusterIP 与 NodePort、对象的uid/resourceVersion/status均会重置。恢复成功不等于字节级一致而是业务状态一致、且能在新集群正常运行。小结回到 FAQ 的两个核心结论etcd 备份 vs Velero前者解决单个 etcd 集群的数据丢失恢复如 etcd 升级前的保险后者解决集群级的备份/恢复、迁移与选择性备份由于 Velero 把资源清单与 PV 快照放在对象存储和云快照中它可以在新集群中重建一切而这是 etcd 备份做不到的。恢复保真度Velero 会尽最大可能还原对象但会主动改写那些绑定旧集群状态的字段——Pod 的nodeName与 token 卷、Service 的ClusterIP/NodePort、Job 的controller-uid、PV/PVC 的绑定信息、所有对象的元数据与 status——这些改写恰恰是恢复能在全新集群中成功落地的前提。想深入了解每个改写规则可以继续研读 pkg/restore/actions 目录下各*_action.go文件及其配套的*_action_test.go测试用例。【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表