如何基于Saltstack Minion本地文件生成动态Pillar数据
问题原因
Pillar的模板渲染默认在Salt Master端执行,你写在模板内的salt['cmd.run']调用会直接在Master节点运行,自然无法读取Minion本地的文件内容。
可行实现方案
按实现成本从低到高排序如下:
方案1:使用自定义Grain存储版本信息(最推荐,适配绝大多数场景)
Grain本身就是Minion本地采集的节点属性,采集逻辑完全在Minion侧执行,刚好匹配你的需求。
- 在Master的
/srv/salt/_grains/目录下新建app_version.py,写入采集逻辑:
def app_version(): import os grain_data = {} target_file = "/绝对路径/to/你的/myfile" if os.path.exists(target_file): with open(target_file, 'r') as f: for line in f: if 'version' in line: # 按你实际的文件格式解析版本号即可 grain_data['app_version'] = line.strip().split('=')[-1].strip() break return grain_data
- 同步自定义Grain到所有Minion:
salt '*' saltutil.sync_grains - 后续可以直接在Pillar、State中直接引用该值,不需要额外配置:
version: {{ grains.get('app_version', 'unknown') }}
补充:应用升级后可以在升级流程的末尾加一行salt <目标节点> grains.refresh自动刷新版本信息
方案2:通过Salt Mine上报版本后写入Pillar
如果你要求版本信息必须存储在Pillar中而非Grain,可以用Mine功能实现Minion主动上报本地数据到Master:
- 先给Minion配置Mine采集任务,可写在Minion配置文件或者公共Pillar中:
mine_functions: get_app_version: - function: cmd.run - arg: - "cat /绝对路径/to/你的/myfile | grep version | awk '{print $2}'" # 上报间隔,单位分钟,按你的版本更新频率调整 mine_interval: 30
- 在Master的Pillar模板中拉取对应Minion上报的版本:
version: {{ salt['mine.get'](minion_id, 'get_app_version').get(minion_id, 'unknown') }}
方案3:使用ext_pillar动态拉取(仅适合小集群复杂场景)
如果你的版本采集逻辑非常复杂,可以用外部Pillar的cmd执行器,在Master生成Pillar时实时调用Minion接口拉取数据:
- 修改Master配置文件
/etc/salt/master,开启ext_pillar的cmd支持:
ext_pillar: - cmd: name: /usr/local/bin/pull_minion_version.sh {{minion_id}} as_json: true
- 编写对应拉取脚本
/usr/local/bin/pull_minion_version.sh,记得给执行权限:
#!/bin/bash MINION_ID=$1 VERSION=$(salt $MINION_ID cmd.run "cat /绝对路径/to/你的/myfile | grep version | awk '{print $2}'" --out=json | jq -r ".\"$MINION_ID\"") echo "{\"version\": \"$VERSION\"}"
注意:该方案每次生成Pillar都会触发Master到Minion的远程调用,集群规模大的话性能开销很高,谨慎使用
内容的提问来源于stack exchange,提问作者Bilbo Bongo
相关产品推荐
相关产品推荐

