
Velero 备份输出文件格式深度解析从对象存储布局到 tar 包内部结构【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero本指南以 Velero及其前身 Ark的备份输出文件格式为核心系统讲解备份产物在对象存储中的目录布局、velero-backup.json元数据文件的字段语义以及 gzip 压缩 tar 包解压后的resources/内部目录结构。读完本文你将掌握如何手工定位、解压、校验和阅读一次 Velero 备份的全部产物并了解当前仓库源码中与之对应的实现与测试证据。备份产物的整体形态一个 gzip 压缩的 tar 文件Velero 的一次备份最终会落成一个gzip 压缩的 tar 文件.tar.gz其文件名与 Backup API 资源的metadata.name完全一致——也就是你在执行velero backup create NAME时指定的那个名称在早期 Ark 版本中命令为ark backup create NAME见关联文档。这一事实可以在源码中得到印证备份执行的核心流程在 pkg/backup/backup.go其中Backup方法的注释明确写着 placing them in a gzip-compressed tar file实现上依次创建gzip.NewWriter(backupFile)与tar.NewWriter(gzippedData)把所有被备份的 Kubernetes 资源对象序列化后写入 tar 流gzippedData : gzip.NewWriter(backupFile) defer gzippedData.Close() tw : NewTarWriter(tar.NewWriter(gzippedData)) defer tw.Close()也就是说tar 负责目录与文件的组织gzip 负责整包压缩二者叠加构成了备份的主体文件。对象存储中的目录布局每个备份一个子目录在云对象存储S3、GCS、Azure Blob 等中每个备份文件被存放在桶内的独立子目录中子目录名同样取自备份名称。以 Ark 时代ark-backup.json为例目录结构形如rootBucket/ backup1234/ ark-backup.json backup1234.tar.gz其中ark-backup.json是备份元数据文件记录与 Backup 资源相关的全部信息包括未显式指定而被填上的默认值相当于一次备份配置的完整历史快照。该 JSON 还包含status.version字段它对应着输出文件格式的版本号用于向后兼容判断。需要特别注意的是这是 v0.8.0 文档时代的命名约定。在当前仓库Velero 主分支的实现中对象存储布局已经演进具体键名由 pkg/persistence/object_store_layout.go 统一生成元数据文件更名为velero-backup.jsongetBackupMetadataKey返回backups/name/velero-backup.json备份主体文件仍为name.tar.gzgetBackupContentsKey新增了配套产物name-logs.gz备份日志、name-podvolumebackups.json.gz、name-volumesnapshots.json.gz、name-itemoperations.json.gz、name-resource-list.json.gz、name-results.gz、name-volumeinfo.json.gz以及 CSI 场景下的-csi-volumesnapshots.json.gz/-csi-volumesnapshotcontents.json.gz/-csi-volumesnapshotclasses.json.gz等。当前实际的顶层子目录由 NewObjectStoreLayout 定义包括backups/、restores/、restic/、metadata/、plugins/、kopia/可在 BSL 中配置 prefix 前缀。因此现代 Velero 的备份存储目录大体为bucket/prefix/ backups/ backup1234/ velero-backup.json backup1234.tar.gz backup1234-logs.gz backup1234-volumesnapshots.json.gz ... restores/ ...写入顺序与容错策略也值得关注在 objectBackupStore.PutBackup 中日志文件上传失败仅是 best-effort不影响备份状态而元数据velero-backup.json上传失败则是 hard-stop一旦后续任何文件上传失败会反向清理已上传的元数据与内容文件避免留下“半成品”备份。示例备份元数据 JSON 文件以下是 Ark 时代ark-backup.json的完整示例引自关联文档{ kind: Backup, apiVersion: ark.heptio.com/v1, metadata: { name: test-backup, namespace: heptio-ark, selfLink: /apis/ark.heptio.com/v1/namespaces/heptio-ark/backups/testtest, uid: a12345cb-75f5-11e7-b4c2-abcdef123456, resourceVersion: 337075, creationTimestamp: 2017-07-31T13:39:15Z }, spec: { includedNamespaces: [ * ], excludedNamespaces: null, includedResources: [ * ], excludedResources: null, labelSelector: null, snapshotVolumes: true, ttl: 24h0m0s }, status: { version: 1, expiration: 2017-08-01T13:39:15Z, phase: Completed, volumeBackups: { pvc-e1e2d345-7583-11e7-b4c2-abcdef123456: { snapshotID: snap-04b1a8e11dfb33ab0, type: gp2, iops: 100 } }, validationErrors: null } }该文件的价值在于即使集群中的 Backup CR 对象已被删除你仍可通过这份 JSON 还原“那次备份到底配置了什么、执行结果如何”。其中status.volumeBackups字段还包含每个已创建云盘快照的详细信息如 AWS 的snapshotID、type、iops方便你在云厂商控制台上人工核对快照。当前版本的字段演进对照当前仓库的 API 类型定义可以清楚看到字段的继承与演进。BackupSpec与BackupStatus的完整定义见 pkg/apis/velero/v1/backup_types.gospec 侧includedNamespaces、excludedNamespaces、includedResources、excludedResources、labelSelector、snapshotVolumes、ttl等核心字段全部保留ttl的类型为metav1.Durationjson:ttl,omitempty即 24h0m0s 这类可被time.ParseDuration解析的字符串。新版本还扩展出includedClusterScopedResources/excludedClusterScopedResources、orLabelSelectors、storageLocation、volumeSnapshotLocations、defaultVolumesToFsBackup、orderedResources、csiSnapshotTimeout、itemOperationTimeout、snapshotMoveData、datamover、uploaderConfig等新能力。status 侧文档示例中的version整数版本号在当前版本中已标记为Deprecated新增了更精确的formatVersion字符串字段json:formatVersion,omitempty此外还增加了startTimestamp、completionTimestamp、volumeSnapshotsAttempted/volumeSnapshotsCompleted、warnings/errors、progresstotalItems/itemsBackedUp、hookStatus等字段。API 组从文档时代的ark.heptio.com/v1迁移为当前的velero.io/v1默认命名空间也由heptio-ark变为velero见 pkg/apis/velero/v1/constants.go 的DefaultNamespace velero。status.formatVersion的写入位置在 pkg/controller/backup_controller.go值为pkgbackup.BackupFormatVersion即当前仓库中的备份格式版本常量1.1.0见 pkg/backup/backup.go。这表明现代备份的格式版本是一个major.minor.patch三段的语义化版本号而非早期文档中的单一整数version: 1。文件格式版本 1解压后的 tar 包内部结构status.version早期/status.formatVersion当前标识着 tar 包内部的输出文件格式。文档所描述的file format version 1中解压一个典型的备份包如backup1234.tar.gz后目录结构如下resources/ persistentvolumes/ cluster/ pv01.json ... configmaps/ namespaces/ namespace1/ myconfigmap.json ... namespace2/ ... pods/ namespaces/ namespace1/ mypod.json ... namespace2/ ... jobs/ namespaces/ namespace1/ awesome-job.json ... namespace2/ ... deployments/ namespaces/ namespace1/ cool-deployment.json ... namespace2/ ... ...目录组织的三层语义从当前源码的常量定义pkg/apis/velero/v1/constants.go与解析器实现pkg/archive/parser.go可以完整还原这套结构的语义顶层resources/ResourcesDir resources所有被备份的资源对象都存放在该目录下第二层为资源类型目录命名形如pods、deployments、persistentvolumes对于非核心组资源会带 group 后缀如deployments.apps、horizontalpodautoscalers.autoscaling解析器注释中明确给出 resource.group 命名示例每个资源类型目录下还可以按 API 版本进一步拆分例如pods/v1-preferredversionPreferredVersionDir -preferredversion用于标记首选 API 版本第三层区分作用域ClusterScopedDir cluster与NamespaceScopedDir namespaces集群作用域资源如 PV放在cluster/下文件名为name.json命名空间作用域资源如 ConfigMap、Pod、Job、Deployment放在namespaces/namespace/下文件名为objectname.json。因此一次备份中每个被捕获的 API 对象都对应一个独立的 JSON 文件路径 resources/资源类型[/api版本]/cluster|namespaces/ns/对象名.json。文件的内容即该对象的完整 Kubernetes manifestJSON 序列化可直接用于人工审阅或离线恢复分析。上述路径规则同样有测试用例背书pkg/backup/backup_test.go 断言生成的 tar 中包含诸如resources/pods/namespaces/foo/bar.json、resources/deployments.apps/namespaces/foo/bar.json、resources/pods/v1-preferredversion/namespaces/foo/bar.json这样的路径。现代备份包中的新增目录metadata/除resources/之外当前版本还在 tar 包顶层新增了metadata/目录MetadataDir metadata。备份开始时kubernetesBackupper.BackupWithResolvers 会调用writeBackupVersion[pkg/backup/backup.go#L1077-L1095]向 tar 包写入metadata/version文件内容为BackupFormatVersion当前为1.1.0加换行versionFile : filepath.Join(velerov1api.MetadataDir, version) versionString : fmt.Sprintf(%s\n, BackupFormatVersion)这使得备份包自身即可自描述格式版本而无需依赖对象存储中元数据 JSON 文件的status字段。备份包的解压与安全校验当你需要手工检查或离线分析一个备份包时可直接用系统工具解压tar -xzf backup1234.tar.gz而 Velero 自身在恢复流程中会通过 pkg/archive/extractor.go 的UnzipAndExtractBackup将 gzip tar 流解压到临时目录这一过程带有两道重要安全防线防 Zip 炸弹Extractor.readBackup会累计所有条目大小超过上限默认16 30即 16 GiB可通过SetMaxExtractionSize在服务启动时调整即中止解压并报错防路径穿越sanitizeArchivePathpkg/archive/extractor.go会校验每个 tar 条目经filepath.Join后仍位于目标目录内防止恶意构造的../路径把文件写到临时目录之外。随后 pkg/archive/parser.go 的ParseGroupVersions等函数负责扫描解压目录按resources/resource.group/apiVersion/...的层级还原出备份中包含的 API 组、版本与资源对象清单供恢复控制器调度使用。实操如何定位并阅读一次备份的产物综合以上内容一次完整的手工排查路径如下用velero backup get或ark backup get找到备份名称NAME登录 BSL 对应的对象存储控制台进入bucket/prefix/backups/NAME/目录通常能看到velero-backup.json当前版本早期 Ark 版本为ark-backup.json——备份配置与状态的历史记录NAME.tar.gz——备份主体NAME-logs.gz、NAME-volumesnapshots.json.gz、NAME-resource-list.json.gz等配套文件视版本而定阅读velero-backup.json的spec确认备份范围与参数、status.phase确认执行结果如Completed、status.formatVersion确认文件格式版本下载NAME.tar.gz并解压进入resources/按资源类型 → cluster|namespaces/ns → 对象.json的结构逐个核对被备份的对象通过metadata/version文件确认备份包自身的格式版本。整个文件格式的键名生成、写入与解析逻辑均可分别在 pkg/persistence/object_store_layout.go、pkg/persistence/object_store.go、pkg/backup/backup.go 与 pkg/archive 中追踪验证对应的格式断言见 pkg/backup/backup_test.go 中的路径校验用例。掌握这套格式无论面对备份产物审计、跨版本迁移还是故障排查都能直接“读懂”对象存储里那份原始备份。【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考