ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Velero 灾备实战:基于 Schedule 定时备份与只读备份存储位置的灾难恢复流程

Velero 灾备实战:基于 Schedule 定时备份与只读备份存储位置的灾难恢复流程 Velero 灾备实战:基于 Schedule 定时备份与只读备份存储位置的灾难恢复流程【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero本文基于 Velero 官方文档 disaster-case 展开,讲解 Kubernetes 集群灾难恢复场景下的完整操作链路:如何通过 Schedule 建立每日定时备份、利用--ttl控制备份保留期,以及在恢复期间将备份存储位置(BackupStorageLocation)切换为只读模式,防止备份在恢复过程中被意外创建或删除。读完后,你可以直接复制文中的命令在自己的集群上执行灾备演练,并能从 Velero 源码层面理解只读保护是如何在各个控制器中生效的。灾备场景与整体思路Velero 是 Kubernetes 应用的备份与迁移工具,每个操作(按需备份、定时备份、恢复)都是一个存储在 etcd 中的 Kubernetes CRD 对象,由对应的控制器驱动执行。当集群发生服务中断等意外事故时,如果你的资源被周期性备份过,就可以回退到之前的状态。灾备的标准流程分为五步:在集群首次运行 Velero Server 之后,建立每日定时备份;灾难发生,需要重建资源;将备份存储位置更新为只读模式(阻止恢复期间创建或删除备份对象);用最近一次备份创建恢复(restore);恢复完成后,将备份存储位置切回读写模式。下面逐步展开,每一步都附带 Velero 源码中的对应实现作为佐证。第一步:创建每日定时备份Velero Server 首次运行后,执行以下命令创建每日备份(将SCHEDULE NAME替换为你期望的名称):velero schedule create SCHEDULE NAME --schedule 0 7 * * *这条命令的要点:--schedule 0 7 * * *是 Cron 表达式,表示每天 7:00 执行一次。Velero 在任意时刻都可以创建 Schedule,首次备份会按照 Cron 表达式的下一次触发时间执行;每次调度生成的 Backup 对象命名为SCHEDULE NAME-TIMESTAMP,其中TIMESTAMP的格式为YYYYMMDDhhmmss(例如daily-backup-20260916070000),这个命名规则在后续创建恢复时要用到;默认备份保留期(以 TTL,即 time to live 表示)为30 天(720 小时),可以用--ttl DURATION标志按需修改。CLI 源码中该 flag 的定义为How long before the backup can be garbage collected.,见 schedule create 的示例:velero create schedule NAME --scheduleevery 168h --ttl 2160h0m0s备份过期(TTL)是如何被执行的保留期的具体行为可以结合 How Velero Works 文档与源码理解:当 Velero 发现某个已有备份资源已过期时,会删除:该备份资源、对象存储中的备份文件、所有 PersistentVolume 快照、以及所有关联的 Restores;过期动作不是立即生效的,而是由 gc-controller 在每小时的调和循环中执行(默认频率),可通过--garbage-collection-frequency DURATION调整。在源码 gc_controller.go 中可以看到默认值:const ( defaultGCFrequency 60 * time.Minute garbageCollectionFailure velero.io/gc-failure )GC 控制器的工作方式是:发现备份已过期后,为其创建一个DeleteBackupRequest对象交由删除流程处理。源码位于 gc_controller.go 的 Reconcile 方法,它先比较backup.Status.Expiration与当前时间,未过期则直接跳过:now : c.clock.Now() if backup.Status.Expiration nil || backup.Status.Expiration.After(now) { log.Debug(Backup has not expired yet, skipping) return ctrl.Result{}, nil }第二步:灾难发生,准备恢复当灾难发生、需要重建资源时,在动手恢复之前,先执行下一步的只读保护。之所以要在恢复期间做只读保护,是因为 Velero 把对象存储当作唯一事实来源(source of truth),它会持续同步备份资源与桶内文件的一致性;恢复期间若发生备份的创建或删除,可能干扰正在进行的恢复操作。第三步:将备份存储位置切换为只读模式执行以下命令,把目标备份存储位置(位于velero命名空间)的accessMode改为ReadOnly:kubectl patch backupstoragelocation STORAGE LOCATION NAME \ --namespace velero \ --type merge \ --patch {spec:{accessMode:ReadOnly}}只读模式在 API 层与控制器层的定义accessMode是BackupStorageLocationSpec 上的字段,合法枚举值只有两个,定义在 backupstoragelocation_types.go:// BackupStorageLocationAccessMode represents the permissions for a BackupStorageLocation. // kubebuilder:validation:EnumReadOnly;ReadWrite type BackupStorageLocationAccessMode string const ( // BackupStorageLocationAccessModeReadOnly represents read-only access to a BackupStorageLocation. BackupStorageLocationAccessModeReadOnly BackupStorageLocationAccessMode ReadOnly // BackupStorageLocationAccessModeReadWrite represents read and write access to a BackupStorageLocation. BackupStorageLocationAccessModeReadWrite BackupStorageLocationAccessMode ReadWrite )从源码结构看,只读保护分布在多个控制器中,各控制器对ReadOnly的判断方式一致——都是比较loc.Spec.AccessMode velerov1api.BackupStorageLocationAccessModeReadOnly:控制器只读模式下的行为源码位置BackupController验证阶段直接拒绝:“backup cant be created because backup storage location %s is currently in read-only mode”backup_controller.goBackupDeletionController拒绝删除备份,返回错误 “cannot delete backup because backup storage location %s is currently in read-only mode”backup_deletion_controller.goGCController跳过过期回收,并给备份打上velero.io/gc-failureBSLReadOnly标签gc_controller.goBackupRepositoryController跳过仓库维护任务:“Skip running maintenance for BackupRepository, because its BSL is in the ReadOnly mode.”backup_repository_controller.goBackupOperationsController同样检查只读模式,阻止备份操作写入backup_operations_controller.go几个值得注意的细节:创建备份被拒是验证错误:BackupController在备份创建前的验证阶段就检查只读模式,并写入request.Status.ValidationErrors,也就是说 Scheduled 备份在只读窗口内的触发会直接失败,而不是静默跳过;过期备份会被“冻结”:GCController在只读模式下不会删除过期备份,而是给备份对象打上velero.io/gc-failureBSLReadOnly标签(相关标签常量定义在 gc_controller.go 中,包含BSLNotFound、BSLCannotGet、BSLReadOnly、BSLUnavailable四种原因)。因此你可以用kubectl get backups -l velero.io/gc-failure筛选出因只读模式等原因未能删除的备份,恢复完成切回读写后,下一轮 GC 循环会自动清除该标签并继续回收;测试用例印证行为:单测验证了只读 BSL 下 GC 会被跳过,见 gc_controller_test.go 和 backup_deletion_controller_test.go。第四步:基于最近的备份创建恢复确认备份存储位置已变为只读后,使用最近一次定时备份(按前面说明,命名形如SCHEDULE NAME-TIMESTAMP)创建恢复:velero restore create --from-backup SCHEDULE NAME-TIMESTAMP恢复执行时,RestoreController会先从对象存储拉取备份信息,对备份中的资源做预处理(例如用备份时的 API 版本校验目标集群是否能恢复该资源),然后逐个恢复每个符合条件的资源。默认是非破坏性恢复:目标集群中已存在的资源会被跳过,可通过--existing-resource-policy标志调整为update策略(详见 How Velero Works 的 Restores 一节)。第五步:恢复完成后切回读写模式恢复工作完成、确认无误后,把备份存储位置切回读写模式,让定时备份和过期回收恢复正常工作:kubectl patch backupstoragelocation STORAGE LOCATION NAME \ --namespace velero \ --type merge \ --patch {spec:{accessMode:ReadWrite}}切回ReadWrite后:Schedule 触发的新备份可以正常写入对象存储;GC 循环会重新评估已过期备份,继续创建DeleteBackupRequest完成回收,并移除velero.io/gc-failure标签;仓库维护(如快照过期清理)任务也会恢复运行。小结与延伸阅读将本文的操作要点归纳为一张速查表:步骤命令目的1velero schedule create SCHEDULE NAME --schedule 0 7 * * *每日 7:00 定时备份,默认保留 30 天,可用--ttl DURATION修改2灾难发生决定重建资源3kubectl patch backupstoragelocation NAME --namespace velero --type merge --patch {spec:{accessMode:ReadOnly}}恢复期间禁止备份创建/删除4velero restore create --from-backup SCHEDULE NAME-TIMESTAMP用最近一次备份恢复5kubectl patch backupstoragelocation NAME --namespace velero --type merge --patch {spec:{accessMode:ReadWrite}}恢复后切回读写,GC 与调度恢复正常延伸阅读:灾备文档原文:disaster-case.md备份过期、对象存储同步机制:how-velero-works.md备份存储位置完整字段说明:backupstoragelocation_types.go恢复参数与 existing-resource-policy 说明:restore-reference.md迁移场景下的类似用法(同样依赖对象存储作为事实来源):migration-case.md【免费下载链接】veleroBackup and migrate Kubernetes applications and their persistent volumes项目地址: https://gitcode.com/GitHub_Trending/ve/velero创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表