使用 salt-api 命令为 Salt Master 启动网络 API 接口
【免费下载链接】saltSoftware to automate the management and configuration of infrastructure and applications at scale.项目地址: https://gitcode.com/gh_mirrors/sa/salt
salt-api 是 Salt 项目中负责为 Salt Master 启动网络 API 连接器的命令行工具,它本身不提供任何 Web 或网络服务,而是加载并托管一系列 netapi 模块(如 REST API),使外部系统可以通过 HTTP 等方式远程调用 Salt 的能力。读完本文,你将掌握 salt-api 的完整命令行用法、守护进程与 pidfile 管理、日志配置方法,以及从入口脚本到 netapi 模块加载的底层启动链路,并能在真实环境中正确启动、配置和运维 salt-api。
什么是 salt-api:Master 网络 API 连接器的管理器
官方命令行手册对 salt-api 的定义非常精炼:
The Salt API system manages network api connectors for the Salt Master
也就是说,salt-api 是一个管理进程,负责为 Salt Master 管理"网络 API 连接器"。它本身不直接提供接口服务,而是把这项工作交给一系列netapi 模块。在当前仓库中,salt/netapi/目录下实际实现的 netapi 模块包括:
salt/netapi/rest_cherrypy/:基于 CherryPy 的 REST API(最常用)salt/netapi/rest_tornado/:基于 Tornado 的 REST APIsalt/netapi/rest_wsgi.py:WSGI 兼容的 REST 接口
从源码结构看(salt/loader/init.py 中的netapi()函数),salt-api 通过 Salt 的 LazyLoader 机制加载salt/netapi/目录下所有可用的 netapi 模块,并启动其中每个以.start结尾的入口函数,从而把外部网络接口(端口、HTTP 服务等)暴露出来。因此,运行 salt-api 之前,Master 配置文件(/etc/salt/master)中必须先配置至少一个 netapi 模块,否则启动时只会得到 "Did not find any netapi configurations, nothing to start" 的报错。
命令语法与调用入口
salt-api 的调用语法非常简单,无需任何必选参数:
salt-api其完整的调用链路可以沿着仓库源码追溯:
- 可执行脚本 scripts/salt-api 是 shell 入口,内容只有几行:引入并调用
salt.scripts.salt_api(); - salt/scripts.py 中的
salt_api()函数是 Python 层主函数,负责固定 multiprocessing fork 行为、通知 systemd,并实例化 CLI 解析器; - salt/cli/api.py 中的
SaltAPI类(继承自parsers.SaltAPIParser)真正承载了参数解析、配置加载、守护进程化与启动逻辑。
其中 CLI 解析器SaltAPIParser定义于 salt/utils/parsers.py,它的description与手册中的定义一字不差,并且有一个关键设定:_config_filename_ = "master"——这意味着salt-api 复用 Salt Master 的配置文件(默认/etc/salt/master),而不是使用独立配置文件。
命令行选项详解
salt-api 的选项由三部分组合而成:通用选项、守护进程选项和日志选项,下面逐一说明。
通用选项
| 选项 | 说明 |
|---|---|
--version | 打印当前运行的 Salt 版本号 |
--versions-report | 显示程序依赖及其版本号后退出 |
-h, --help | 显示帮助信息后退出 |
-c CONFIG_DIR, --config-dir=CONFIG_DIR | 指定 Salt 配置目录(默认/etc/salt),该目录下包含 Master 和 Minion 的配置文件 |
其中-c/--config-dir尤为重要:由于 salt-api 复用 Master 配置,通过该参数可以指向自定义的配置目录(例如多套环境并存时),salt-api 会从该目录读取master配置文件。
守护进程与进程管理选项
salt-api -d # 以后台守护进程方式运行 salt-api --pid-file=/run/salt/salt-api.pid # 自定义 pidfile 路径 salt-api --disable-keepalive # 禁用自动重启包装,交由外部进程管理器(如 systemd)托管-d, --daemon:以后台守护进程方式运行 salt-api。手册原文说明为 "Run the salt-api as a daemon"。在源码层面,该选项由DaemonMixIn(salt/utils/parsers.py)提供,实际执行时调用salt.utils.process.daemonize()完成双 fork 守护进程化,并重新初始化日志系统(见daemonize_if_required(),salt/utils/parsers.py)。--pid-file=PIDFILE:指定 pidfile 的位置。默认值:/var/run/salt-api.pid。源码中该默认值由DaemonMixIn根据进程名拼接生成(os.path.join(syspaths.PIDFILE_DIR, "salt-api.pid")),同时 salt/config/init.py 中的DEFAULT_API_OPTS["api_pidfile"]也指向同一路径。启动时set_pidfile()会向该文件写入进程 PID;退出时(_mixin_before_exit)会尝试删除 pidfile,供服务管理器判断进程是否存活。--disable-keepalive:关闭默认的"自动重启机制"。默认情况下守护进程运行在一个子进程中,具备"退出后自动重启"的能力(由 keepalive 信号驱动);开启此选项后 salt-api 直接在前台运行、不套 keepalive 包装,适合由 systemd 等外部进程管理器负责重启的场景,也适合容器环境(容器运行时负责进程生命周期)。从源码看该选项同样是DaemonMixIn提供的。
日志选项
日志选项用于覆盖配置文件中的日志设置,salt-api 的默认日志文件为/var/log/salt/api,默认日志级别为warning。
| 选项 | 说明 |
|---|---|
-l LOG_LEVEL, --log-level=LOG_LEVEL | 控制台日志级别,可选all、garbage、trace、debug、info、warning、error、quiet,默认warning |
--log-file=LOG_FILE | 日志文件路径,默认/var/log/salt/api |
--log-file-level=LOG_LEVEL_LOGFILE | 日志文件的日志级别,可选值与--log-level相同,默认warning |
在源码层面,SaltAPIParser通过两个属性把日志设置与配置文件挂钩(salt/utils/parsers.py):
_logfile_config_setting_name_ = "api_logfile":日志文件路径取自 Master 配置中的api_logfile项;- 默认日志文件
config.DEFAULT_API_OPTS["api_logfile"],即/var/log/salt/api。
调试排查 API 问题时,常用salt-api -l debug前台运行以观察完整日志。
配置文件:salt-api 如何读取 Master 配置
如前所述,salt-api 没有独立配置文件,而是读取 Master 配置。这条逻辑在 salt/config/init.py 的api_config(path)函数中清晰可见:
- 先拷贝
DEFAULT_API_OPTS(salt-api 专属默认值); - 再用 Master 配置(
client_config(path, defaults=DEFAULT_MASTER_OPTS))覆盖; - 最后把
pidfile和log_file两个内部键指向api_pidfile与api_logfile,并做 root_dir 前缀处理。
DEFAULT_API_OPTS中与 salt-api 直接相关的默认值包括(salt/config/init.py):
| 配置键 | 默认值 | 含义 |
|---|---|---|
api_pidfile | /var/run/salt-api.pid | API 进程 pidfile 路径 |
api_logfile | /var/log/salt/api | API 日志文件路径 |
rest_timeout | 300 | REST 请求超时(秒) |
在 Master 配置文件 conf/master 中,还有两个 NetAPI 相关的全局开关:
# 允许通过 API 调用 Salt SSH client 时使用 raw_shell 参数 #netapi_allow_raw_shell: True # 设置 API 中启用的客户端列表(如 local、runner、wheel 等) #netapi_enable_clients: []netapi 模块自身的配置也写在 Master 配置文件中,以 YAML 字典形式组织,模块名作为顶层键,例如 doc/topics/netapi/writing.rst 给出的 rest_cherrypy 配置:
rest_cherrypy: port: 8000 debug: True ssl_crt: /etc/pki/tls/certs/localhost.crt ssl_key: /etc/pki/tls/certs/localhost.key配置完成后,即可用salt-api启动,使外部客户端通过http://<master-ip>:8000访问 Salt 的 REST API。
启动流程与底层实现:从命令行到 netapi 模块
了解 salt-api 的启动流程有助于排查启动失败问题。SaltAPI类(salt/cli/api.py)的核心生命周期如下:
prepare():- 创建
NetapiClient(self.config)(salt/client/netapi.py),该对象会立即通过salt.loader.netapi(self.opts)加载所有 netapi 模块; - 调用
daemonize_if_required():若指定了-d,在此完成守护进程化; - 调用
set_pidfile():写入 pidfile。
- 创建
start():- 通过
check_user()校验运行用户; - 调用
self.api.run()真正启动服务。
- 通过
shutdown()/_handle_signals():收到 SIGINT/SIGTERM 时,将信号转交给NetapiClient内部的ProcessManager,实现对所有 API 子进程的优雅退出。
NetapiClient.run()(salt/client/netapi.py)是核心启动逻辑:
- 若没有加载到任何 netapi 模块,记录错误日志并直接返回(这正是"未配置任何 netapi 模块时 salt-api 无输出地空跑"的原因);
- 遍历加载到的所有 netapi 函数,对每个以
.start结尾的函数,通过ProcessManager.add_process()以独立子进程方式启动(RunNetapi进程,见 salt/client/netapi.py); - 安装 SIGINT/SIGTERM 信号处理器,最后进入 asyncio 事件循环管理子进程生命周期。
也就是说,每个 netapi 服务(如 rest_cherrypy、rest_tornado)都在独立的子进程中运行,由 salt-api 主进程统一管理;这与 doc/topics/netapi/writing.rst 中 "start() 函数会在多进程(multiprocess)中被启动" 的描述一致。因此,同一时刻可以在 Master 配置中同时启用多个 netapi 模块(甚至同一模块的多个实例,2016.11.0 起支持通过复制目录方式运行多实例),salt-api 会并行托管它们。
运维实践:启动、守护与停止
前台调试模式
salt-api -l debug适合初次配置或排查问题:日志直接输出到控制台,Ctrl-C 即可退出。
后台守护进程模式
salt-api -d以后台方式运行,pidfile 写入/var/run/salt-api.pid,日志默认写入/var/log/salt/api。可通过以下命令确认进程状态:
cat /var/run/salt-api.pid # 查看主进程 PID kill $(cat /var/run/salt-api.pid) # 发送 SIGTERM 优雅停止salt-api 收到 SIGTERM/SIGINT 后会通过ProcessManager依次关闭所有 netapi 子进程,退出时会尝试清理 pidfile。
由 systemd 托管
若使用发行版自带的 salt-api 服务单元(仓库中提供了 pkg/common/salt-api.service),建议在 ExecStart 中配合--disable-keepalive,将进程生命周期完全交给 systemd 管理,避免双重守护造成管理混乱。
停止与信号处理
salt-api 安装的默认信号处理器支持 SIGINT 与 SIGTERM(见NetapiClient.run()中的信号安装逻辑),发送任一信号即可触发优雅关闭流程:先通知所有 netapi 子进程退出,再清理自身 pidfile。
相关手册参考
如需进一步了解,可查阅仓库内与该命令配套的文档与源码:
salt-api命令文档:doc/ref/cli/salt-api.rst,即本文所依据的手册页;- netapi 模块编写指南:doc/topics/netapi/writing.rst,介绍
__virtual__判定、start()入口与多实例支持; - CLI 解析器实现:salt/utils/parsers.py 的
SaltAPIParser与 salt/utils/parsers.py 的DaemonMixIn; - 启动客户端实现:salt/client/netapi.py 的
NetapiClient; - API 默认配置:salt/config/init.py 的
DEFAULT_API_OPTS与 salt/config/init.py 的api_config(); - 系统服务单元:pkg/common/salt-api.service、pkg/common/salt-api.upstart;
- 与
salt-api(7)、salt(7)、salt-master(1)手册页配套,共同构成 Salt 服务端的完整运维手册体系。
【免费下载链接】saltSoftware to automate the management and configuration of infrastructure and applications at scale.项目地址: https://gitcode.com/gh_mirrors/sa/salt
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考