news 2026/9/24 16:04:18

Salt Runners 实战指南:在 Salt Master 上编写与运行便捷管理程序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Salt Runners 实战指南:在 Salt Master 上编写与运行便捷管理程序

Salt Runners 实战指南:在 Salt Master 上编写与运行便捷管理程序

【免费下载链接】saltSoftware to automate the management and configuration of infrastructure and applications at scale.项目地址: https://gitcode.com/gh_mirrors/sa/salt

Salt Runners(Runner 模块)是 Salt 提供的一类「便捷应用(convenience applications)」,通过salt-run命令在 Salt Master 本机上执行,用于完成作业查询、Minion 状态巡检、密钥管理、文件服务器操作等 Master 侧的运维工作。本文以 doc/ref/runners/index.rst 为主线,结合当前仓库中 salt/runners 的源码实现,系统讲解 Runner 的定位、编写方式、输出与事件机制、同步/异步执行模式以及自定义 Runner 的加载配置,帮助你掌握在 Master 侧扩展 Salt 管理能力的方法。

Runner 是什么:与 Execution Module 的核心区别

Salt 的执行模块(Execution Module)在远程 Minion 上执行,而 Salt Runner 与之工作原理相似,但运行在 Salt Master 本机。一个 Runner 既可以是一次简单的本地客户端调用,也可以是一个复杂的应用(例如跨多个 Minion 聚合数据、操作 Master 缓存或密钥等)。

两者的共同点在于:它们都是包含函数的 Python 模块,模块中的每个公开函数(public function)都对应一个可以通过salt-run调用的 Runner。

维度Execution ModuleRunner
执行位置远程 MinionSalt Master 本机
调用命令saltsalt-callsalt-run
典型用途管理目标主机的软件、服务、文件管理整个 Salt 环境(作业、密钥、节点状态)
源码目录salt/modulessalt/runners

从实现上看,RunnerClient(见 salt/runner.py)是salt-runCLI 在 Master 上执行 Runner 模块的接口,其client = "runner"tag_prefix = "run",事件前缀对应salt/run/...

用 salt-run 调用 Runner

Runner 的调用语法与执行模块一致:模块名.函数名,后面可跟参数与关键字参数。例如test.py模块(对应源码 salt/runners/test.py)中的arg函数:

# salt-run test.arg foo bar=baz

如果有一个名为test.py的模块放在 runners 目录下,并包含函数foo,则调用方式为:

# salt-run test.foo

关键字参数采用key=value的写法,例如查询作业列表、查看 Minion 状态:

salt-run jobs.list_jobs salt-run manage.status salt-run manage.up

说明:本文命令中的#表示以 Master 用户执行的提示符,并非命令的一部分。

编写你的第一个 Runner

Runner 的编写方式与执行模块非常相似:它是一个 Python 模块,每个公开函数就是一个可被salt-run调用的 Runner。函数的 docstring 中通过CLI Example:代码块给出调用示例,这与 Salt 中所有模块的约定一致,docstring 会被自动提取到文档中(参见 doc/ref/runners/all 下每个模块的独立文档页)。

来看一个源自 salt/runners/manage.py 的简化示例——返回当前在线 Minion 列表:

# Import salt modules import salt.client def up(): """ Print a list of all of the minions that are up """ client = salt.client.LocalClient(__opts__["conf_file"]) minions = client.cmd("*", "test.version", timeout=1) for minion in sorted(minions): print(minion)

保存后执行:

salt-run up

几个关键点:

  • __opts__是 Salt 注入到 Runner 模块中的 Master 配置字典,可以直接读取conf_filetimeout等配置项;
  • 通过salt.client.LocalClient可以在 Master 侧向 Minion 发起同步命令,这是 Runner 与 Execution Module 最本质的能力差异——Runner 能够"调度"整个集群;
  • 实际仓库中manage.up的完整实现(salt/runners/manage.py)还考虑了超时未返回的 Minion、no_return合成超时行的过滤等问题,说明 Runner 可以做得相当复杂。

输出控制:print 语句与事件总线

Runner 在输出控制上有多种方式,其中最关键的一条:Runner 中的任何print语句都会自动被作为事件(event)发送到 Master 事件总线上

例如:

def a_runner(outputter=None, display_progress=False): print("Hello world") ...

执行后会触发如下事件:

Event fired at Tue Jan 13 15:26:45 2015 ************************* Tag: salt/run/20150113152644070246/print Data: {'_stamp': '2015-01-13T15:26:45.078707', 'data': 'hello', 'outputter': 'pprint'}

事件特征说明:

  • 事件 Tag 形如salt/run/<jid>/printjid是本次 Runner 运行的作业 ID;
  • Data 中的data字段携带打印内容,outputter字段可指定输出格式化器(如上例的pprint);
  • 这意味着即使salt-run不在交互式终端中运行,Runner 的输出也可以通过监听事件总线被其他系统捕获。

进度事件(Progress Event)

Runner 还可以发送进度事件(progress event),它会在 Runner 执行期间展示给用户,并且在 Runner 的display_progress参数被设置为 True 时,同样会通过事件总线传递。

自定义 Runner 可以通过__jid_event__.fire_event()方法发送自己的进度事件:

if display_progress: __jid_event__.fire_event({"message": "A progress message"}, "progress")

上述代码会在控制台输出A progress message,并在事件总线上产生类似如下的事件:

Event fired at Tue Jan 13 15:21:20 2015 ************************* Tag: salt/run/20150113152118341421/progress Data: {'_stamp': '2015-01-13T15:21:20.390053', 'message': "A progress message"}
  • __jid_event__是 Salt 注入到 Runner 中的事件对象,其fire_event(data, tag)方法接收两个参数:事件数据字典与事件 Tag;
  • 将第二个参数(progress)替换为任意自定义 Tag,即可把事件发送到事件总线。不过要注意:使用自定义 Tag 的事件不会显示在命令行上,只会被发送到事件总线
  • --progress标志(见下文异步模式)用于在salt-runCLI 上展示这些进度事件。

同步与异步执行模式

Runner 支持同步与异步两种执行模式。

同步模式(默认):控制权不会返回,直到 Runner 执行完毕。这是salt-run命令行默认的行为。

异步模式:Runner 可以异步触发,调用后立即返回控制权。此时:

  • 若通过salt-run命令行使用,不会向用户显示任何输出;
  • 若以编程方式(programmatically)调用,不会返回任何结果;
  • 如果需要结果,必须通过 Runner 在事件总线上触发事件并监听这些事件,或其他方式来收集。

注意:以异步模式运行 Runner 时,--progress标志不会把输出传递给 salt-run CLI,但进度事件仍然会发送到事件总线上。

在源码层面,salt/runner.py 中RunnerClient同时混入了SyncClientMixinAsyncClientMixin,分别提供cmd_sync()cmd_async()方法;其中cmd_async()需要 Master 配置external_auth且用户被授权执行 Runner(@runner)。而_reformat_low()(salt/runner.py)负责把多种 low-data 格式统一为内部结构,说明 Runner 既可以从 CLI 触发,也可以从 Python API、eauth 认证的客户端等多种途径调用。

添加自定义 Runner:runner_dirs 配置

要添加自定义 Runner,只需把它们放到一个目录中,并在Master 配置文件中通过runner_dirs指定该目录:

# /etc/salt/master runner_dirs: - /srv/salt/runners
  • 配置项位于 Master 配置文件的 "Master Module Management" 段,当前仓库默认配置见 conf/master:#runner_dirs: [],即默认不加载额外的自定义目录;
  • runner_dirs接受一个目录列表,可以同时指定多个路径;
  • 配置后需要重启salt-master服务使配置生效。

从源码看,salt/loader/init.py 中runner()加载函数通过_module_dirs(opts, "runners", "runner", ext_type_dirs="runner_dirs")将内置的 salt/runners 目录与runner_dirs指定的自定义目录一并交给LazyLoader加载,并以tag="runners"标记、将__utils____context__注入模块、以__salt__作为模块自我引用名。这解释了自定义 Runner 之所以能与内置 Runner 使用完全一致的__opts____jid_event__等注入对象的原因。

仓库中的内置 Runner 一览

