Salt 执行模块 systemd_service 完全指南:基于 systemd 的服务管理实战
运维配置管理后端【免费下载链接】saltSoftware to automate the management and configuration of infrastructure and applications at scale.项目地址https://gitcode.com/gh_mirrors/sa/salt点击查看免费下载本文是 Salt 官方参考文档 doc/ref/modules/all/salt.modules.systemd_service.rst 对应执行模块systemd_service的深度技术指南。该模块实现了 Salt 的虚拟service模块用于在通过 systemd 启动的 Linux 主机上管理服务的启动、停止、重启、开机自启与屏蔽等操作。读者在读完本文后将掌握通过salt * service.*命令与 service 状态模块 管理 systemd 单元的完整姿势并理解其底层与systemctl、systemd-run的交互原理。一、模块定位与加载前提systemd_service模块自 Salt 0.10.0 引入完整实现位于 salt/modules/systemd_service.py。它本身是一个虚拟 service 模块的实现模块内部通过__virtualname__ service源码 L57声明虚拟名称因此在使用时必须通过service这个名字调用而不是systemd# 正确用法 salt * service.start sshd # 错误用法 salt * systemd.start sshd模块的加载条件由__virtual__()决定源码 L60-L73系统内核必须是 Linux__grains__.get(kernel) Linux系统必须使用 systemd 启动salt.utils.systemd.booted()返回真或者 systemd 处于离线模式offline()返回真。booted()的实现与 libsystemd 的sd_booted()等价即检查目录/run/systemd/system是否存在见 salt/utils/systemd.py L40-L52。若条件不满足模块加载失败并返回提示only available on Linux systems which have been booted with systemd。关于模块提供者provider覆盖如果 Salt 未正确选择本模块例如报错service.start is not available可以通过模块提供者覆盖机制在 minion 配置中显式指定将service虚拟模块绑定到systemd实现例如在 conf/minion 中加入providers: service: systemd二、服务枚举get_all / get_enabled / get_disabled / get_static / get_running单元类型与命名规范化模块支持全部合法的 systemd 单元类型定义于VALID_UNIT_TYPES源码 L43-L53service, socket, device, mount, automount, swap, target, path, timer_canonical_unit_name()源码 L86-L95负责名称规范化传入的名称若不带上述任一合法后缀则自动补上.service。因此sshd与sshd.service是等价的。get_all列出所有可用服务salt * service.get_allget_all()源码 L604-L619合并两类来源systemd 单元通过_get_systemd_services()直接扫描三个系统目录源码 L40-L41/lib/systemd/system/usr/lib/systemd/system/etc/systemd/system目录必须可读且不是符号链接单元文件按名称.类型拆分service类型返回去后缀的名称其余类型保留完整单元名如timer1.timer。SysV 兼容脚本扫描/etc/init.d下可执行的脚本_get_sysv_services()源码 L218-L256若同名 systemd 单元已存在则跳过该 init 脚本保证 systemd 单元优先。get_enabled / get_disabled / get_staticsalt * service.get_enabled salt * service.get_disabled salt * service.get_static这三个函数源码 L478-L601都通过systemctl list-unit-files输出解析单元状态列get_enabled状态为enabled的服务代码注释特别说明不能使用--stateenabled参数因为该选项在 systemd 216 之前不存在需手动解析列同时兼容 Arch Linux 额外追加第三列的情况get_disabled状态为disabled的服务get_static状态为static的服务不能手动启用/禁用由依赖自动激活SysV 脚本不存在 static 概念。对于 systemd 单元之外还会把/etc/rc运行级.d/S*中存在启动符号链接的 SysV 脚本并入enabled集合_sysv_enabled()源码 L362-L373。get_running列出运行中的服务salt * service.get_runningget_running()源码 L439-L475执行systemctl --full --no-legend --no-pager解析第 4 列为running的单元并返回排序列表。root 参数面向镜像/容器的脱机管理get_enabled、get_disabled、get_static、get_all以及后文的enable/disable/mask/unmask/show等函数都支持root参数用于在指定根目录下操作单元文件例如在 chroot 环境或构建镜像时底层通过systemctl --root root实现源码 L336-L337salt * service.enable foo root/mnt/rootfs三、服务可用性与运行状态检查available / missingsalt * service.available sshd # 检查服务是否可用含模板单元 salt * service.missing sshd # available 的反向判断available()源码 L622-L636内部通过systemctl status的输出判断单元是否已加载。_check_available()源码 L98-L131针对不同 systemd 版本采用两套策略systemd ≥ 231直接依据systemctl status的退出码判断0 retcode 4视为存在systemd 231 起对不存在的服务返回码变为 4systemd 231解析输出中loaded:行的值是否等于not-found同时兼容 RHEL 7.3 等将新版行为回移植的发行版。status查询服务是否在运行salt * service.status service name [service signature]status()源码 L1109-L1150执行systemctl is-active退出码为 0 即视为运行中。自 2018.3.0 起支持 glob 通配如salt*当名称包含*、?或[...]时先对get_all()的结果做fnmatch过滤再返回{服务名: True/False}的字典否则返回单个布尔值。注意sig参数在本模块中未实现保留仅为与其他平台 service 模块保持 API 一致。enabled / disabled开机自启状态salt * service.enabled service name salt * service.disabled service nameenabled()源码 L1297-L1356依次走三层判断逻辑执行systemctl is-enabled返回码 0 且输出非alias即视为已启用输出为alias时通过systemctl show -P Id解析别名背后的真实单元再复查名称含模板单元时在/etc/systemd/system下用find查找 enable 时创建的符号链接兼容旧版 systemd 无法用is-enabled检查模板单元的限制最后回退到 SysV init 脚本的rc*.d符号链接判断。四、服务生命周期操作start / stop / restart / reload / force_reloadsalt * service.start service name salt * service.stop service name salt * service.restart service name salt * service.reload service name salt * service.force_reload service name这组函数源码 L824-L1104是日常运维中最常用的入口底层分别映射到systemctl start|stop|restart|reload|force-reload。reload与unmask因与 Python 内建关键字冲突在模块顶部通过__func_alias__做了别名映射源码 L35-L38因此 CLI 上直接写service.reload即可。systemd.scope 配置与 systemd-run 隔离从 2015.8.12 / 2016.3.3 / 2016.11.0 起当 minion 运行在 systemd ≥ 205 时这些修改性操作会通过systemd-run --scope隔离执行见 源码 L320-L332 的_systemctl_cmd实现。这样做的目的是避免在重启 salt-minion 服务本身时产生竞争条件——因为如果直接在 minion 的 cgroup 内执行systemctl restart salt-minion命令自身会被信号杀死导致状态不确定。如果不想使用该机制可在 minion 配置conf/minion中关闭systemd.scope: Falseno_block 参数与 salt-minion 死锁防护start/stop/restart/reload/force_reload/enable/disable均支持no_block参数2017.7.0 引入为True时使用systemctl --no-block异步返回。特别值得注意的是stop与restart的默认值源码 L403-L412 的_no_block_default自 3006.15 起当目标服务是 salt-minion 自身时no_block默认自动变为True防止 minion 在退出前等待自身停止而陷入死锁其他服务默认仍为False。unmask / unmask_runtime 参数自 2017.7.0 起Salt 不再默认在 start/restart 前自动 unmask。若服务处于 masked 状态需显式传参salt * service.start foo unmaskTrue # 先移除持久 mask 再启动 salt * service.start foo unmask_runtimeTrue # 先移除运行时 mask 再启动五、开机自启管理enable / disablesalt * service.enable service name salt * service.disable service nameenable()源码 L1155-L1231与disable()源码 L1236-L1292对 systemd 单元直接执行systemctl enable/disable。若目标服务实际是 SysV 脚本则会回退调用update-rc.d或chkconfig_get_service_exec()按update-rc.d、chkconfig的顺序探测可执行文件源码 L259-L278update-rc.denable 执行update-rc.d -f name defaults 99disable 执行update-rc.d -f name removechkconfigenable 执行chkconfig name ondisable 执行chkconfig name off。这两个函数同样支持no_block、unmask、unmask_runtime与root参数语义与生命周期操作一致。六、服务屏蔽mask / unmask / masked屏蔽mask是 systemd 独有的强约束机制被 mask 的服务无法被任何依赖拉起。salt * service.mask foo # 持久屏蔽 salt * service.mask foo runtimeTrue # 仅本次开机周期内屏蔽 salt * service.unmask foo # 解除持久屏蔽 salt * service.unmask foo runtimeTrue # 解除运行时屏蔽 salt * service.masked foo # 查询是否被持久屏蔽 salt * service.masked foo runtimeTrue # 查询是否存在运行时屏蔽mask()源码 L711-L756与unmask_()源码 L656-L708同样走systemd-run --scope隔离路径runtimeTrue时对应systemctl mask --runtime/unmask --runtimemasked()源码 L759-L821的实现并不调用systemctl而是直接检查符号链接/etc/systemd/system/unit持久或/run/systemd/system/unit运行时是否指向/dev/null。这是从 systemd 207 起 mask 的标准实现方式若路径是普通文件而非符号链接会记录一条可能为 Salt bug 的错误日志。2017.7.0 起masked()返回值由systemctl is-enabled的输出改为布尔值并可通过runtime参数精确区分持久 mask 与运行时 mask——因为同一个服务可以同时挂两种 mask。七、单元文件变更检测与 systemctl_reload修改单元文件后必须执行daemon-reloadsystemd 才会重新读取。模块通过_check_for_unit_changes()源码 L134-L141在几乎每个公开函数前自动处理_untracked_custom_unit_found()源码 L376-L383服务当前不可用但在/etc/systemd/system下存在单元文件即新放置的自定义单元_unit_file_changed()源码 L386-L392systemctl status输出中包含systemctl daemon-reload提示systemd 检测到单元文件已变更。任一条件成立即自动执行systemctl daemon-reload免去手动刷新。手动刷新使用systemctl_reload()源码 L415-L436salt * service.systemctl_reload八、单元属性展示与进程映射show展示单元全部属性salt * service.show service nameshow()源码 L1375-L14092014.7.0 引入执行systemctl show并把keyvalue输出解析为字典以{开头的值解析为嵌套字典Before、After、Wants解析为列表其余保持字符串。execs列出所有服务的 ExecStartsalt * service.execsexecs()源码 L1412-L1433遍历get_all()的结果对每个服务调用show()收集ExecStart的path字段返回{服务名: 可执行文件路径}映射。pid_to_service由 PID 反查服务名虽然该函数位于工具层 salt/utils/systemd.py L165-L224但它与模块配合紧密若系统装有dbus优先通过 D-Bus 调用org.freedesktop.systemd1.Manager.GetUnitByPID反查单元名否则回退到systemctl --output json status pid解析_SYSTEMD_UNIT字段。九、离线模式与系统初始化offline判断 systemd 离线模式salt * service.offlineoffline()源码 L1500-L15153004 引入透传salt.utils.systemd.offline()salt/utils/systemd.py L55-L76当系统并非由 systemd 启动无 PID 1 可对话但systemctl二进制存在时视为离线模式。在此模式下_check_available()会直接抛出CommandExecutionError提示无法获取单元信息。firstbootsystemd-firstboot 封装salt * service.firstboot keymapjp localeen_US.UTF-8firstboot()源码 L1436-L14973001 引入封装systemd-firstboot支持一次性配置locale、locale-message、keymap、timezone、hostname、machine_id与root等基本系统设置常用于镜像构建与首次开机初始化场景。十、与 service 状态模块的协同systemd_service执行模块通常不作为最终用户直接调用的对象而是作为 service 状态模块 的底层驱动。状态模块中的service.running、service.dead、service.enabled、service.disabled、service.masked见 salt/states/service.py L387、L648、L813、L841、L860会依次调用本模块对应的执行函数完成收敛并且service.running支持enable参数在确保运行的同时设置开机自启。因此在 SLS 文件中可以这样声明式地管理服务sshd: service.running: - name: sshd - enable: True - reload: True状态模块中unmask、unmask_runtime、no_block等参数同样会透传到本执行模块。十一、测试佐证与可靠性模块的单元测试位于 tests/pytests/unit/modules/test_systemd_service.py覆盖了关键行为test_systemctl_reload验证daemon-reload失败时抛出CommandExecutionError成功时返回Truetest_get_enabled/test_get_disabled基于模拟的list-unit-files输出验证enabled/disabled/static状态解析、service去后缀与timer保留全名以及 SysV 脚本合并逻辑fixturesystemctl_status/systemctl_status_gte_231分别模拟 systemd 231 与 ≥ 231 两种systemctl status行为印证_check_available()的双版本兼容设计。这些测试确认了本文前述的状态解析与版本兼容逻辑均是模块的真实行为而非文档推测。总结systemd_service是 Salt 在 systemd 生态下的服务管理基石通过虚拟名service对外提供统一的跨发行版 API内部则精细处理 systemd 多版本差异231 的状态码变化、216 之前的 list-unit-files、205 引入的 scope 隔离、模板单元与别名单元的特殊判断并完整兼容 SysV init 脚本。理解其函数族与参数语义no_block、unmask、runtime、root、systemd.scope后即可在任意 systemd 主机上通过命令行或状态模块安全、可靠地自动化服务生命周期。赞分享运维配置管理后端【免费下载链接】saltSoftware to automate the management and configuration of infrastructure and applications at scale.项目地址https://gitcode.com/gh_mirrors/sa/salt点击查看免费下载相关推荐Salt macOS 服务管理实战基于 launchctl 的 mac_service 执行模块完全指南Salt macOS 服务管理实战基于 launchctl 的 mac_service 执行模块完全指南 本篇技术指南围绕 Salt 项目中为 macOS 平运维配置管理后端Salt rest_service 执行模块实战基于 rest_sample 代理 minion 的 REST 服务管理Salt rest_service 执行模块实战基于 rest_sample 代理 minion 的 REST 服务管理 Salt 的 rest_servic运维配置管理后端Salt 的 pkgutil 执行模块基于 OpenCSW 管理 Solaris 软件包全指南Salt 的 pkgutil 执行模块基于 OpenCSW 管理 Solaris 软件包全指南 导读 本文深入讲解 Salt 中面向 Solaris 操作系统运维配置管理后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

