You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

执行salt "*" state.apply时跨节点共享命令输出遇问题求方案

解决SaltStack中mine.get首次执行无数据的问题

问题场景

执行salt "*" state.apply时,想要把master节点的命令输出共享到worker节点,采用mine.send+mine.get方案,配置如下:

配置文件

top.sls:

base:
  'master*':
    - states.master*

  'worker*':
    - states.worker*

states/master.sls:

save:
  module.run:
    - mine.send:
      - foo
      - mine_function: cmd.shell
      - name: whoami

states/worker.sls:

load:
  file.managed:
    - name: /tmp/a.sh
    - contents: {{ salt['mine.get']("*", "foo").values() | first }}

首次执行错误

首次运行时worker节点直接报错:

worker-0:
    Data failed to compile:
----------
    Rendering SLS 'base:states.worker' failed: Jinja variable No first item, sequence was empty.; line 7

---
[...]
load:
  file.managed:
    - name: /tmp/a.sh
    - contents: {{ salt['mine.get']("*", "foo").values() | first }}
---

第二次运行一切正常,核心原因是:Jinja渲染worker的SLS模板时,master节点的mine.send还没执行完成,mine数据未同步到master,导致mine.get返回空序列,触发渲染失败。

解决建议

方法1:给worker的state加等待逻辑,确保mine数据就绪

修改states/worker.sls,用wait_for模块等待master的mine数据可用,再执行文件生成:

wait_for_mine_data:
  module.run:
    - name: wait_for.wait_for
    - condition: mine.get("master*", "foo")
    - timeout: 30
    - interval: 2

load:
  file.managed:
    - name: /tmp/a.sh
    - contents: {{ salt['mine.get']("master*", "foo").values() | first }}
    - require:
      - module: wait_for_mine_data

这里设置等待30秒,每2秒检查一次master节点的foo mine数据,worker的文件生成操作依赖等待完成,确保渲染时已有数据。

方法2:分批次执行state,先同步mine再部署worker

先单独执行master节点的state,确保mine数据发送完成:

salt "master*" state.apply states.master

再执行所有节点的state:

salt "*" state.apply

也可以用SaltStack的batch模式,先跑master组再跑worker组,从根源避免并行执行的时序冲突。

方法3:给Jinja模板加默认值,避免渲染失败

修改worker的SLS,给first过滤器加默认值,即使首次mine为空也不会报错,后续state运行时自动更新文件:

load:
  file.managed:
    - name: /tmp/a.sh
    - contents: {{ salt['mine.get']("master*", "foo").values() | first | default("", true) }}
    - onchanges:
      - module: save

添加default("", true)保证空序列时渲染不报错,同时用onchanges关联master的save状态,只有当mine数据更新时才重新生成文件,避免无意义的覆盖。

方法4:缩短mine数据的缓存刷新间隔

修改master配置文件/etc/salt/master,调整mine缓存刷新周期:

mine_interval: 5

默认mine数据缓存是60秒,缩短间隔能让master更快同步节点的mine数据,但会增加master负载,根据实际集群规模调整。

内容的提问来源于stack exchange,提问作者yellowhat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 10:18:22