Salt 发行版自带的 Runner 位于 salt/runners 目录,共有 30 个模块,包括但不限于:

  • manage(salt/runners/manage.py):节点管理,如manage.status(列出 up/down 的 Minion)、manage.upmanage.down、密钥重新生成manage.key_regen等;
  • jobs(salt/runners/jobs.py):作业缓存查询,如jobs.list_jobsjobs.lookup_jidjobs.active等;
  • state:在 Master 侧触发 State 编排(orchestrate),是salt-run state.orchestrate的实现;
  • cache:Minion 数据缓存管理;
  • mine:管理 Mine(Minion 数据共享);
  • pillar:Pillar 数据管理与外部 Pillar 刷新;
  • fileserver:文件服务器操作与文件列表更新;
  • event:事件总线操作,如event.send手动向事件总线发送事件;
  • http:在 Master 上发起 HTTP 请求;
  • pki:Master/Minion 密钥管理;
  • queue:Master 队列管理;
  • reactor:Reactor 系统管理;
  • ssh:Salt SSH 的 Roster 与部署相关操作;
  • winrepo:Windows 软件仓库管理;
  • test(salt/runners/test.py):仅用于测试目的,如test.arg(原样输出参数)、test.metasyntactic等,无生产用途。

每个模块的完整函数文档可以在 doc/ref/runners/all 目录下按salt.runners.<module>.rst查看,例如manage模块的文档为 salt.runners.manage.rst。

manage.status为例(salt/runners/manage.py),它通过salt.client.get_local_client()client.run_job()向目标 Minion 发布test.ping作业,再以get_cli_event_returns()收集返回结果,最终输出{"up": [...], "down": [...]}字典;命令行支持:

salt-run manage.status salt-run manage.status tgt="webservers" tgt_type="nodegroup" salt-run manage.status timeout=5 gather_job_timeout=10

其中tgt为目标、tgt_type为匹配器类型(globnodegroupcompound等),timeoutgather_job_timeout控制等待返回的时长,未显式指定时取自 Master 的timeoutgather_job_timeout配置。_ping()内部还处理了"合成超时行"(out == "no_return")的过滤逻辑,避免把未返回的 Minion 误判为在线(对应 changelog 中 issue #69582 的修复),这是一个值得自定义 Runner 借鉴的健壮性处理模式。

小结

Runner 是 Salt 在 Master 侧提供的一组可编程管理接口:它以 Python 函数为最小单元,通过salt-run调用,天然接入 Master 事件总线与作业系统,既能完成简单的集群巡检,也能承载managejobsstate.orchestrate这类复杂应用。编写自定义 Runner 时,只需要把模块放入runner_dirs指定的目录、公开函数、利用print__jid_event__.fire_event()输出结果即可,同时要理解同步/异步两种模式在结果获取方式上的差异。如需深入了解,可继续阅读 doc/ref/runners/all 下的模块文档,以及 salt/runner.py 中RunnerClient的完整实现。

【免费下载链接】saltSoftware to automate the management and configuration of infrastructure and applications at scale.项目地址: https://gitcode.com/gh_mirrors/sa/salt

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 16:01:57

Salt TOML 渲染器(salt.renderers.tomlmod)使用与实现原理详解

Salt TOML 渲染器&#xff08;salt.renderers.tomlmod&#xff09;使用与实现原理详解 【免费下载链接】salt Software to automate the management and configuration of infrastructure and applications at scale. 项目地址: https://gitcode.com/gh_mirrors/sa/salt …

作者头像 李华
网站建设 2026/9/24 15:59:50

DRF 3.x Throttling 节流使用示例和配置方法

在现代Web应用中,限制API请求的速率是一项重要的技术,尤其是在分布式系统和大规模用户使用的场景下。这不仅有助于保护服务器资源,防止过载,还能够提升API的安全性,防止恶意攻击。Django REST Framework(简称DRF)提供了丰富的节流(Throttling)机制,通过合理的配置和使…

作者头像 李华
网站建设 2026/9/24 15:59:50

Linux基础——环境

前言 使用 VMware 安装 Ubuntu 22.04.5 虚拟机&#xff08;图文教程&#xff09; 本文将带你一步步完成在 VMware 中创建并运行 Ubuntu 22.04.5 虚拟机的全过程&#xff0c;适合初学者参考。 一、下载软件 VMware&#xff08;VMware by Broadcom - Cloud Computing for the E…

作者头像 李华