PyBullet机械臂抓取闭环:从深度学习检测到仿真控制

PyBullet机械臂抓取闭环:从深度学习检测到仿真控制

简介:本资源是一套基于深度学习的平面抓取检测与机械臂控制完整仿真实现方案,面向机器人学、计算机视觉及AI控制方向的学习者与开发者,解决真实场景中抓取位姿估计与仿真闭环控制的关键问题。压缩包共1031个文件,含149个URDF模型&…

2026/9/24 0:36:46 阅读更多 →
RISC-V中断子系统深入解析:CLINT与PLIC的分工协作

RISC-V中断子系统深入解析:CLINT与PLIC的分工协作

自己写嵌入式固件这些年,经手过ARM Cortex-M的NVIC,也调过RISC-V的完整中断链路。说实话,刚接触RISC-V中断子系统的时候,最直观的感受就是“怎么这么绕”,又是CLINT又是PLIC,还要配合一堆CSR寄存器。但真正…

2026/9/25 3:32:18 阅读更多 →
嵌入式MCU开发为何转向LLVM/Clang编译器

嵌入式MCU开发为何转向LLVM/Clang编译器

1. 为什么现在越来越多嵌入式工程师开始用 LLVM/Clang 编译 MCU 程序?你手头那块 STM32F407 的开发板,还在用默认的 arm-none-eabi-gcc 编译?Keil MDK 或 IAR 的授权费又涨了?调试时遇到莫名其妙的优化 bug,翻遍汇编发…

