Salt master_tops 外部节点分类器(ext_nodes):从外部系统动态生成 Top 文件数据

发布时间:2026/9/25 5:15:56
Salt master_tops 外部节点分类器(ext_nodes):从外部系统动态生成 Top 文件数据 运维配置管理后端【免费下载链接】saltSoftware to automate the management and configuration of infrastructure and applications at scale.项目地址https://gitcode.com/gh_mirrors/sa/salt点击查看免费下载ext_nodes是 Salt 开源配置管理系统中master_tops子系统的一项经典能力由 salt/tops/ext_nodes.py 实现。它允许 Salt Master 在每次 highstate 运行时调用一个外部 Shell 命令最典型的是 Cobbler 提供的cobbler-ext-nodes来获取目标节点的分类classes与环境信息并自动将其翻译为 Salt Top 文件top.sls能理解的数据结构。读完本文你将掌握master_tops.ext_nodes的配置方法、返回数据格式约定、源码级的执行原理以及如何用自定义命令替代cobbler-ext-nodes实现外部节点分类。背景master_tops 系统是什么Salt 的传统状态管理依赖位于 file server 中的top.sls文件通过匹配规则决定某个 minion 应应用哪些 state。但在 0.10.4 版本中Salt 引入了 master tops 系统在 Master 端通过可插拔的子系统动态生成 Top 文件数据用于 highstate 运行。关于这一演进releases/0.10.4.rst 中有明确记载external_nodes系统被升级为模块化子系统旧的external_nodes配置项仍可工作但将被废弃取而代之的是master_tops配置项。当前仓库中的 doc/ref/configuration/master.rst 同样说明The master_tops option replaces the external_nodes option by creating a pluggable system for the generation of external top data. The external_nodes option is deprecated by the master_tops option.也就是说本文讨论的ext_nodes是master_tops下的一个具体实现模块它是对经典 external nodes 方案的现代化封装。除ext_nodes外master_tops还支持cobbler、mongo、reclass、saltclass、varstack等实现这些模块共同存放在 salt/tops/ 目录下对应 API 文档位于 doc/ref/tops/all/。配置方法一行 YAML 接入外部分类命令ext_nodes的配置非常简单。在 Master 配置文件默认/etc/salt/master仓库中对应 conf/master 的模板中加入master_tops: ext_nodes: cobbler-ext-nodes其中cobbler-ext-nodes是一个 Shell 命令。Salt 会在每次需要生成 Top 数据时执行该命令并把当前 minion 的 id 作为参数追加到命令尾部。例如当名为web01的 minion 发起 highstate 时Master 实际执行的命令等价于cobbler-ext-nodes web01该命令必须向stdout输出一段符合约定的 YAML 数据下文详述格式Salt 将解析这段 YAML 并转换为 Top 文件数据。配置项说明配置项说明master_tops.ext_nodes返回 YAML 的外部 Shell 命令字符串Master 端配置默认值未配置时master_tops默认为{}见 doc/ref/configuration/master.rst需要强调的是Salt 并不会直接消化cobbler-ext-nodes的原始输出而是先把输出转换为 Salt Top 文件top.sls所需的信息结构。因此任何命令都可以替换上面的cobbler-ext-nodes但当前返回数据的格式必须与标准cobbler-ext-nodes保持一致。返回数据格式classes 与环境environment外部命令返回的 YAML 数据约定如下该示例同样出现在模块源码的 docstring 中见 salt/tops/ext_nodes.pyclasses: - basepackages - database上面这段数据本质上等价于一个包含以下内容的 top.slsbase: *: - basepackages - database也就是说ext_nodes命令返回的classes列表会被映射为某个 environment默认base下匹配全部目标*的 state 列表。可选的环境键如果外部命令额外返回了environment键Salt 会将其作为这些 classes 所属的环境名classes: - one - two environment: dev等价于dev: *: - one - two源码中的解析规则从 salt/tops/ext_nodes.py 的实现可以看到解析逻辑非常直接如果返回数据中没有environment键默认环境为base如果classes是列表list直接作为该环境下的 state 列表使用如果classes是字典dict取其键列表list(ndata[classes])作为 state 列表使用如果classes既不是列表也不是字典或者数据中根本没有classes键则返回空结果ret保持为空仅在日志中记录提示信息。当外部命令没有任何输出时模块会记录一条 info 级日志master_tops ext_nodes call did not return any data缺少classes键时记录master_tops ext_nodes call did not have a dictionary with a classes key.。源码级执行原理下面结合 salt/tops/ext_nodes.py 逐段剖析它的运行机制。模块加载条件__virtual__def __virtual__(): if __opts__[master_tops].get(ext_nodes): return True return False只有当 Master 配置中的master_tops.ext_nodes存在且非空时该 tops 模块才会被 loader 加载否则直接返回False跳过加载。这正是 Salt loader 体系中__virtual__的典型用法按配置决定模块是否可用。核心函数top(**kwargs)def top(**kwargs): if id not in kwargs[opts]: return {} proc subprocess.run( [ _cmd_quote(part) for part in shlex.split( __opts__[master_tops][ext_nodes], posixsalt.utils.platform.is_windows() is False, ) [_cmd_quote(kwargs[opts][id])] ], stdoutsubprocess.PIPE, checkTrue, ) ndata salt.utils.yaml.safe_load(proc.stdout) ...执行流程可以拆解为五个步骤参数完整性检查如果调用参数opts中没有id键即缺少目标 minion 的 id直接返回空字典{}不执行外部命令命令构造使用shlex.split把配置的命令字符串按 Shell 语法拆分成参数列表Windows 平台关闭 POSIX 模式Linux 等平台启用再逐段使用_cmd_quote进行 Shell 引用转义最后把当前 minion 的 id 作为最后一个参数追加。_cmd_quote在非 Windows 平台为shlex.quote在 Windows 平台使用salt.utils.win_functions.escape_argument——这保证了包含空格、特殊字符的命令段和 minion id 能被安全地作为单个参数传递执行子进程通过subprocess.run(..., stdoutsubprocess.PIPE, checkTrue)执行命令并捕获 stdout。checkTrue表示命令返回非零退出码时直接抛出异常解析 YAML用salt.utils.yaml.safe_load解析子进程的标准输出得到ndata字典映射转换按上文所述规则把environment和classes转换为{环境名: [state 列表]}的结构返回。跨平台细节模块顶部对 Windows 与非 Windows 做了显式分支if salt.utils.platform.is_windows(): from salt.utils.win_functions import escape_argument as _cmd_quote else: _cmd_quote shlex.quote同时shlex.split的posix参数也根据平台动态设置。这保证了ext_nodes在 Windows Master 与类 Unix Master 上都能正确拼接并执行外部命令。与 Top 文件的合并机制ext_nodes返回的数据并不会取代 top.sls而是与 top.sls 的匹配结果合并。这一合并逻辑位于状态系统的核心文件 salt/state.pyext_matches self._master_tops() for saltenv in ext_matches: top_file_matches matches.get(saltenv, []) if self.opts.get(master_tops_first): first ext_matches[saltenv] second top_file_matches else: first top_file_matches second ext_matches[saltenv] matches[saltenv] first [x for x in second if x not in first]要点默认顺序top.sls 的匹配结果在前ext_nodes的结果在后且去重x not in firstmaster_tops_first如果 Master 配置了master_tops_first: True则ext_nodes的结果排在前面按环境合并ext_matches中的每个环境如base、dev分别与该环境下已有的 top.sls 匹配项合并。此外_master_tops()方法会根据file_client判断masterless本地文件客户端模式下走_local_master_tops()否则通过 master client 的master_tops()获取数据。从 releases/3007.0.md 与 doc/topics/master_tops/index.rst 的说明可知从 3007.0 版本起 masterless minion 也支持 master tops 模块因此ext_nodes在 masterless 场景下同样可以生效。在_local_master_topssalt/state.py中还会对 minion id 做salt.utils.verify.valid_id校验只有通过校验才会加载 tops 模块并合并结果。自定义外部分类命令ext_nodes的设计决定了它不绑定 Cobbler只要你的命令接收一个 minion id 参数并向 stdout 输出约定格式的 YAML就能无缝替换。一个最小可用的自定义命令示例Shell 脚本#!/bin/sh # 接收 minion id 作为 $1根据业务数据返回 YAML case $1 in web*) echo classes: echo - webserver echo - common echo environment: prod ;; db*) echo classes: echo - database echo - common echo environment: prod ;; *) echo classes: echo - common ;; esac随后在 Master 配置中指向该脚本master_tops: ext_nodes: /usr/local/bin/my-ext-nodes也可以直接使用返回 YAML 的现有工具命令。仓库中的单元测试 tests/pytests/unit/tops/test_ext_nodes.py 就用echo作为测试命令ext_nodes: echo以验证模块在无真实外部程序的情况下也能正常工作。数据约定小结命令接收参数目标 minion 的 id作为最后一个参数传入输出要求向 stdout 输出 YAML必须包含classes键列表或字典形式可选包含environment键缺省为base。验证方式单元测试仓库自带的单元测试 tests/pytests/unit/tops/test_ext_nodes.py 覆盖了两个核心场景基础场景test_ext_nodes外部命令输出classes: [one, two]时top()返回{base: [one, two]}并断言subprocess.run以[echo, foo], checkTrue, stdout-1的方式被调用环境场景test_ext_nodes_with_environment输出中带environment: dev时返回{dev: [one, two]}验证 classes 被正确分配到指定环境。运行时验证配置完成后可以用 Salt 自带的命令查看 minion 的 Top 数据是否生效salt minion state.show_top如果一切正常输出中会出现由ext_nodes提供的 state 列表合并逻辑下与 top.sls 内容一同显示。参考资料模块 API 文档doc/ref/tops/all/salt.tops.ext_nodes.rst模块实现源码salt/tops/ext_nodes.py单元测试tests/pytests/unit/tops/test_ext_nodes.pyMaster 配置参考doc/ref/configuration/master.rst 与 conf/masterMaster Tops 系统总览doc/topics/master_tops/index.rst状态合并逻辑salt/state.py功能引入历史doc/topics/releases/0.10.4.rst适用说明以上配置与行为均基于当前仓库源码确认。ext_nodes依赖 Master 端的master_tops配置在 masterless 模式下需 3007.0 及以上版本才支持 tops 模块的本地执行。赞分享运维配置管理后端【免费下载链接】saltSoftware to automate the management and configuration of infrastructure and applications at scale.项目地址https://gitcode.com/gh_mirrors/sa/salt点击查看免费下载相关推荐Salt master_tops 的 reclass 适配器用外部数据源动态生成 Highstate Top 数据Salt master_tops 的 reclass 适配器用外部数据源动态生成 Highstate Top 数据 导读 本文围绕 Salt 内置的 mast运维配置管理后端Salt Master Tops 系统完全指南用外部数据源动态生成 top 数据Salt Master Tops 系统完全指南用外部数据源动态生成 top 数据 Salt 的 Master Tops 是一套可插拔的 master 端子系统运维配置管理后端Salt 的 Saltclass master_tops 模块用分层类继承为节点生成 top 与 PillarSalt 的 Saltclass master_tops 模块用分层类继承为节点生成 top 与 Pillar Salt 通过 master_tops 机制允运维配置管理后端上一篇AutoBlue-MS17-010源码解析exploit函数与SMB协议交互实现下一篇ZLMediaKit H265视频转码失败问题分析与解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询