Velero(Ark)create schedule 命令详解:定时备份调度配置实战指南
Velero(Ark)create schedule 命令详解:定时备份调度配置实战指南
导读
create schedule 是 Velero(早期版本名为 Ark)命令行工具中用于创建**定时备份(Scheduled Backup)**的核心命令。通过一条 cron 表达式,它能让 Velero 自动、周期性地为 Kubernetes 集群执行备份任务,是集群数据保护策略中实现"按计划自动备份"的标准手段。读完本文,你将掌握该命令的完整参数体系、cron 表达式与 @every 两种调度写法、以及如何结合备份过滤、标签、TTL 等参数构造生产可用的定时备份。
说明:本文对应仓库中的 v0.6.0 文档 ark_create_schedule.md。该版本 CLI 名称为
ark,后续版本更名为velero,本文两种写法都会给出,并基于仓库源码剖析命令背后的实现机制。
命令概述与基本用法
命令原型
create schedule 子命令用于创建一个定时执行备份的 Schedule 对象,其基本语法为:
ark create schedule NAME [flags]
在引入 ark schedule 子命令组之后,等价写法为:
ark schedule create NAME [flags]
仓库 pkg/cmd/cli/schedule/create.go 中 NewCreateCommand 定义了该命令:它接收且仅接收一个位置参数 NAME(cobra.ExactArgs(1) 强制校验),作为待创建的 Schedule 名称。
--schedule 是必填参数。从源码 Validate 方法可以看出,一旦 --schedule 为空字符串,命令会直接报错 "--schedule is required"(见 pkg/cmd/cli/schedule/create.go)。
命令执行流程
从源码的 Run 方法(pkg/cmd/cli/schedule/create.go)可以还原出该命令的完整执行链路:
- 通过
f.KubebuilderClient()获取访问 Kubernetes API 的 client; - 若指定了
--ordered-resources,调用backup.ParseOrderedResources解析资源执行顺序; - 将所有 CLI 参数组装成一个
velero.io/v1的Schedule对象(Spec.Template就是一次完整备份的BackupSpec); - 若指定了
-o/--output,先以 table/json/yaml 格式打印对象但不提交(output.PrintWithFormat); - 否则调用
crClient.Create将 Schedule 提交到集群,并打印Schedule "NAME" created successfully.。
一个最小可用的例子
# 每 6 小时执行一次备份(cron 写法)
ark create schedule my-backups --schedule="0 */6 * * *"
# 等价写法:@every 写法
ark create schedule my-backups --schedule="@every 6h"
命令执行成功后,Velero 的 ScheduleController 会持续监听该对象,并在每个调度时刻自动创建对应的 Backup 资源。默认创建的备份名称格式为 schedule名-时间戳,如 my-backups-20260916001505(时间戳格式 20060102150405,见 pkg/apis/velero/v1/schedule_types.go 中 TimestampedName 方法)。
调度表达式(--schedule)详解
--schedule 支持两种写法:标准 5 字段 cron 表达式和 @every 间隔语法。
标准 cron 表达式(UTC 时间)
参考源码中命令的 Long 描述(pkg/cmd/cli/schedule/create.go),标准 cron 表达式包含 5 个字段,按空格分隔,取值为:
| 字段位置 | 字段含义 | 可接受值 |
|---|---|---|
| 1 | 分钟(Minute) | 0-59, * |
| 2 | 小时(Hour) | 0-23, * |
| 3 | 日期(Day of Month) | 1-31, * |
| 4 | 月份(Month) | 1-12, * |
| 5 | 星期(Day of Week) | 0-6, * |
重要前提:cron 表达式基于 UTC 时间计算,这一点与 crontab 的本地时区语义不同,在规划"每天凌晨执行"之类的任务时务必换算时差,避免备份时间与预期不符。
常用示例:
# 每天 02:00(UTC)执行一次
ark create schedule daily-backup --schedule="0 2 * * *"
# 每个整点执行一次
ark create schedule hourly-backup --schedule="0 * * * *"
# 每周一 01:00(UTC)执行一次
ark create schedule weekly-backup --schedule="0 1 * * 1"
@every 间隔语法
除了标准 cron,还支持 @every <duration> 形式,duration 可由秒(s)、分(m)、时(h)组合:
@every 2h30m # 每 2 小时 30 分钟一次
@every 6h # 每 6 小时一次
@every 168h # 每 7 天(168 小时)一次
从源码看,ScheduleController 使用 github.com/netresearch/go-cron 库解析调度表达式,并通过 cron.ParseStandard 解析标准 cron(见 pkg/controller/schedule_controller.go),同时以 recover() 兜底空字符串导致的 panic。
调度如何触发备份
从源码(pkg/controller/schedule_controller.go)可还原调度触发逻辑:
getNextRunTime以上一次备份时间(Status.LastBackup)为基准,调用cronSchedule.Next(...)计算下一次运行时间,判断当前时刻是否到期(ifDue);- 到期后,controller 会生成一个新的 Backup,其规格即 Schedule 的
Spec.Template,随后更新Status.LastBackup时间戳; - 整个 Schedule 拥有三种生命周期阶段(见 pkg/apis/velero/v1/schedule_types.go):
New(已创建未处理)、Enabled(校验通过、正常触发备份)、FailedValidation(校验失败、不会触发备份)。因此创建后应通过ark get schedules确认其 Phase 为Enabled。
备份内容控制参数
调度每次触发的备份内容,由下面这组参数决定。它们本质上是把一次"临时备份"的 BackupSpec 完整嵌入到 Schedule 的 Spec.Template 中(对应源码 pkg/cmd/cli/schedule/create.go 中 IncludedNamespaces、IncludedResources、LabelSelector 等字段的赋值)。
命名空间过滤
| 参数 | 说明 | 默认值 |
|---|---|---|
--include-namespaces stringArray |
要备份的命名空间列表,* 表示全部 |
* |
--exclude-namespaces stringArray |
要从备份中排除的命名空间 | 空 |
# 只备份 web 命名空间
ark create schedule web-daily --schedule="@every 24h" --include-namespaces web
# 备份除 kube-system 之外的所有命名空间
ark create schedule cluster-backup --schedule="@every 24h" --exclude-namespaces kube-system
资源类型过滤
| 参数 | 说明 |
|---|---|
--include-resources stringArray |
要备份的资源,格式为 resource.group,如 storageclasses.storage.k8s.io;* 表示全部资源 |
--exclude-resources stringArray |
要排除的资源,同样使用 resource.group 格式 |
资源名的"组"后缀很重要:例如 deployments.apps 与裸的 deployments 是不同的匹配粒度。使用 kubectl api-resources 可查看每种资源完整的 resource.group 名称。
# 只备份 deployments 和 PVC
ark create schedule app-backup --schedule="@every 12h" \
--include-resources deployments.apps,persistentvolumeclaims
集群级资源与标签选择器
| 参数 | 说明 | 默认值 |
|---|---|---|
--include-cluster-resources optionalBool[=true] |
是否备份集群作用域资源(如 Namespace、CRD) | true |
-l, --selector labelSelector |
仅备份匹配该标签选择器的资源 | <none> |
optionalBool 类型支持 true/false 两种显式取值,不指定时使用默认值 true。
# 仅备份带 app=myapp 标签的资源,且不包含集群级资源
ark create schedule app-backup --schedule="@every 6h" \
--selector "app=myapp" --include-cluster-resources=false
卷快照控制
| 参数 | 说明 | 默认值 |
|---|---|---|
--snapshot-volumes optionalBool[=true] |
是否在备份中对 PersistentVolume 执行快照 | true |
若集群中未配置对应的卷快照位置(VolumeSnapshotLocation),可将此参数设为 false,让备份只保存资源清单而不产生云盘快照:
ark create schedule config-only --schedule="@every 24h" --snapshot-volumes=false
备份生命周期与元数据参数
TTL:备份可被 GC 回收的时间
| 参数 | 说明 | 默认值 |
|---|---|---|
--ttl duration |
备份创建多久后可以被垃圾回收(garbage collected) | 720h0m0s(30 天) |
TTL 采用 Go duration 格式(h/m/s 组合)。默认 720 小时 = 30 天,恰好与服务器端 --default-backup-ttl 的默认值 30 * 24 * time.Hour 一致(见 pkg/cmd/server/config/config.go)。TTL 到期后,备份由 GC 控制器(gc controller)清理。
# 每周备份一次,每个备份保留 90 天(2160 小时)
ark create schedule weekly-long --schedule="@every 168h" --ttl 2160h0m0s
# 备份只保留 7 天
ark create schedule weekly-short --schedule="@every 168h" --ttl 168h0m0s
标签与显示控制
| 参数 | 说明 |
|---|---|
--labels mapStringString |
为备份对象附加的标签(key=value 形式) |
--label-columns stringArray |
在 get 输出中作为列展示的标签列表(逗号分隔) |
--show-labels |
在 get 输出的最后一列显示标签 |
-o, --output string |
输出格式:table、json、yaml;对 create 命令而言,仅打印对象而不提交到服务器 |
# 打上 team 标签,并在查询时将其作为单独一列显示
ark create schedule team-backup --schedule="@every 24h" \
--labels "team=platform" --label-columns team
# 仅打印 YAML 而不真正创建(预演)
ark create schedule dry-run --schedule="@every 24h" -o yaml
-o 的"预演"能力来自源码中的 output.PrintWithFormat(pkg/cmd/cli/schedule/create.go):一旦指定了输出格式,命令打印对象后直接返回,不再调用 crClient.Create,非常适合先审查生成的 Schedule 定义再落库。
从父命令继承的通用参数
以下参数由所有 ark 子命令继承,用于控制集群连接与日志(详见 site/content/docs/v0.6.0/cli-reference/ark.md 及 README.md):
| 参数 | 说明 |
|---|---|
--kubeconfig string |
kubeconfig 文件路径;未设置时依次尝试 $KUBECONFIG 环境变量与集群内(in-cluster)配置 |
--logtostderr |
日志输出到标准错误而不是文件 |
--alsologtostderr |
同时输出日志到标准错误和文件 |
--stderrthreshold severity |
达到该级别及以上的日志写入 stderr(默认 2) |
-v, --v Level |
V 日志级别 |
--vmodule moduleSpec |
按文件过滤的日志级别设置(pattern=N,逗号分隔) |
--log_backtrace_at traceLocation |
当日志命中 file:N 时输出堆栈(默认 :0) |
--log_dir string |
日志文件输出目录 |
集群凭证的查找顺序为:--kubeconfig 命令行参数 → $KUBECONFIG 环境变量 → 集群内凭证(仅当 Ark/Velero 运行在 Pod 内时生效)。
推荐实践:从 Ark 到 Velero 的完整示例
仓库自 v0.6.0 之后的版本将 CLI 从 ark 更名为 velero,子命令从 create schedule 演进为 schedule create(两者在当前代码库 pkg/cmd/cli/schedule/schedule.go 与 pkg/cmd/cli/schedule/create.go 中并存)。以下示例使用现代 velero 语法,可作为生产配置模板:
# 1) 每 6 小时备份整个集群(排除 kube-system 与 velero 自身)
velero schedule create cluster-6h \
--schedule="0 */6 * * *" \
--exclude-namespaces kube-system,velero \
--ttl 168h0m0s \
--snapshot-volumes=true
# 2) 每天 02:00 (UTC) 备份 web 与 db 两个命名空间,按 app 标签过滤
velero schedule create prod-apps-daily \
--schedule="0 2 * * *" \
--include-namespaces web,db \
--selector "env=production" \
--ttl 720h0m0s \
--labels "backup-policy=daily,team=platform"
# 3) 验证调度状态(应显示 Enabled)
ark get schedules
# 4) 查看某个调度生成的备份
ark get backups -l velero.io/schedule-name=cluster-6h
验证与排障建议
- 确认 Schedule Phase:新建的 Schedule 只有进入
Enabled阶段才会触发备份;若显示FailedValidation,说明 cron 表达式或 Template 校验失败,可通过ark describe schedule NAME查看ValidationErrors详情(对应 pkg/apis/velero/v1/schedule_types.go 中的ValidationErrors字段); - 核对备份是否生成:每次触发会生成
schedule名-YYYYMMDDHHMMSS格式的 Backup,可用ark get backups核对触发时间是否符合预期; - 注意时区:cron 基于 UTC,跨时区团队务必换算;
- 先预演再落地:任何复杂参数组合,先用
-o yaml检查生成的 Schedule 定义,再真正创建。
源码阅读指引
若希望进一步深入理解 create schedule 的实现,可沿以下路径阅读:
- 命令定义与参数绑定:pkg/cmd/cli/schedule/create.go
- Schedule 自定义资源类型(Spec/Status/Phase):pkg/apis/velero/v1/schedule_types.go
- 调度控制器(cron 解析、到期判断、触发备份):pkg/controller/schedule_controller.go
- 备份默认 TTL 与服务器端配置:pkg/cmd/server/config/config.go
- 集群凭证加载顺序:site/content/docs/v0.6.0/cli-reference/README.md
通过 CLI 创建 Schedule 只是入口之一,Schedule 本质上是一个标准的 Kubernetes 自定义资源(CRD),其完整 YAML 定义同样可以通过 kubectl apply -f 直接提交,效果与 CLI 等价——理解这一点有助于在 GitOps 场景下将定时备份策略纳入版本化管理。