2026/9/25 2:51:06 阅读更多 →

最新新闻

rsuite Calendar 自定义单元格样式:深入解析 cellClassName 的用法与实现原理

rsuite Calendar 自定义单元格样式:深入解析 cellClassName 的用法与实现原理

前端UI组件 【免费下载链接】rsuite 🧱 A suite of React components . 项目地址: https://gitcode.com/gh_mirrors/rs/rsuite 点击查看 免费下载 导读 本文围绕 rsuite 的 Calendar(日历)组件,重点讲解如何通过 ce…

2026/9/25 22:56:19 阅读更多 →
802.11ax调度机制全解析:OFDMA、MU-MIMO与TWT实战调优

802.11ax调度机制全解析:OFDMA、MU-MIMO与TWT实战调优

如果你最近在无线网络圈子里逛,应该会频繁看到“ax调度”这个词。“ax”就是 802.11ax,也就是 Wi-Fi 6 的技术代号,而“调度”才是 802.11ax 真正值钱的地方。很多人以为 Wi-Fi 6 只是“快了一点”,换了张网卡、开了 160MHz 频宽就…

2026/9/25 22:56:19 阅读更多 →
Windows下H.264解码库集成指南:从选型到踩坑

Windows下H.264解码库集成指南:从选型到踩坑

