如何在找到特定主机后跳过其他主机 – Ansible

56次阅读
没有评论

问题描述

在使用Ansible时,有一个需求是希望在一组主机中找到第一个运行特定Docker容器的主机。他创建了一个包含一系列任务的playbook,最终执行一个curl命令。他只想在一个主机上执行该命令,但首先必须根据主机是否运行特定的Docker镜像来找到该主机。他使用一个shell任务来执行docker ps | grep my-filter命令,以查看主机是否有名为”my-filter”的Docker容器。一旦在特定主机上找到该容器,他希望在该主机上执行其余的任务。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

为了在找到第一个主机后跳过其他主机,可以使用blockwhen语句来实现。以下是一个示例playbook:

- hosts: test
  tasks:
    - block:
        - shell: docker ps | grep my-filter
          register: result
          delegate_to: "{{ item }}"
          ignore_errors: true
          when: (result|default({})).rc == 0
        - set_fact:
            my_host: "{{ result.results|json_query('[?rc == `0`].item')|first }}"
        - debug:
            var: my_host
        - add_host:
            name: "{{ my_host }}"
            groups: my_group
      run_once: true

- hosts: my_group
  tasks:
    - debug:
        var: inventory_hostname

在上面的示例中,我们首先在test组的所有主机上执行一个shell命令来检查是否有名为”my-filter”的Docker容器。如果命令返回0(即找到了容器),我们将该主机添加到my_group组中。然后,我们在my_group组的主机上执行其他任务。

请注意,delegate_to参数用于将任务委派给特定的主机,以便在该主机上执行命令。ignore_errors参数用于忽略命令执行的错误,以便在找到容器的主机上继续执行任务。

方案2

另一种方法是使用with_first_found循环来找到第一个满足条件的主机,并将其添加到一个新的组中。以下是一个示例playbook:

- hosts: test
  tasks:
    - set_fact:
        my_host: "{{ item }}"
      with_first_found:
        - command: docker ps | grep my-filter
          delegate_to: "{{ item }}"
          ignore_errors: true
      run_once: true

    - add_host:
        name: "{{ my_host }}"
        groups: my_group
      run_once: true

- hosts: my_group
  tasks:
    - debug:
        var: inventory_hostname

在上面的示例中,我们使用with_first_found循环来执行一个命令来检查是否有名为”my-filter”的Docker容器。一旦找到满足条件的主机,我们将其添加到my_group组中。然后,我们在my_group组的主机上执行其他任务。

请注意,delegate_to参数用于将命令委派给特定的主机,以便在该主机上执行命令。ignore_errors参数用于忽略命令执行的错误,以便在找到容器的主机上继续执行任务。

以上是两种解决方案,你可以根据自己的需求选择其中一种。

正文完