尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Longhorn 定时任务 Age-Based 保留策略:基于时长的快照/备份/系统备份自动清理

发布时间:2026/9/28 3:00:08

资讯中心
01
ARTICLE

Longhorn 定时任务 Age-Based 保留策略:基于时长的快照/备份/系统备份自动清理

Longhorn 定时任务 Age-Based 保留策略:基于时长的快照/备份/系统备份自动清理
云原生存储高可用容器编排【免费下载链接】longhornCloud-Native distributed storage built on and for Kubernetes项目地址https://gitcode.com/gh_mirrors/lo/longhorn点击查看免费下载导读本文围绕 Longhorn 新增的age-based基于时长保留策略展开讲解如何让snapshot、snapshot-force-create、backup、backup-force-create与system-backup类定时任务Recurring Job按保留时间窗口而非保留数量自动清理过期产物。读者将掌握retentionPolicy与retainAge两个新字段的完整用法、与既有count-based策略的互斥关系、CRD 校验规则、webhook 拦截行为以及升级到新版本后存量定时任务的自动回填机制从而在合规备份、低写入卷快照治理等场景中直接落地。背景为什么需要按时长保留Longhorn 的 Recurring Job 是围绕 CRD 构建的定时任务机制详见 enhancements/20210624-label-driven-recurring-job.md通过cron表达式调度对挂载的卷执行快照、备份、文件系统 trim 等操作。长期以来清理策略只有一种spec.retain即保留最近 N 个产物。这种按数量模型存在两个结构性弱点数量与时间窗口脱钩retain: 90只有在cron保持每天一次时才近似等于90 天。一旦有人把 cron 改成每天两次保留窗口会无声地缩短到 45 天旧备份可能被提前销毁而retain与cron之间的漂移在 spec 中完全不可见。低写入卷上的快照链膨胀对长期处于 detached 状态的卷若未开启allow-recurring-job-while-volume-detached设置定时任务会跳过运行导致凑满 N 个才清理迟迟无法触发快照链在空闲期不断累积。age-based策略正是为解决这两类问题而设计保留窗口由产物的创建时间戳直接约束与调度频率、漏跑次数、cron 是否被修改都无关。核心概念两种互斥的保留策略增强方案为 RecurringJob 增加两个新字段见 chart/templates/crds.yaml L3258-3286 的 CRD schema 定义retentionPolicy取值为count-based或age-basedCRD 通过enum约束L3283-3285且默认值为count-basedL3275。retainAge以 Go duration 字符串表示的保留时长例如10m、24h、8760h。注意 Go duration没有天和年的单位一天必须写成24h、一年写成8760h。CRD 通过XValidation规则!self.startsWith(-)拒绝负值L3271-3273。两种策略的行为与互斥关系如下表策略生效字段被忽略字段清理依据count-based默认retainretainAge保留最新 N 个产物age-basedretainAgeretain清理创建时间早于now - retainAge的产物两者严格独立、互斥count-based完全忽略retainAgeage-based完全忽略retainretain可以照旧保留在 spec 中只是不会被读取。这也保证了升级路径的兼容性——存量任务在升级后默认回填为count-based继续删除与升级前完全相同的产物集合。典型用户场景场景一合规驱动的备份时间窗运维要求卷备份恰好保留 90 天然后清除改造前必须把90 天手工换算成 cron 频率下的数量——每天备份一次就得写retain: 90。这个换算只在调度不变时成立若 cron 被改成每天两次保留窗口会无声减半为 45 天旧备份被过早销毁retain与cron的漂移在 spec 中不可见故障不可感知。改造后设置retentionPolicy: age-based与retainAge: 2160h。每次运行都会以每个备份的创建时间戳为准强制执行时间窗无论调度多频繁、是否有运行被跳过、cron 是否被编辑过窗口都恒定。retain保持原值不参与计算。场景二低写入卷的快照治理团队对几乎不写入的卷每小时做一次快照设置retain: 24期望约一天历史。但数量阈值要凑满 24 次运行才触发清理且当allow-recurring-job-while-volume-detached关闭时工作负载在夜间与周末缩容到 0 会导致任务跳过于是最老快照经常是几天前的单个快照虽便宜但快照链不断增长卷的快照数在长空闲期持续漂移上浮。改造后retentionPolicy: age-based、retainAge: 24h。下一次运行时超过一天的所有快照都会被清理无论是否已积累 24 个空闲期反而会收缩快照链而不是拉长它。实际使用YAML 配置与命令行查看创建一个保留一年备份的 age-based 任务apiVersion: longhorn.io/v1beta2 kind: RecurringJob metadata: name: yearly-backup namespace: longhorn-system spec: cron: 0 2 * * * task: backup groups: - default retentionPolicy: age-based retainAge: 8760hretain可以存在但会被忽略。按原样书写的 count-based 任务count-based 的写法与升级前完全一致但官方建议显式设置retentionPolicy: count-basedapiVersion: longhorn.io/v1beta2 kind: RecurringJob metadata: name: save-24-snapshots namespace: longhorn-system spec: cron: 0 * * * * task: snapshot retentionPolicy: count-based retain: 24用 kubectl 列出定时任务CRD 新增的 printer columns 会在kubectl get中直接展示保留策略信息对应 chart/templates/crds.yaml L3181-3194 的RetentionPolicy、RetainCount、RetainAge列定义$ kubectl -n longhorn-system get lhrj NAME GROUPS TASK CRON RETENTIONPOLICY RETAINCOUNT RETAINAGE CONCURRENCY AGE hourly-snap [default] snapshot 0 * * * * count-based 24 1m 2 31d yearly-backup [default] backup 0 2 * * * age-based 50 8760h 2 10s被拒绝的配置以下配置会在kubectl apply时被准入 webhookadmission webhook拦截错误信息随行给出配置结果retentionPolicy: age-based且task: snapshot-delete或snapshot-cleanup、filesystem-trim拒绝 —recurring job retention policy age-based can not be used with task snapshot-deleteretentionPolicy: Age-Based/age_based/ 任何其他值被 CRD enum 拒绝webhook 报retentionPolicy should be count-based or age-basedretainAge: -1h被 CRDXValidation拒绝 —retainAge must be a positive durationretainAge: 1d或1y解码阶段拒绝 — Go duration 没有天/年单位应写24h/8760hretentionPolicy: count-basedretain: 0task: backup拒绝 —recurring job retain count 0 must be greater than 0API 变更字段与 CRD 落地增强方案对RecurringJobCreate与RecurringJobUpdateAPI 增加RetentionPolicy与RetainAge字段。其类型定义如下来自原设计文档的 Go 结构体type RecurringJob struct { client.Resource longhorn.RecurringJobSpec longhorn.RecurringJobStatus } ... type RecurringJobSpec struct { ... // The number of snapshots/backups to retain. // Retain applies only when the retention policy is count-based. // optional Retain int json:retain // The retention age of the snapshot/backup, specified as a Go duration string, // such as 10m, 24h, or 8760h. Note that Go durations have no day or year unit, // so a day is 24h. Snapshots/backups older than this are cleaned up by the recurring job. // Only takes effect when the retention policy is age-based. // If the retention policy is age-based and this value is 0s, the recurring job will not start. // kubebuilder:validation:XValidation:rule!self.startsWith(-),messageretainAge must be a positive duration RetainAge metav1.Duration json:retainAge,omitempty // The retention policy that determines whether the recurring job cleans up // snapshots/backups based on their count or age. Can be count-based or // age-based. The two policies work independently: count-based (the default) // retains the configured number of newest snapshots/backups and ignores // RetainAge, while age-based retains snapshots/backups no older than RetainAge // and ignores Retain. // kubebuilder:default:count-based RetentionPolicy RecurringJobRetentionPolicy json:retentionPolicy,omitempty ... }该结构已在当前仓库的 CRD 清单中实际落地可以从两处核对完整 schemaHelm chart 模板 chart/templates/crds.yaml L3154-3318recurringjobs.longhorn.ioCRD 的v1beta2版本定义了retainL3258-3262、retainAge含负值 XValidationL3263-3273、retentionPolicy含 enum 与default: count-basedL3274-3286、task的八种取值L3287-3300以及新增的RetentionPolicy/RetainCount/RetainAgeprinter columnsL3181-3194。直接部署清单 deploy/longhorn.yaml L3529-3628与 Helm 模板对应的 CRD 定义retentionPolicy默认count-basedL3623-3624retainAge的 XValidation 规则为!self.startsWith(-)L3621-3622。设计原理保留逻辑与准入校验统一清理判定函数filterExpiredItems所有保留逻辑集中在app/recurringjob/util.go的辅助函数filterExpiredItems中。它先把产物按创建时间从旧到新排序再依据policy为每个产物精确选择一个判定谓词func filterExpiredItems(nts []NameWithTimestamp, retainCount int, retainAge time.Duration, policy longhorn.RecurringJobRetentionPolicy, now time.Time) []string { ... switch policy { case longhorn.RecurringJobRetentionPolicyAgeBased: expired retainAge 0 now.Sub(nt.Timestamp) retainAge case longhorn.RecurringJobRetentionPolicyCountBased: expired i len(nts)-retainCount default: // This case is unreachable: // new jobs default to count-based, existing jobs are backfilled on upgrade, and the webhook rejects an empty or unrecognized policy. // Returning nothing is the safe failure mode, so an unexpected policy never deletes anything. return ret } ... }值得注意的设计细节age-based分支要求retainAge 0才判定过期且default分支理论上不可达选择什么都不删的安全失败模式——任何意外策略都不会误删产物。变更 webhookmutateRetainCountAndRetainAge原先Create与Update两个处理函数里重复的按任务类型保留参数归一化逻辑被抽取为mutateRetainCountAndRetainAge。它针对清理类任务snapshot-cleanup、filesystem-trim、snapshot-delete把retainAge归一化为0s这些任务不存在时间窗口概念对其他任务则把非正时长默认补写为0s0s会让 age-based 任务无法启动避免误配func mutateRetainCountAndRetainAge(patchOps admission.PatchOps, recurringJob *longhorn.RecurringJob, log *logrus.Entry) admission.PatchOps { switch recurringJob.Spec.Task { case longhorn.RecurringJobTypeSnapshotCleanup, longhorn.RecurringJobTypeFilesystemTrim, longhorn.RecurringJobTypeSnapshotDelete: ... if recurringJob.Spec.RetainAge.Duration ! 0 { patchOps append(patchOps, {op: replace, path: /spec/retainAge, value: 0s}) } default: ... if recurringJob.Spec.RetainAge.Duration 0 { // RetainAge defaults to 0, which prevents an age-based recurring job from starting. patchOps append(patchOps, {op: add, path: /spec/retainAge, value: 0s}) } }校验 webhookvalidateRetentionPolicy校验 webhook 新增validateRetentionPolicy负责四件事拒绝负的retainAge、拒绝在清理类任务上使用age-based、拒绝无法识别的策略值同时保持 count-based 下原有retain 0的约束不变func validateRetentionPolicy(policy longhorn.RecurringJobRetentionPolicy, task longhorn.RecurringJobType, retain int, retainAge metav1.Duration) error { if retainAge.Duration 0 { return err } notCleanupTask : (task ! longhorn.RecurringJobTypeSnapshotCleanup task ! longhorn.RecurringJobTypeFilesystemTrim task ! longhorn.RecurringJobTypeSnapshotDelete) switch policy { case longhorn.RecurringJobRetentionPolicyCountBased: if notCleanupTask retain 0 { return err } return nil case longhorn.RecurringJobRetentionPolicyAgeBased: if !notCleanupTask { return err } return nil } return err }由此形成三层防线CRD 的enum与XValidation在 schema 层面拦截非法值变更 webhook 归一化参数校验 webhook 执行任务-策略组合的语义检查最终filterExpiredItems的 default 分支兜底。测试计划集成/e2e 测试longhorn-tests计划覆盖以下四组场景Age-based 备份/快照保留创建卷与backup/snapshot定时任务设置retentionPolicy: age-based、短retainAge如5m、cron 为*/1 * * * *验证产物的创建时间符合预期且五分钟内恰好保留五个备份/快照。age-based 下数量不参与计算retain: 1配合覆盖多次运行的retainAge必须保留多于一个产物。count-based 下时长不参与计算retain: 3配合短于一个 cron 周期的retainAge仍须保留三个产物。拒绝场景将被拒绝的配置表中的每一行分别通过 Kubernetes API 与 HTTP API 提交断言操作均失败。升级场景安装 Longhorn v1.12.x → 创建卷 A 与 backup/snapshot 定时任务 B 并绑定 → 升级到 v1.13.x-head 或 master-head → 断言任务 B 的Spec.RetentionPolicy自动变为count-based且任务 B 对卷 A 的运作不变。升级策略存量任务自动回填升级路径由upgrade/v112xto1130完成对每个RecurringJob.Spec.RetentionPolicy为空的存量 CR统一回填为count-based。配合 CRD 的default: count-based默认值可以保证升级前创建的定时任务保留策略与升级前完全一致继续删除相同集合的产物新建任务即使不显式写retentionPolicy也默认按 count-based 工作两个模式严格互斥不会出现既按数量又按时长的混合行为。与周边机制配合StorageClass 选择器与相关设置age-based 定时任务完全兼容现有的标签驱动调度体系。定时任务通过groups与卷标签绑定默认组default自动作用于无任务标签的卷参见 enhancements/20210624-label-driven-recurring-job.md 的用户场景二也可以在 StorageClass 中通过recurringJobSelector在创建卷时挂接例如 examples/storageclass.yaml L22-23 的示例# recurringJobSelector: [{name:snap-group, isGroup:true}, # {name:backup, isGroup:false}]Helm 部署时对应的配置项见 chart/values.yaml L211-215recurringJobSelector.enable与jobList。与保留策略相关的全局设置chart/values.yaml 中均有 Helm 化配置allow-recurring-job-while-volume-detachedL281-282是否在卷处于 detached 状态时仍执行定时任务。Story 2 中提到的空闲期快照链膨胀即与该设置相关age-based策略能有效缓解该设置关闭时的累积问题。recurring-job-max-retentionL319-320全局上限限制单个卷可保留的最大快照/备份数量可作为 age-based 之外的第二道护栏。restore-volume-recurring-jobsL313-314从备份目标恢复卷时自动重建定时任务恢复出的任务同样遵循新的保留策略字段。小结retentionPolicy: age-basedretainAge为 Longhorn Recurring Job 补齐了时间窗口维度的清理能力使快照、备份与系统备份的保留不再依赖数量 × 调度频率的脆弱换算。两个策略由 CRD enum、默认值、XValidation、变更/校验 webhook 与filterExpiredItems单点判定共同约束保证互斥性、安全性与升级兼容性存量任务通过upgrade/v112xto1130自动回填为count-based升级无需人工干预。对于合规保留、低写入卷治理等场景这是比retain更稳定、更可审计的保留方案。赞分享云原生存储高可用容器编排【免费下载链接】longhornCloud-Native distributed storage built on and for Kubernetes项目地址https://gitcode.com/gh_mirrors/lo/longhorn点击查看免费下载相关推荐Marge-bot 与 GitLab 工作流集成如何优化团队代码审查流程Marge bot 与 GitLab 工作流集成如何优化团队代码审查流程 Marge bot 是一款专为 GitLab 设计的合并机器人merge botMealie 备份自动化基于 n8n 实现每日定时备份与保留 7 份的滚动清理Mealie 备份自动化基于 n8n 实现每日定时备份与保留 7 份的滚动清理 Mealie 自带完善的备份与恢复能力但手动备份容易遗忘。本文以官方社区指南后端前端docker-gitlab备份保留策略基于时间与版本的清理规则docker gitlab备份保留策略基于时间与版本的清理规则 引言 在使用Dockerized GitLab项目路径时备份管理是确保数据安全的关键环节运维云原生上一篇将 Ultralytics YOLO 模型导出为 TFLite Edge TPU 格式并部署到边缘设备下一篇LinkAndroid手机投屏神器实现安卓设备与电脑无缝连接的终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。