【问题标题】:How to create new system service by ansible-playbook如何通过 ansible-playbook 创建新的系统服务
【发布时间】:2016-06-29 06:59:38
【问题描述】:

我创建了一个脚本来启动/停止我的应用程序。现在我想将它添加为centos系统服务。首先,我创建了一个任务来创建从我的脚本到 /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,但它只显示了如何管理服务而不是创建新服务。

【问题讨论】:

  • 这将有助于指定 CentOS 版本,因为 CentOS 6 使用 sysvinit 而 CentOS 7 使用 systemd。 sysvinit 兼容的初始化脚本不能总是被 Ansible 的 service 模块(或 Ansible 2.2 中添加的 systemd 模块)激活,这取决于 Linux 发行版如何配置 systemd。

标签: ansible ansible-playbook


【解决方案1】:

“服务”模块支持“启用”参数。

这是剧本的一个示例部分,我承认它确实看起来像新手尝试。这假设 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 初始化而失败;原因是“状态”选项(服务监督状态)需要返回符合 LSB 的返回代码。否则,Ansible 将不知道服务是启动还是关闭,幂等性将失败(重启仍然有效,因为这是无条件的)

这是一个脚本的一部分,我刚刚重写它以利用 /etc/init.d/functions 中的“状态”函数(您会在其他 Red Hat 提供的 init-scripts 中注意到相同的模式/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

如果请求状态操作,初始化脚本将返回 以下退出状态代码。

0 程序正在运行或服务正常 1 程序已死且 /var/run pid 文件存在 2 程序已死且 /var/lock 锁定文件存在 3 程序未运行 4 程序或服务状态未知 5-99 保留供将来 LSB 使用 100-149 保留供分配使用 150-199 保留供应用程序使用 200-254 保留

【讨论】:

    【解决方案2】:

    对于 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
    

    【讨论】:

      【解决方案3】:

      以下代码 sn -p 将在 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
      

      参考:

      【讨论】:

      【解决方案4】:

      确实,service 模块只管理您已经发现的已注册服务。据我所知,没有用于注册服务的模块。

      您是否知道在您的 init.d 脚本中可以使用 some modifications 跳过此步骤?如果脚本遵循这些规则,您可以使用service 模块来启用/启动服务。

      【讨论】:

      • 我已经有这样的脚本来启动/停止服务。我所要做的就是将其注册为系统服务。看来我得手动调用shell命令注册服务了。
      猜你喜欢
      • 2021-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多