Ansible实现仅启动停止状态服务失败求助
问题描述
需求:实现仅当MariaDB服务处于停止状态时启动该服务。
编写的Playbook如下:
tasks: - name: Check the Service Status ansible.builtin.command: systemctl status mariadb.service register: service_status notify: Mariadb restart changed_when: service_status.rc != 0 ignore_errors: true handlers: - name: Mariadb restart ansible.builtin.service: name: httpd state: restarted
运行时即使配置了ignore_errors: true,仍出现任务失败提示,运行日志:
TASK [Check the Service Status] ************************************************************************************************************************************************************ fatal: [192.168.1.102]: FAILED! => {"changed": true, "cmd": ["systemctl", "status", "mariadb.service"], "delta": "0:00:00.016680", "end": "2024-11-21 00:20:53.396153", "msg": "non-zero return code", "rc": 3, "start": "2024-11-21 00:20:53.379473", "stderr": "", "stderr_lines": [], "stdout": "○ mariadb.service - MariaDB 10.5 database server\n Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; preset: disabled)\n Active: inactive (dead) since Wed 2024-11-20 23:30:01 EST; 50min ago\n Duration: 3min 52.893s\n Docs: man:mariadbd(8)\n https://mariadb.com/kb/en/library/systemd/\n Process: 12935 ExecStartPre=/usr/libexec/mariadb-check-socket (code=exited, status=0/SUCCESS)\n Process: 12957 ExecStartPre=/usr/libexec/mariadb-prepare-db-dir mariadb.service (code=exited, status=0/SUCCESS)\n Process: 12992 ExecStart=/usr/libexec/mariadbd --basedir=/usr $MYSQLD_OPTS $_WSREP_NEW_CLUSTER (code=exited, status=0/SUCCESS)\n Process: 13004 ExecStartPost=/usr/libexec/mariadb-check-upgrade (code=exited, status=0/SUCCESS)\n Main PID: 12992 (code=exited, status=0/SUCCESS)\n Status: \"MariaDB server is down\"\n CPU: 526ms\n\nNov 20 23:26:08 RHEL-Node-2 systemd[1]: Starting MariaDB 10.5 database server...\nNov 20 23:26:08 RHEL-Node-2 mariadb-prepare-db-dir[12957]: Database MariaDB is probably initialized in /var/lib/mysql already, nothing is done.\nNov 20 23:26:08 RHEL-Node-2 mariadb-prepare-db-dir[12957]: If this is not the case, make sure the /var/lib/mysql is empty before running mariadb-prepare-db-dir.\nNov 20 23:26:08 RHEL-Node-2 systemd[1]: Started MariaDB 10.5 database server.\nNov 20 23:30:01 RHEL-Node-2 systemd[1]: Stopping MariaDB 10.5 database server...\nNov 20 23:30:01 RHEL-Node-2 systemd[1]: mariadb.service: Deactivated successfully.\nNov 20 23:30:01 RHEL-Node-2 systemd[1]: Stopped MariaDB 10.5 database server.", "stdout_lines": ["○ mariadb.service - MariaDB 10.5 database server", " Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; preset: disabled)", " Active: inactive (dead) since Wed 2024-11-20 23:30:01 EST; 50min ago", " Duration: 3min 52.893s", " Docs: man:mariadbd(8)", " https://mariadb.com/kb/en/library/systemd/", " Process: 12935 ExecStartPre=/usr/libexec/mariadb-check-socket (code=exited, status=0/SUCCESS)", " Process: 12957 ExecStartPre=/usr/libexec/mariadb-prepare-db-dir mariadb.service (code=exited, status=0/SUCCESS)", " Process: 12992 ExecStart=/usr/libexec/mariadbd --basedir=/usr $MYSQLD_OPTS $_WSREP_NEW_CLUSTER (code=exited, status=0/SUCCESS)", " Process: 13004 ExecStartPost=/usr/libexec/mariadb-check-upgrade (code=exited, status=0/SUCCESS)", " Main PID: 12992 (code=exited, status=0/SUCCESS)", " Status: \"MariaDB server is down\"", " CPU: 526ms", "", "Nov 20 23:26:08 RHEL-Node-2 systemd[1]: Starting MariaDB 10.5 database server...", "Nov 20 23:26:08 RHEL-Node-2 mariadb-prepare-db-dir[12957]: Database MariaDB is probably initialized in /var/lib/mysql already, nothing is done.", "Nov 20 23:26:08 RHEL-Node-2 mariadb-prepare-db-dir[12957]: If this is not the case, make sure the /var/lib/mysql is empty before running mariadb-prepare-db-dir.", "Nov 20 23:26:08 RHEL-Node-2 systemd[1]: Started MariaDB 10.5 database server.", "Nov 20 23:30:01 RHEL-Node-2 systemd[1]: Stopping MariaDB 10.5 database server...", "Nov 20 23:30:01 RHEL-Node-2 systemd[1]: mariadb.service: Deactivated successfully.", "Nov 20 23:30:01 RHEL-Node-2 systemd[1]: Stopped MariaDB 10.5 database server."]} ...ignoring PLAY RECAP ********************************************************************************************************************************************************************************* 192.168.1.102 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
问题根源
- 命令选择不当:
systemctl status命令在服务停止时返回非0值,Ansible会默认标记任务失败,ignore_errors: true仅让Play继续执行,但无法消除任务失败的提示。 - Handler配置错误:Handler中指定的服务名是
httpd,与目标服务mariadb不符,即使触发也不会正确操作MariaDB。 - 状态参数错误:使用
state: restarted会强制重启服务,无论当前状态,不符合“仅启动停止服务”的需求,应使用state: started。
正确实现方案
方案一:使用Ansible内置Service模块(推荐)
Ansible的service模块会自动检测服务状态,仅当服务未运行时执行启动操作,无需额外判断,简洁且可靠:
- name: Ensure MariaDB is started when stopped hosts: 192.168.1.102 tasks: - name: Start MariaDB if it's not running ansible.builtin.service: name: mariadb state: started
方案二:改进命令检测方式(不推荐,仅作参考)
若必须通过命令判断状态,可使用systemctl is-active命令,该命令返回0表示服务活跃,3表示服务停止,通过failed_when控制任务失败条件:
- name: Ensure MariaDB is started when stopped hosts: 192.168.1.102 tasks: - name: Check MariaDB service status ansible.builtin.command: systemctl is-active mariadb.service register: service_status # 仅当返回值不是0(活跃)或3(停止)时标记任务失败 failed_when: service_status.rc not in [0, 3] # 仅当服务停止时标记任务为changed changed_when: service_status.rc == 3 - name: Start MariaDB if stopped ansible.builtin.service: name: mariadb state: started # 仅当服务停止时执行该任务 when: service_status.rc == 3
内容的提问来源于stack exchange,提问作者Linux4u
相关产品推荐
相关产品推荐

