grains.item 仅查单个键(如 grains.item cpu_model),grains.items 才显示全部键值对;常见硬件键有 cpu_model、num_cpus、mem_total 等;/etc/salt/grains 必须严格 YAML 格式,修改后需重启 salt-minion;-G 匹配严格类型一致,disks 等列表需用复合匹配;grains.setval 不持久且需 root 权限,批量设置应通过 file.managed 推送配置并重启服务。

grains.item 和 grains.items 区分清楚再查
直接用 grains.item 只能查单个键,比如 grains.item cpu_model;想看全部可用键值对得用 grains.items。很多人误以为 grains.item 能列出所有项,结果返回空或报错 ValueError: No such key,其实是命令用错了。
常见硬件相关键名有:cpu_model、num_cpus、mem_total(单位 MB)、disks、ssds、virtual、kernelrelease、osfullname。注意 disks 返回的是设备名列表(如 ['sda', 'nvme0n1']),不是容量,要容量得结合 disk.usage 模块。
/etc/salt/grains 文件写法必须 YAML 格式
手动加自定义硬件标识(比如标记某台机器是否带 GPU)时,不能写成 gpu: true 就完事——YAML 对缩进和冒号后空格敏感。错误示例:gpu:true 或顶格写 - gpu: yes 都会导致 minion 启动失败,日志里出现 yaml.scanner.ScannerError。
正确写法是:
gpu: true rack_id: "r07b" disk_type: nvme
改完必须重启 salt-minion 服务,否则新字段不会出现在 grains.items 输出里。别指望热加载——grains 是启动时一次性加载的静态快照。
用 -G 进行硬件条件匹配时注意键存在性
salt -G "num_cpus:8" state.apply webserver 看似合理,但如果某台 minion 的 num_cpus 是字符串 "8"(旧版系统常见),而另一台是整数 8(新版),匹配会失败。Salt 的 -G 匹配是严格类型一致的。
更稳妥的做法是用通配符或正则:
AI 舌诊面诊问诊医疗系统 + 诊疗商城系统源码是一套结合 AI 辅助诊断与商品转化的健康类程序,基于浩创云、ThinkPHP(PHP)开发,支持微信服务号与 H5 端,适合做中医舌诊面诊问答、健康建议推送以及配套诊疗商品的运营。
salt -G "num_cpus:*8*" state.apply webserver- 或者先统一转成字符串:在 pillar 或 state 中用
{{ grains['num_cpus']|string }}
另外,disks 是列表,不能直接 -G "disks:nvme0n1",得用 salt -C "G@disks:*nvme0n1*"(复合匹配)或写自定义 grain 函数判断。
grains.setval 在运行时修改不持久,且有权限限制
虽然可以用 grains.setval gpu True 临时设值,但这个只在当前 minion 进程生命周期内有效,重启就丢。它也不写入 /etc/salt/grains,所以不能替代配置文件方式。
更重要的是:该操作需要 minion 本机 root 权限,且 master 端无法通过 salt '*' grains.setval 批量下发——grains.setval 是本地执行函数,master 调用时实际是在 minion 上运行,但多数生产环境禁用了远程执行这类敏感函数(disable_grains_functions 默认为 True)。
真正要批量设置硬件标识,还是走集中化配置管理:用 salt 的 file.managed 把 /etc/salt/grains 模板推送到各 minion,再触发 systemctl restart salt-minion。
硬件属性本身不变频次低,但一旦变更(比如换 CPU、加内存),最容易被忽略的其实是验证环节——别只信 grains.get num_cpus,顺手跑个 cmd.run "lscpu | grep '^CPU(s)'" 对比下更踏实。










