使用 Ansible 批量部署 systemd 服务配置文件,核心是通过 ansible.builtin.template 模块将.service 文件分发到目标主机的/etc/systemd/system/目录,随后调用 ansible.builtin.systemd 模块执行 daemon-reload 并启用服务。此方案适用于需要统一管理服务启停状态和配置参数的多台 Linux 服务器场景,操作前需确认目标主机已安装 systemd 且 Ansible 控制端具备 sudo 权限。
先说结论:Ansible 适合通过模板化配置文件配合 systemd 模块实现批量服务部署,重点在于确保配置文件变更后触发守护进程重载。
- 适合:多台 Linux 服务器统一管理服务单元文件和启停状态
- 先准备:编写支持变量替换的.service 模板文件和 Ansible Playbook
- 验收:在目标主机执行 systemctl status 确认服务活跃且开机自启
命令速用版
---
- name: Deploy systemd service
hosts: all
become: true
tasks:
- name: Copy service file
ansible.builtin.template:
src: templates/myapp.service.j2
dest: /etc/systemd/system/myapp.service
notify: reload systemd
- name: Enable and start service
ansible.builtin.systemd:
name: myapp
enabled: true
state: started
daemon_reload: true
handlers:
- name: reload systemd
ansible.builtin.systemd:
daemon_reload: true
为什么会这样
systemd 守护进程在启动时加载单元文件缓存,直接修改/etc/systemd/system/下的配置文件不会立即生效。
Ansible 的 ansible.builtin.systemd 模块提供了 daemon_reload 参数,能在配置变更时自动通知 systemd 重新加载单元文件,避免手动执行 systemctl daemon-reload 命令,确保批量操作的一致性。
分步处理
步骤 1:编写 Service 模板文件
在 Ansible 项目的 templates 目录下创建.myapp.service.j2 文件,使用 Jinja2 语法定义可变参数,如端口或路径。
[Unit]
Description=My Application
After=network.target
[Service]
ExecStart=/usr/bin/myapp `--port`={{ app_port }}
Restart=always
[Install]
WantedBy=multi-user.target
步骤 2:编写 Playbook 任务
使用 ansible.builtin.template 模块分发文件,权限通常设为 0644。配置变更后必须触发 daemon_reload。
步骤 3:执行部署
在控制端运行 ansible-playbook 命令,确保使用具备 sudo 权限的用户。
ansible-playbook -i inventory.ini deploy_service.yml
怎么验证是否生效
登录任意一台目标主机,检查服务运行状态和开机自启标记。
systemctl status myapp
systemctl is-enabled myapp
输出中 Active 状态应为 active (running),is-enabled 应返回 enabled。
常见坑
- 忘记重载守护进程:修改.service 文件后未执行 daemon_reload,systemd 仍使用旧配置。
- 文件权限错误:service 文件权限过于开放可能导致 systemd 拒绝加载,建议设为 0644。
- 服务命名冲突:确保部署的服务名称不与系统现有服务重名,避免覆盖系统关键组件。
常见问题
部署 systemd 服务需要 root 权限吗
需要。修改/etc/systemd/system/目录和管理系统服务通常需要 sudo 权限,Playbook 中需设置 become: true。
如何更新已部署的服务配置
直接修改模板文件并重新运行 Playbook,Ansible 会检测文件变化并触发 handler 执行 daemon_reload 重启服务。
daemon_reload 参数放在哪里
可放在 ansible.builtin.systemd 任务参数中,也可放在 handler 中由文件变更事件通知触发,后者性能更优。
参考来源
- Ansible 官方文档 - ansible.builtin.systemd 模块 https://docs.ansible.com/ansible/latest/collections/ansible/builtin/systemd_module.html
- Ansible 官方文档 - ansible.builtin.template 模块 https://docs.ansible.com/ansible/latest/collections/ansible/builtin/template_module.html
- systemd 官方文档 - systemd.unit https://www.freedesktop.org/software/systemd/man/systemd.unit.html