news 2026/9/25 13:57:24

Salt 状态管理实战:使用 schedule 状态模块托管 minion 端定时任务

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Salt 状态管理实战:使用 schedule 状态模块托管 minion 端定时任务
  • 运维
  • 配置管理
  • 后端

【免费下载链接】salt

Software to automate the management and configuration of infrastructure and applications at scale.

项目地址:https://gitcode.com/gh_mirrors/sa/salt
点击查看免费下载

导读

本文围绕 Salt 的 schedule 状态模块(salt.states.schedule)展开,讲解如何在状态文件中以声明式方式创建、修改、删除、启用和禁用 minion 端的定时调度任务(Scheduled Jobs)。读完本文后,你将掌握schedule.present、schedule.absent、schedule.enabled、schedule.disabled四个状态函数的完整用法、全部参数语义,并了解它们与底层schedule执行模块、minion 事件系统之间的调用关系,能够直接把定时任务纳入 Salt 的自动化管理体系。

schedule 状态模块是什么

在 Salt 中,minion 内置了一个"调度器(scheduler)",可以让指定函数按固定间隔、特定时间点或 cron 表达式周期性地在 minion 本机执行。这些任务通常定义在 minion 配置或 pillar 中,而 schedule 状态模块 提供了一套状态层的接口,使你能在普通的 SLS 状态文件中管理调度任务,将其与其他状态统一纳入 Salt 的声明式编排体系。

模块提供四个状态函数:

状态函数作用
schedule.present确保某个调度任务存在于 minion 的调度表中(不存在则新增,已存在但配置不一致则修改)
schedule.absent确保某个调度任务从调度表中删除
schedule.enabled确保某个调度任务处于启用状态
schedule.disabled确保某个调度任务处于禁用状态

从实现上看,这四个函数都依赖执行模块 salt/modules/schedule.py 提供的schedule.list、schedule.add、schedule.modify、schedule.delete、schedule.enable_job、schedule.disable_job等底层函数,并通过 minion 的事件总线(manage_schedule事件)完成实际调度表变更。

schedule.present:定义与确保调度任务

schedule.present(name, **kwargs)是核心状态函数,保证名为name的调度任务处于期望状态。其工作流程如下(对应 schedule.py 中的 present 实现):

  1. 调用schedule.list(show_all=True, return_yaml=False, offline=...)获取当前调度表快照;
  2. 若任务尚不存在,则调用schedule.add新增;
  3. 若任务已存在,则先调用schedule.build_schedule_item根据本次参数构建期望项,与当前项逐字段比较:完全一致则返回"Job {name} in correct state"(幂等,无变更);不一致则调用schedule.modify更新;
  4. 在test=True试运行模式下,所有变更仅做预演,不实际生效。

基础示例:按固定间隔执行

job3: schedule.present: - function: test.ping - seconds: 3600 - splay: 10

以上配置将test.ping命令每隔 3600 秒(1 小时)执行一次,并把执行时间在 0~10 秒之间随机抖动(splay)。

splay 区间抖动示例

job2: schedule.present: - function: test.ping - seconds: 15 - splay: start: 10 end: 20

此例中test.ping每 15 秒执行一次,执行时刻在 10~20 秒之间随机偏移。splay既可以是单个秒数值,也可以是含start/end的字典区间(源码中 build_schedule_item 对此做了专门处理,保证区间内的start/end顺序)。

按具体时刻执行(when)

job1: schedule.present: - function: state.sls - job_args: - httpd - job_kwargs: test: True - when: - Monday 5:00pm - Tuesday 3:00pm - Wednesday 5:00pm - Thursday 3:00pm - Friday 5:00pm

该示例在每周一、周三、周五下午 5 点和周二、周四下午 3 点执行state.sls httpd test=True。when使用 dateutil 格式的时间字符串,要求 minion 上安装 python-dateutil;模块在构建任务时会逐个调用dateutil_parser.parse校验时间字符串合法性,解析失败会直接报错(见 build_schedule_item 中的 when 校验)。

使用 cron 表达式

job1: schedule.present: - function: state.sls - job_args: - httpd - job_kwargs: test: True - cron: '*/5 * * * *'

调度任务也可以直接使用标准 crontab 格式。本例表示每 5 分钟运行一次state.sls httpd test=True,要求 minion 上安装 python-croniter。

组合 returner 回传执行结果

