You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
问题根源
  1. 命令选择不当:systemctl status命令在服务停止时返回非0值,Ansible会默认标记任务失败,ignore_errors: true仅让Play继续执行,但无法消除任务失败的提示。
  2. Handler配置错误:Handler中指定的服务名是httpd,与目标服务mariadb不符,即使触发也不会正确操作MariaDB。
  3. 状态参数错误:使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 05:15:54