如何通过ansible-playbook创建新的系统服务
How to create new system service by ansible-playbook
我已经为 start/stop 我的应用程序创建了一个脚本。现在我想把它添加为centos系统服务。首先,我创建了一个任务,从我的脚本创建一个 link 到 /etc/init。d/service_name,如下所示。
---
- name: create startup link
file: src={{ cooltoo_service_script }} dest={{ cooltoo_service_init }} state=link
创建服务后,我想将其添加到系统服务中。用于执行此操作的命令是 "chkconfig --add service_name"。我想知道是否有一个 ansible 模块可以做到这一点,而不是在 ansible-playbook 文件中硬编码命令。我查看了此页面 http://docs.ansible.com/ansible/service_module.html,但它只显示了如何管理服务而不是创建新服务。
事实上,service
模块仅管理已注册的服务,正如您所了解的那样。据我所知,没有用于注册服务的模块。
您知道可以使用 some modifications 跳过此步骤到您的 init.d 脚本吗?如果脚本遵循这些规则,您可以只使用 service
模块来 enable/start 服务。
'service' 模块支持 'enabled' 参数。
这是剧本的一个示例部分,我坦率地承认它看起来确实像是新手的尝试。这假设 RHEL/CentOS 6.x,它使用 SysV,而不是 systemd。
- name: install rhel sysv supervisord init script
copy: src=etc/rc.d/init.d/supervisord dest=/etc/rc.d/init.d/supervisord owner=root group=root mode=0755
- name: install rhel sysv supervisord sysconfig
copy: src=etc/sysconfig/supervisord dest=/etc/sysconfig/supervisord owner=root group=root mode=0640
- name: enable sysv supervisord service
service: name=supervisord enabled=yes
- name: start supervisord
service: name=supervisord state=started
重要 许多自定义初始化脚本在使用 Ansible 和 SysV 初始化时会失败;原因是 'status' 选项(服务监督状态)需要 return 符合 LSB 的 return 代码。否则,Ansible 将不知道服务是 up 还是 down,幂等性将失败(重启仍然有效,因为那是无条件的)
这是脚本的一部分,我刚刚重写了它以利用 /etc/init.d/functions 中的 'status' 函数(您会在其他脚本中注意到相同的模式Red Hat 在 /etc/init.d/
中提供了初始化脚本
status)
/usr/bin/supervisorctl $OPTIONS status
status -p $PIDFILE supervisord
# The 'status' option should return one of the LSB-defined return-codes,
# in particular, return-code 3 should mean that the service is not
# currently running. This is particularly important for Ansible's 'service'
# module, as without this behaviour it won't know if a service is up or down.
RETVAL=$?
;;
参考:http://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
If the status action is requested, the init script will return the
following exit status codes.
0 program is running or service is OK 1 program is dead and /var/run
pid file exists 2 program is dead and /var/lock lock file exists
3 program is not running 4 program or service status is unknown
5-99 reserved for future LSB use 100-149 reserved for distribution use
150-199 reserved for application use 200-254 reserved
下面的代码片段将在 CentOS 7 中创建服务。
代码
任务
/tasks/main.yml
- name: TeamCity | Create environment file
template: src=teamcity.env.j2 dest=/etc/sysconfig/teamcity
- name: TeamCity | Create Unit file
template: src=teamcity.service.j2 dest=/lib/systemd/system/teamcity.service mode=644
notify:
- reload systemctl
- name: TeamCity | Start teamcity
service: name=teamcity.service state=started enabled=yes
模板
/templates/teamcity.service.j2
[Unit]
Description=JetBrains TeamCity
Requires=network.target
After=syslog.target network.target
[Service]
Type=forking
EnvironmentFile=/etc/sysconfig/teamcity
ExecStart={{teamcity.installation_path}}/bin/teamcity-server.sh start
ExecStop={{teamcity.installation_path}}/bin/teamcity-server.sh stop
User=teamcity
PIDFile={{teamcity.installation_path}}/teamcity.pid
Environment="TEAMCITY_PID_FILE_PATH={{teamcity.installation_path}}/teamcity.pid"
[Install]
WantedBy=multi-user.target
\templates\teamcity.env.j2
TEAMCITY_DATA_PATH="{{ teamcity.data_path }}"
处理程序
\handlers\main.yml
- name: reload systemctl
command: systemctl daemon-reload
参考:
对于RedHat/CentOS 7(使用systemd/systemctl
),chkconfig --add ${SERVICE_NAME}
等价于systemctl daemon-reload
[via fedoraproject.org].
然后,使用 Ansible 2.2 或更高版本的 systemd
模块,您可以使用前面的 systemctl daemon-reload
启动服务,例如 [via docs.ansible.com]:
# Example action to restart service cron on centos, in all cases, also issue daemon-reload to pick up config changes
- systemd:
state: restarted
daemon_reload: yes
name: crond
根据我的经验,daemon_reload
参数也可以在通用 service
模块中使用,尽管没有记录,并且在非 systemd 系统上可能会失败:
- service:
state: restarted
daemon_reload: yes
name: crond
我已经为 start/stop 我的应用程序创建了一个脚本。现在我想把它添加为centos系统服务。首先,我创建了一个任务,从我的脚本创建一个 link 到 /etc/init。d/service_name,如下所示。
---
- name: create startup link
file: src={{ cooltoo_service_script }} dest={{ cooltoo_service_init }} state=link
创建服务后,我想将其添加到系统服务中。用于执行此操作的命令是 "chkconfig --add service_name"。我想知道是否有一个 ansible 模块可以做到这一点,而不是在 ansible-playbook 文件中硬编码命令。我查看了此页面 http://docs.ansible.com/ansible/service_module.html,但它只显示了如何管理服务而不是创建新服务。
事实上,service
模块仅管理已注册的服务,正如您所了解的那样。据我所知,没有用于注册服务的模块。
您知道可以使用 some modifications 跳过此步骤到您的 init.d 脚本吗?如果脚本遵循这些规则,您可以只使用 service
模块来 enable/start 服务。
'service' 模块支持 'enabled' 参数。
这是剧本的一个示例部分,我坦率地承认它看起来确实像是新手的尝试。这假设 RHEL/CentOS 6.x,它使用 SysV,而不是 systemd。
- name: install rhel sysv supervisord init script
copy: src=etc/rc.d/init.d/supervisord dest=/etc/rc.d/init.d/supervisord owner=root group=root mode=0755
- name: install rhel sysv supervisord sysconfig
copy: src=etc/sysconfig/supervisord dest=/etc/sysconfig/supervisord owner=root group=root mode=0640
- name: enable sysv supervisord service
service: name=supervisord enabled=yes
- name: start supervisord
service: name=supervisord state=started
重要 许多自定义初始化脚本在使用 Ansible 和 SysV 初始化时会失败;原因是 'status' 选项(服务监督状态)需要 return 符合 LSB 的 return 代码。否则,Ansible 将不知道服务是 up 还是 down,幂等性将失败(重启仍然有效,因为那是无条件的)
这是脚本的一部分,我刚刚重写了它以利用 /etc/init.d/functions 中的 'status' 函数(您会在其他脚本中注意到相同的模式Red Hat 在 /etc/init.d/
中提供了初始化脚本status)
/usr/bin/supervisorctl $OPTIONS status
status -p $PIDFILE supervisord
# The 'status' option should return one of the LSB-defined return-codes,
# in particular, return-code 3 should mean that the service is not
# currently running. This is particularly important for Ansible's 'service'
# module, as without this behaviour it won't know if a service is up or down.
RETVAL=$?
;;
参考:http://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
If the status action is requested, the init script will return the following exit status codes.
0 program is running or service is OK 1 program is dead and /var/run pid file exists 2 program is dead and /var/lock lock file exists 3 program is not running 4 program or service status is unknown 5-99 reserved for future LSB use 100-149 reserved for distribution use 150-199 reserved for application use 200-254 reserved
下面的代码片段将在 CentOS 7 中创建服务。
代码
任务
/tasks/main.yml
- name: TeamCity | Create environment file
template: src=teamcity.env.j2 dest=/etc/sysconfig/teamcity
- name: TeamCity | Create Unit file
template: src=teamcity.service.j2 dest=/lib/systemd/system/teamcity.service mode=644
notify:
- reload systemctl
- name: TeamCity | Start teamcity
service: name=teamcity.service state=started enabled=yes
模板
/templates/teamcity.service.j2
[Unit]
Description=JetBrains TeamCity
Requires=network.target
After=syslog.target network.target
[Service]
Type=forking
EnvironmentFile=/etc/sysconfig/teamcity
ExecStart={{teamcity.installation_path}}/bin/teamcity-server.sh start
ExecStop={{teamcity.installation_path}}/bin/teamcity-server.sh stop
User=teamcity
PIDFile={{teamcity.installation_path}}/teamcity.pid
Environment="TEAMCITY_PID_FILE_PATH={{teamcity.installation_path}}/teamcity.pid"
[Install]
WantedBy=multi-user.target
\templates\teamcity.env.j2
TEAMCITY_DATA_PATH="{{ teamcity.data_path }}"
处理程序
\handlers\main.yml
- name: reload systemctl
command: systemctl daemon-reload
参考:
对于RedHat/CentOS 7(使用systemd/systemctl
),chkconfig --add ${SERVICE_NAME}
等价于systemctl daemon-reload
[via fedoraproject.org].
然后,使用 Ansible 2.2 或更高版本的 systemd
模块,您可以使用前面的 systemctl daemon-reload
启动服务,例如 [via docs.ansible.com]:
# Example action to restart service cron on centos, in all cases, also issue daemon-reload to pick up config changes
- systemd:
state: restarted
daemon_reload: yes
name: crond
根据我的经验,daemon_reload
参数也可以在通用 service
模块中使用,尽管没有记录,并且在非 systemd 系统上可能会失败:
- service:
state: restarted
daemon_reload: yes
name: crond