job1: schedule.present: - function: state.sls - job_args: - httpd - job_kwargs: test: True - when: - Monday 5:00pm - Tuesday 3:00pm - Wednesday 5:00pm - Thursday 3:00pm - Friday 5:00pm - returner: xmpp - return_config: xmpp_state_run - return_kwargs: recipient: user@domain.com

该示例在同样的时间点执行state.sls httpd test=True,并使用 xmpp returner 将任务执行结果回传,回传时使用xmpp_state_run配置节中的替代配置项,并通过return_kwargs覆盖单个配置(收件人)。

skip_during_range:避开特定时间段

job1: schedule.present: - function: state.sls - job_args: - httpd - job_kwargs: test: True - hours: 1 - skip_during_range: start: 2pm end: 3pm - run_after_skip_range: True

该示例让任务每小时运行一次,但避开下午 2 点至 3 点的时间段;run_after_skip_range: True表示跳过区间结束后立即补跑一次。skip_during_range同样要求 python-dateutil。

present 完整参数详解

schedule.present支持的参数如下(均为**kwargs透传给执行模块),完整声明见 schedule.py 的 present 文档字符串:

参数类型/默认值说明
namestring(必填)调度任务的唯一名称,即调度表中的键名
seconds/minutes/hours/daysint固定时间间隔,任务经过指定时长后执行一次
whenstring 或 list在指定时刻执行,使用 dateutil 格式,需 python-dateutil
cronstring使用 crontab 格式指定执行时刻,需 python-croniter
run_on_startboolminion 启动时是否立即执行;否则首次会跳过,等下一个调度周期
functionstring调度任务要执行的函数名(必填)
job_argslist传给函数的定位参数
job_kwargsdict传给函数的关键字参数
maxrunningint同一任务最多允许同时运行 N 个副本,防止任务重叠
jid_includebool(默认 True)是否将任务纳入 job cache(任务缓存)
splayint 或 dict执行时刻的随机抖动;可为秒数或{start, end}区间
rangedict仅在该时间范围内执行,需 python-dateutil
oncestring在指定日期只执行一次
once_fmtstringonce的日期格式,默认 ISO 8601,可覆盖
enabledbool(默认 True)任务是否启用
return_jobbool任务完成后是否向 master 回传执行信息
metadatadict关联到任务的元数据,不参与执行,可用于与return_job组合检索任务
returnerstring用于回传任务结果的 returner 名称
return_configstringreturner 使用的替代配置节
return_kwargsdict覆盖单个 returner 配置项
persistbool(默认 True)变更是否持久化保存到 minion 配置文件
skip_during_rangedict在指定时间区间内不执行({start, end}),需 python-dateutil
run_after_skip_rangebool跳过区间结束后是否立即补跑
offlineboolminion 未运行时也把任务写入调度(versionadded 3006.3 引入)

几个值得注意的实现细节

  • 时间参数互斥校验:seconds/minutes/hours/days不能与when或cron混用,when与cron也不能同时使用。schedule.add、schedule.modify、schedule.build_schedule_item三处均有此校验,冲突时会直接返回result: False并给出明确报错(见 build_schedule_item 的冲突检查)。
  • job_args/job_kwargs类型校验:job_args必须是 list、job_kwargs必须是 dict,否则构建任务会失败(见 build_schedule_item)。
  • 默认值注入:maxrunning默认 1、enabled默认 True、jid_include默认 True。state 层比较新旧配置时,也会为期望项补上缺失的enabled字段后再比较,避免误判(见 present 的实现)。
  • offline模式:当 minion 进程未运行时,schedule.add/schedule.modify不再通过事件总线触发,而是直接把合并后的调度表写入_schedule.conf文件(由_get_schedule_config_file生成,位于 minion 配置目录下,见 list_ 与 add 的 offline 分支 与 add 的 offline 写文件逻辑)。

schedule.absent:移除调度任务

schedule.absent(name, **kwargs)用于确保某任务不在调度表中:

cleanup-job: schedule.absent: - name: job1
  • 若任务存在,调用schedule.delete删除,返回Removed job {name} from schedule,changes中记录移除结果;
  • 若任务本就不存在,返回Job {name} not present in schedule,视为成功(幂等);
  • test=True模式下仅预演删除;
  • persist参数(默认 True)决定删除操作是否持久化——为 False 时任务只从运行中的调度表移除,minion 重启后仍会从保存的配置中恢复;
  • 同样支持offline=True,在 minion 未运行时直接改写_schedule.conf(见 absent 实现)。

