两个模块的分工
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能力对照
| 能力 | service | systemd |
|---|---|---|
| 起停与自启 | 支持 | 支持 |
| 重载单元文件 | 不支持 | 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 确认单元状态