首页/系统与基础设施/自动化运维速查/Ansible 服务模块的差异与选择
Ansible 核心70 条

Ansible 服务模块的差异与选择

service 是跨发行版的通用服务管理模块,按主机事实自动选择 systemd、sysvinit 等后端;systemd 模块只服务 systemd 主机,但提供 daemon_reload、masked、scope 等单元级能力,需要动单元文件时用它。

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌​​​​‌​‌‌‌​‌​‌​‌‌‌​‌​​​‌‌​‌‌‌‌​‌‌​‌‌​‌​‌‌​​​​‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌‌‌​‌‌‌​​‌‌​‌‌​​‌​‌​‌‌‌​​‌​​‌‌‌​‌‌​​‌‌​‌​​‌​‌‌​​​‌‌​‌‌​​‌​‌​​‌​‌‌​‌​‌‌‌​‌‌​​‌‌‌​​‌‌​​‌​‌‌​‌​‌‌‌​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​‌‌‌​‌​​​‌‌​​‌​‌​‌‌​‌‌​‌​‌‌​​‌​​​​‌​‌‌​‌​‌‌​‌‌​‌​‌‌​‌‌‌‌​‌‌​​‌​​​‌‌‌​‌​‌​‌‌​‌‌​​​‌‌​​‌​‌​​‌​‌‌​‌​‌‌​​‌​​​‌‌​‌​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌​​‌​‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​

两个模块的分工

service 是通用服务管理抽象:它按目标主机探测出的服务管理器事实,自动调用 systemd、sysvinit、upstart 等后端。systemd 模块只面向以 systemd 为 init 的主机,换来的是单元级别的能力——重载单元文件、屏蔽单元、管理用户级 scope、按单元名而非服务名操作。判断标准很简单:需要动单元文件本身就用 systemd,只需要起停与开机自启用 service。

基本信息

模块名ansible.builtin.service / ansible.builtin.systemd_service
适用平台service 覆盖多 init 体系;systemd 仅 systemd 主机
核心差异daemon_reload、masked、scope 仅 systemd 支持
幂等判定以单元或服务的实际运行状态与自启状态为准

典型使用场景

  • 一套 playbook 同时管 Debian 与 RHEL 主机:用 service 让后端自动适配,避免写死 systemctl
  • 改过 .service 单元文件后要求生效:只有 systemd 模块能触发 daemon_reload
  • 需要屏蔽单元防止被依赖项拉起:用 systemd 的 masked 参数
  • 管理用户级单元(scope: user):service 无法表达
  • 只是起停与设置开机自启:service 写法更短、跨平台更稳

两种写法对照

两种写法对照
- name: 跨发行版起服务  # service 自动匹配 systemd/sysvinit 后端
  ansible.builtin.service:
    name: nginx
    state: started
    enabled: true

- name: 改过单元文件后重载并重启  # daemon_reload 只有 systemd 模块有
  ansible.builtin.systemd_service:
    name: nginx
    daemon_reload: true
    state: restarted

能力对照

能力servicesystemd
起停与自启支持支持
重载单元文件不支持daemon_reload
屏蔽单元不支持masked
用户级单元不支持scope: user
旧 init 系统支持不支持
Ansible 2.15 起 systemd 模块的文档名改为 systemd_service,旧名 systemd 仍可作为别名使用;写新 playbook 用新名,便于通过 ansible-lint 的 fqcn 规则。
state 与 enabled 是两件独立的事:只写 enabled 不会拉起进程,只写 state 不会设置开机自启,部署脚本里通常两个都要写。

选择判据

挑模块前先问三件事:这段 playbook 会不会跑到非 systemd 的机器上、改完要不要触发单元重载、要不要屏蔽或管理用户级单元。只要有一件事是肯定的,就在对应的任务上换成 systemd 模块,其余继续保持 service。反过来,如果只是起停加开机自启,用 systemd 只会把 playbook 绑死在某一种初始化体系上,换一批机器就要重写。

服务名与单元名的差别:service 接收服务名(nginx、sshd、cron),systemd 接收单元名(nginx.service、sshd.service、crond.service 或 cron.service,因发行版而异)。带实例后缀的模板单元(形如 postgresql@14-main)两条路径都能写全名,具体别名与默认实例名以各发行版的 systemd 手册为准。

按条件选模块

按条件选模块
- name: 只有 systemd 机器才用单元级能力  # 避免非 systemd 主机报错
  ansible.builtin.systemd_service:
    name: sshd
    daemon_reload: true
    state: restarted
  when: ansible_service_mgr == 'systemd'

状态判读要点

  • service 返回的 changed 表示这次真的改了状态;状态本来就一致时返回 ok
  • systemd 的 daemon_reload 本身会带来 changed,但不能当成服务被重启的证据
  • 批量任务里想看某台机器是否被改动,用 -v 观察单个任务的 ok/changed 分布
  • 被 masked 的单元在部分版本上表现为“服务不存在”,排查时先用 systemctl status 确认单元状态

易错点

  • 把 enabled 当成顺带启动:服务可能仍处于停止状态,需要同时给 state: started
  • 在非 systemd 主机上调用 systemd 模块会因 systemctl 缺失直接失败,混合环境请回退 service
  • 改了单元文件不 daemon_reload,重启后仍按旧单元配置运行,表现为“配置改了没生效”
  • 用 command 手写 systemctl 起停会丢失幂等与 changed 语义,检查模式也无法预演
  • 对已 masked 的单元直接 start 会失败,需要先 unmask 或改回 service 管理

数据来源与参考

  • Ansible 官方模块文档 ansible.builtin.service
  • Ansible 官方模块文档 ansible.builtin.systemd_service
  • systemd.unit(5) 手册页

整理校对:其其网ICT文档中心 · 本页地址:docs.qiqicto.com/automation/service-vs-systemd-module-differences.html

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌​​​​‌​‌‌‌​‌​‌​‌‌‌​‌​​​‌‌​‌‌‌‌​‌‌​‌‌​‌​‌‌​​​​‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌‌‌​‌‌‌​​‌‌​‌‌​​‌​‌​‌‌‌​​‌​​‌‌‌​‌‌​​‌‌​‌​​‌​‌‌​​​‌‌​‌‌​​‌​‌​​‌​‌‌​‌​‌‌‌​‌‌​​‌‌‌​​‌‌​​‌​‌‌​‌​‌‌‌​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​‌‌‌​‌​​​‌‌​​‌​‌​‌‌​‌‌​‌​‌‌​​‌​​​​‌​‌‌​‌​‌‌​‌‌​‌​‌‌​‌‌‌‌​‌‌​​‌​​​‌‌‌​‌​‌​‌‌​‌‌​​​‌‌​​‌​‌​​‌​‌‌​‌​‌‌​​‌​​​‌‌​‌​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌​​‌​‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​