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 Module | Runner |
|---|---|---|
| 执行位置 | 远程 Minion | Salt Master 本机 |
| 调用命令 | salt、salt-call | salt-run |
| 典型用途 | 管理目标主机的软件、服务、文件 | 管理整个 Salt 环境(作业、密钥、节点状态) |
| 源码目录 | salt/modules | salt/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_file、timeout等配置项;- 通过
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>/print,jid是本次 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同时混入了SyncClientMixin与AsyncClientMixin,分别提供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.up、manage.down、密钥重新生成manage.key_regen等; - jobs(salt/runners/jobs.py):作业缓存查询,如
jobs.list_jobs、jobs.lookup_jid、jobs.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为匹配器类型(glob、nodegroup、compound等),timeout与gather_job_timeout控制等待返回的时长,未显式指定时取自 Master 的timeout与gather_job_timeout配置。_ping()内部还处理了"合成超时行"(out == "no_return")的过滤逻辑,避免把未返回的 Minion 误判为在线(对应 changelog 中 issue #69582 的修复),这是一个值得自定义 Runner 借鉴的健壮性处理模式。
小结
Runner 是 Salt 在 Master 侧提供的一组可编程管理接口:它以 Python 函数为最小单元,通过salt-run调用,天然接入 Master 事件总线与作业系统,既能完成简单的集群巡检,也能承载manage、jobs、state.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),仅供参考