ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Salt 执行模块 systemd_service 完全指南:基于 systemd 的服务管理实战

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),仅供参考
返回列表