top.sls是salt状态系统的强制调度起点,必须存在且路径、语法正确;缺失或错误会导致state.highstate报“no matching sls found”或静默跳过,因salt仅从此文件解析minion对应的状态目标。

top.sls 文件必须存在且路径正确,否则所有状态执行都会失败——它不是可选入口,而是 Salt 状态系统强制识别的调度起点。
为什么 top.sls 一错全崩
Salt 不会自动扫描所有 .sls 文件,它只从 top.sls 开始解析目标 minion 应该加载哪些状态。如果 top.sls 缺失、语法错误或未匹配到 minion ID,salt '*' state.highstate 会直接报 No matching sls found for 'top' in env 'base' 或静默跳过。
-
top.sls必须放在file_roots指定的 base(或其他)环境根目录下,比如/srv/salt/base/top.sls - 内容必须是合法 YAML,且缩进严格为两个空格;冒号后必须跟空格,
-后也必须跟空格 - 常见写法:
base: '*': - apache - users.admin注意:这里apache对应apache.sls,users.admin对应users/admin.sls或users/admin/init.sls - 如果 minion ID 是
web01.prod,而top.sls中只有base: '*',那它只会加载 base 环境下的状态;想让它走 prod 环境,得显式写prod: 'web01.prod': - web.nginx
pkg.installed 和 service.running 的参数陷阱
这两个是最常用的状态函数,但参数名和行为容易被误用:
-
pkg.installed的name参数不是“包名别名”,而是真实包名(如httpd、nginx),在 CentOS/RHEL 上不能写成apache2;Debian/Ubuntu 则相反 - 若需安装多个包,用
pkgs列表而非多个name:install-tools: pkg.installed: - pkgs: - curl - wget - git -
service.running的enable: True只控制开机自启,不保证当前运行;watch才能联动触发重启,例如配置文件变更后 reload:httpd-config: file.managed: - name: /etc/httpd/conf/httpd.conf - source: salt://files/httpd.conf - watch_in: - service: httpd-service <p>httpd-service: service.running:</p>- name: httpd
- enable: True
多层目录结构下 init.sls 的隐式引用规则
当路径中出现 init.sls,Salt 会自动将其“折叠”进父目录名,这是最易混淆的命名机制。
-
/srv/salt/base/web/apache/init.sls→ 引用时写web.apache,不是web.apache.init -
/srv/salt/base/zabbix/server.sls→ 引用时写zabbix.server - 同一个目录下不能同时存在
zabbix.sls和zabbix/init.sls,否则 Salt 会报Duplicate SLS name - 如果想让
zabbix目录下所有子状态都生效,可在zabbix/init.sls中用include:include: - zabbix.server - zabbix.agent - zabbix.db
注意:include必须是顶级键,且只能出现一次
YAML 缩进和空格错误导致的静默失败
Salt 对 YAML 格式极其敏感,一个空格偏差就会让整个状态块被跳过,且不报错——只显示 Comment: State was not run because no function was matched。
- 所有缩进必须是空格,禁止 Tab;每级严格两个空格(不是 4 个,也不是 1 个)
- 冒号后必须有空格:
pkg.installed:✅,pkg.installed:❌(末尾无空格) - 列表项前的
-后必须有空格:- name: httpd✅,-name: httpd❌ - 注释符号
#前必须有空格,否则会被当成值的一部分 - 调试建议:用
yamllint扫描文件,或先在 minion 上跑salt-call --local state.show_sls apache -l debug查看解析结果
实际部署中,最难排查的往往不是逻辑错误,而是 top.sls 匹配失效或 YAML 空格错位——它们不会抛出明显异常,只会让状态“看起来执行了”,实则什么都没做。