schedule.enabled 与 schedule.disabled:启停任务

这两个状态函数分别调用schedule.enable_job和schedule.disable_job,用于在不删除任务的前提下启停任务,适合临时维护场景:

pause-backup: schedule.disabled: - name: nightly-backup resume-backup: schedule.enabled: - name: nightly-backup
  • 任务存在时正常启停并返回对应 comment;任务不存在则返回Job {name} not present in schedule;
  • test=True时仅预演;
  • persist决定变更是否保存(见 enabled 实现 与 disabled 实现)。

与执行模块及事件系统的联动原理

状态函数本身不做调度,而是把参数透传给 salt/modules/schedule.py 的执行函数。在线模式下,执行函数通过event.fire(data, "manage_schedule")向 minion 事件总线发送manage_schedule事件,minion 调度器进程收到后执行真实变更,再通过minion_schedule_add_complete、minion_schedule_modify_complete、minion_schedule_enabled_job_complete等标签回发完成事件,执行函数等待事件返回后确认结果(例如 enable_job 的事件往返)。

在test=True试运行模式下,状态层会把test参数注入kwargs透传下去,使执行模块返回"would be added / would be modified / would be deleted"等预演信息而不做真实变更。

测试验证

仓库中针对本状态模块的单元测试位于 tests/pytests/unit/states/test_schedule.py,覆盖了以下关键行为:

  • 新增任务:调度表为空时调用schedule.add,返回Adding new job job1 to schedule;
  • 无变化幂等:任务已存在且期望配置一致时返回Job job1 in correct state;
  • 修改任务:任务已存在但when等字段变化时调用schedule.modify,changes中给出 old/new 完整对比;
  • test 模式:test=True时只预演,comment 变为would be added / would be modified / would be deleted;
  • 删除任务:存在时调用schedule.delete,不存在时返回Job job1 not present in schedule;
  • offline 模式:offline=True时直接写入_schedule.conf,且不触发事件总线调用(测试中断言event.call_count == 0)。

这些测试同时佐证了状态层对test、offline、persist等分支的处理逻辑与上述说明一致。

使用建议

  • 将调度任务定义放进状态文件后,可通过salt 'minion*' state.apply schedule批量下发,任务会同时持久化到 minion 配置目录下的_schedule.conf;
  • 需要快速查看 minion 当前调度表时,可结合执行模块命令salt '*' schedule.list show_all=True对比状态管理结果;
  • 涉及when、range、skip_during_range时务必确认 minion 已安装 python-dateutil,涉及cron时确认已安装 python-croniter,否则任务构建会直接报错;
  • 需要"立刻执行一次"某调度任务时,可使用执行模块的salt '*' schedule.run_job job1(force=True可强制执行被禁用的任务,见 run_job 实现)。

综上,salt.states.schedule把 minion 端定时任务的"增删改查启停"全部收敛为声明式状态,配合事件系统与配置文件持久化机制,让定时任务的管理和审计与 Salt 的其他基础设施管理保持同一套自动化流程。

  • 运维
  • 配置管理
  • 后端

【免费下载链接】salt

Software to automate the management and configuration of infrastructure and applications at scale.

项目地址:https://gitcode.com/gh_mirrors/sa/salt
点击查看免费下载
上一篇:WarcraftHelper:魔兽争霸3终极兼容性增强插件完整使用指南
下一篇:Sunshine完全指南:5步打造你的终极家庭游戏串流中心

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 13:52:06

果味黄酒可以兑什么?苏打水、果汁、茶饮搭配指南

果味黄酒冰镇纯饮已经顺口,但很多人更喜欢兑着喝,让口感更清爽或更丰富。这篇围绕苏打水、果汁、茶饮三类常见搭配,给出具体比例和口味说明,再补充几个容易踩坑的细节。下文以缤果日纪果味黄酒为例:7%vol 半甜型&#…

作者头像 李华
网站建设 2026/9/25 13:48:14

Oracle Cursor 配 TaoToken:显式游标与 settings.json 骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/25 13:39:09

广工数据库课设车站售票管理系统:表结构设计与并发扣票实战

简介:这份资源是广东工业大学数据库系统课程设计的个人选题方案——车站售票管理系统,面向正在准备数据库课设的本科生及需要Java数据库综合练习的开发者。系统围绕售票与退票核心业务展开,涵盖车次查询、时刻表查询、售票情况统计等常用功能…

作者头像 李华