根本原因是salt master未启用runner监听或orchestrate文件未置于_orch/目录下;文件须放/srv/salt/_orch/且master配置runner_dirs包含该路径,否则salt-run找不到sls。

为什么 salt-run state.orchestrate 不执行你的 orchestrate 文件?
根本原因通常是 Salt Master 没启用 runner 类型的外部事件监听,或者 orchestrate 文件路径没放在 _orch/ 目录下被同步。Salt 的 orchestrate 不是直接跑 SLS,而是靠 runner 服务在 Master 端解析并调度,它默认不自动加载任意位置的 SLS。
-
salt-run命令只在 Master 本地运行,不会把文件推到 Minion,所以state.orchestrate读的是 Master 本地的file_roots(通常是/srv/salt)下的_orch/子目录 - 确保
/srv/salt/_orch/存在且有读权限;SLS 文件必须放在这里,比如/srv/salt/_orch/deploy_app.sls - Master 配置里要确认
runner_dirs包含/srv/salt/_orch,否则salt-run根本找不到这个路径 - 常见错误现象:
State 'orch.my_state' was not found in SLS 'my_state'—— 实际是路径不对,不是语法错
Orchestrate SLS 里调用 state.apply 和 state.sls 有什么区别?
本质区别在于执行上下文和返回控制权的方式。state.sls 是传统状态应用函数,而 state.apply 是它的别名(Salt 3000+ 后统一推荐),但在 orchestrate 中二者行为一致;真正关键的是你是否用了 require 或 onfail 来串起步骤。
- 在
_orch/SLS 中写state.apply时,target 是 Minion ID 或 grain 匹配表达式,比如target: 'web*',不是target: 'G@os:ubuntu'这种复合写法——后者需要加引号且必须用双引号包裹整个字符串 - 如果你依赖前一步的输出(比如部署完配置再重启服务),必须显式用
require引用上一个 ID,不能只靠顺序;Salt 不保证 SLS 内 ID 的执行顺序 - 性能影响:每个
state.apply调用都会触发一次完整的状态编译+传输+执行流程,频繁小调用不如合并成一个 SLS 文件 + 多个 ID
如何让 orchestrate 在失败时中止后续步骤?
默认情况下,salt-run state.orchestrate 遇到某个 step 失败,会继续跑完所有定义的 steps,这跟预期不符。必须手动加 failhard: true 或用 onfail 显式控制流。
- 全局中止:在 orchestrate SLS 最外层加
failhard: true,但注意这是 Salt 3005+ 才支持的特性,老版本无效 - 条件中止:对关键步骤加
onfail,例如重启服务失败时触发回滚动作:rollback_config:→state.apply: - mods: rollback.sls - target: web01 - onfail: - cmd.run: restart_failed - 容易踩的坑:用
cmd.run执行 shell 命令时,如果命令本身返回非零退出码但没加ignore_retcode: false,Salt 默认当成功处理,导致onfail不触发
为什么 salt-run jobs.list_jobs 看不到 orchestrate 任务?
因为 orchestrate 任务由 runner 执行,不走 Salt 的 job cache 机制,默认不会出现在 jobs.list_jobs 输出里。它属于 Master 本地调度行为,不是发往 Minion 的 job。
- 查 orchestrate 执行日志只能看 Master 的
/var/log/salt/master,搜索关键词orchestrate或你的 SLS 文件名 - 如果想追踪进度,可在 orchestrate SLS 里插入
test.echo或cmd.run打点日志,例如:log_start: cmd.run: - name: echo "starting deploy at $(date)" - tgt: master - local: true - 兼容性注意:Salt 3006 开始引入
salt-run jobs.active对 runner 任务的部分支持,但依然不包含 orchestrate,别指望它能列出来
Orchestrate 的“隐式执行模型”是最容易被忽略的一环——它不暴露 job ID、不进 Event bus、不走 returner,调试时得切回 Master 日志和 salt-run 的实时输出,而不是习惯性去查 jobs.list_jobs。