简介:这是一份面向Windows平台的H.264视频解码库资源,由开发者rapidly552整理分享,适合需要在应用程序中快速集成H.264解码能力的C/C工程师及视频技术学习者。该库严格基于AVC标准,实现了运动补偿、帧内预测、多参考帧、熵编码等核…

2026/9/25 22:56:19 阅读更多 →
C#控制台贪吃蛇实战:从数据结构到游戏循环的完整指南

C#控制台贪吃蛇实战:从数据结构到游戏循环的完整指南

简介:面向C#初学者的控制台贪吃蛇实战项目,以经典小游戏为载体,串联类、方法、变量、条件语句等核心语法,并完整覆盖控制台输入输出、按键捕获、主循环、碰撞检测、蛇身增长、随机食物生成、状态更新与字符画面重绘等关键开发环节…

2026/9/25 22:56:19 阅读更多 →
图书管理系统数据库设计与实现:E-R建模到SQLAlchemy落地

图书管理系统数据库设计与实现:E-R建模到SQLAlchemy落地

简介:本资源是一份面向高校数据库课程学习者与Python初学者的完整课程设计实践方案,聚焦图书管理系统的开发全流程,涵盖需求分析、数据库建模、后端逻辑实现与基础部署。压缩包共9个文件,含4个SQL脚本(books、admin、s…

2026/9/25 22:56:19 阅读更多 →
ZoneDeck进程冻结与效率模式指南:挂起进程省CPU降内存,后台视频游戏秒停

ZoneDeck进程冻结与效率模式指南:挂起进程省CPU降内存,后台视频游戏秒停

ZoneDeck进程冻结与效率模式指南:挂起进程省CPU降内存,后台视频游戏秒停 【免费下载链接】ZoneDeck The Ultimate Workspace Manager, Switch between work and life, seamlessly生活工作无缝切换,专业的桌面工作区管理助手 项目地址: http…

2026/9/25 22:54:18 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/25 19:27:14 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/25 11:15:26 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/25 20:29:09 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/25 20:29:43 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/25 20:29:31 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/25 19:27:26 阅读更多 →