salt state.sls遇到reclass错误
以下都是AI的总结,根据我和AI之间的对话生成的。Gemini 模型。
但是总结的不好,没有正确的复现“我们”的排查过程。
[故障复盘] SaltStack Reclass 从“节点冲突”到“幽灵报错”的排查实录
日期: 2025-12-08 环境: SaltStack + Reclass (ext_pillar) 核心问题: 新增/管理节点时出现 Pillar 渲染失败,报错信息误导性强。
阶段一:初遇“节点冲突” (Collision)
- 故障现象
在执行 Salt 命令时,报错提示 Pillar 渲染失败,原因是由于 Reclass 检测到同一个节点 ID (SVR22753HW1288) 定义了两次(冲突)。
# salt SVR21793HW1288 state.sls npd
...
Failed to load ext_pillar reclass: Definition of node 'SVR22753HW1288' ... collides with definition in ...
- 排查过程 动作: 检查文件系统,寻找重复文件。
find /srv/reclass/nodes -name "SVR22753HW1288.yml"
现象: find 命令无结果,或者只显示一个文件。文件系统层面上并不存在物理冲突。
Salt Master 日志: 出现 ERROR: ‘list’ object has no attribute ‘items’。
分析: 这是一个“幽灵冲突”。很可能是文件已被删除,但 Salt Master 的内存/缓存中仍保留旧的索引,或者是之前的软链接导致的递归扫描。
- 初步处理 结论: 需要强制刷新 Master 状态。如果文件确实删除了,重启服务应能解决冲突报错。
阶段二:报错突变 —— “找不到节点” (Node not found)
- 故障现象
在清理了环境并尝试操作目标节点 SVR21793HW1288 后,冲突报错消失,但出现了新错误:
Failed to load ext_pillar reclass: ext_pillar.reclass: Node ‘SVR21793HW1288’ not found under yaml_fs:///srv/reclass/nodes
- 排查过程
动作: 手工创建该节点文件 SVR21793HW1288.yml。
现象: 报错依旧。
关键测试: 在 Minion 端执行 salt-call –local state.sls npd 成功,但在 Master 端执行 salt 命令 失败。
这表明文件物理存在,且内容逻辑大概率没问题(Minion 能读),但 Master 进程“看不见”它。
深入检查:
检查 Minion ID 与文件名是否匹配:✅ 匹配。
检查权限:✅ 正常。
检查文件内容:
cat -A /srv/reclass/nodes/prod-client/muise/SVR21793HW1288.yml
发现: cat -A 无输出。文件是空的(0字节)!
修正: 填入 YAML 内容。
结果: 依然报错 Node not found!这非常反直觉。
阶段三:真相大白 —— 公共文件语法错误
- 深度诊断
既然文件存在、有内容、有权限,且 Minion 本地能跑通,说明问题出在 Master 端 Reclass 加载器的全局状态。
动作: 绕过 Salt,直接使用 Reclass CLI 工具诊断。
Bash
reclass –inventory 现象: Reclass CLI 抛出了巨长的 Traceback 报错:
Plaintext
yaml.parser.ParserError: while parsing a block mapping in “/srv/reclass/classes/client/ssm.yml”, line 17, column 9 did not find expected key
- 根本原因 (Root Cause)
问题根本不在新节点 SVR21793HW1288 上。
问题出在一个 公共 Class 文件 (/srv/reclass/classes/client/ssm.yml) 存在 YAML 语法错误(缩进/冒号缺失)。
连锁反应:
Salt Master 启动或重新加载 Pillar 时,Reclass 尝试构建全局 Inventory。
读到 client/ssm.yml 时,解析器崩溃 (Crash)。
Reclass 无法完成索引构建。
当查询 任何 节点时,Reclass 返回“未找到”或直接抛出异常,导致 Salt 认为节点不存在。
最终解决方案
修复语法错误: 编辑 /srv/reclass/classes/client/ssm.yml,修正第 17-18 行的缩进错误。
| 验证修复: 再次运行 reclass –inventory | grep SVR21793HW1288,确认能输出节点信息。 |
彻底刷新 Master (SOP): 修复配置后,必须执行以下三步,缺一不可:
# 1. 重启 Master (清除内存中的错误状态)
systemctl restart salt-master
# 2. 清除 Pillar 缓存 (防止读取旧的错误缓存)
salt-run pillar.clear_pillar_cache
# 3. 刷新 Minion 状态
salt SVR21793HW1288 saltutil.refresh_pillar
测试:
salt SVR21793HW1288 state.sls npd
结果: 成功!
经验总结 (SOP)
在 master 运行
reclass --inventory # 检查并修复存在的问题
# 清除 Pillar 缓存 (防止读取旧的错误缓存)
salt-run pillar.clear_pillar_cache
# 刷新 Minion 状态
salt SVR21793HW1288 saltutil.refresh_pillar
# 重启 Master (清除内存中的错误状态)
systemctl restart salt-master
下面是AI给的总结,我觉得总结的不好:
以后遇到类似 Reclass 诡异报错 的标准排查流程:
隔离测试:
先跑 salt-call –local …。如果 Minion 本地成功,但 Master 失败,说明是 Master 端环境/缓存/全局文件的问题。
直接诊断 (关键一步):
不要猜,直接在 Master 运行 reclass –inventory。
如果它报错 ParserError,直接修那个报错的文件(通常是公共 Class)。
检查“低级”错误:
文件是否为空?(ls -l)
是否用了 Tab 键?(cat -A)
文件名有没有空格?
黄金法则:
修改了公共 Class 文件后,必须重启 salt-master。
不要相信 Master 会自动从严重的 Reclass 崩溃中恢复。