在主机上执行任务的正确方法

Right way to execute task on host

我有一个包含以下主机的清单,如下所示(第一个集群)

[elasticsearch-cluster-india]
elasticsearch-01-mumbai ansible_host=10.0.87.19
elasticsearch-02-mumbai ansible_host=10.0.87.20
elasticsearch-03-mumbai ansible_host=10.0.87.21

我有下面的不同集群

[elasticsearch-cluster-kyrgyzstan]
elasticsearch-01-bishkek ansible_host=10.0.92.2
elasticsearch-02-bishkek ansible_host=10.0.92.3
elasticsearch-03-bishkek ansible_host=10.0.92.4

我想运行完成以下任务

- name: Set up snapshot cron job
  cron:
    name: "Elasticsearch backup"
    minute: 59
    hour: 23
    job: "{{ es_snapshot_snapshot_script_path }}/snapshot_es.sh"

那么如何仅在我组中的第一台主机上执行此任务? 我只想在主机 elasticsearch-01-bishkekelasticsearch-01-mumbai

上执行此任务

给主机添加一个变量:

[elasticsearch-cluster-india]
elasticsearch-01-mumbai ansible_host=10.0.87.19 do_backup=yes
elasticsearch-02-mumbai ansible_host=10.0.87.20
elasticsearch-03-mumbai ansible_host=10.0.87.21

然后检查一下:

- name: Set up snapshot cron job
  cron:
    name: "Elasticsearch backup"
    minute: 59
    hour: 23
    job: "{{ es_snapshot_snapshot_script_path }}/snapshot_es.sh"
  when: do_backup|default(false)|bool

这仍然不是详尽无遗的,但在我对@anemyte 的回答发表评论后,我想添加一些替代解决方案,以便路过的用户可以看到有不同的方法可以实现相同的需求并做出明智的选择.正如我在评论中所述,@anemyte 解决方案绝对有效,应该添加到以下命题中。

备注:

  • 我在下面使用简单的调试任务进行说明,因为您 运行 的实际任务对答案并不重要。
  • 我使用下划线 (_) 修复了组名,因为破折号 (-) 已被弃用。
  • 我用“大师”这个词来描述组中的第一个主机。这并没有真正适应 Elasticsearch 架构,但我希望你仍然明白这一点。

检查我们是否 运行 在组中的第一个主机上

这里的目标是动态创建一个列表,其中包含每个集群组的第一个元素,并查看当前目标是否匹配。我在下面的一个任务中做到了这一点,但您可以在 playbook/inventory.

中使用 vars 轻松扩展

这将在不对问题中的示例清单进行任何更改的情况下工作(除了我的笔记中所述的使用下划线的固定组命名)。

- name: Run a task if host is first on a set of groups
  debug:
    msg: "I'm a host on top of a cluster group"
  var:
    cluster_groups:
      - elasticsearch_cluster_india
      - elasticsearch_cluster_kyrgyzstan
    first_hosts: "{{ cluster_groups | map('extract', groups) | map('first') | flatten }}"
  when: inventory_hostname in first_hosts

与专业团队一起重构库存

这里我们修改清单以在特定组中添加“主”服务器。我提出的库存是一个简单的例子,可以根据具体需求进行调整。 yaml 格式的示例

---
elasticsearch_cluster_india_masters:
  hosts:
    elasticsearch-01-mumbai:
      ansible_host: 10.0.87.19

elasticsearch_cluster_india_clients:
  hosts:
    elasticsearch-02-mumbai:
      ansible_host: 10.0.87.20
    elasticsearch-03-mumbai:
      ansible_host: 10.0.87.21

elasticsearch_cluster_india:
  children:
    elasticsearch_cluster_india_masters:
    elasticsearch_cluster_india_clients:


elasticsearch_cluster_kyrgyzstan_masters:
  hosts:
    elasticsearch-01-bishkek:
      ansible_host: 10.0.92.2

elasticsearch_cluster_kyrgyzstan_clients:
  hosts:
    elasticsearch-02-bishkek:
      ansible_host: 10.0.92.3
    elasticsearch-03-bishkek:
      ansible_host: 10.0.92.4

elasticsearch_cluster_kyrgyzstan:
  children:
    elasticsearch_cluster_kyrgyzstan_masters:
    elasticsearch_cluster_kyrgyzstan_clients:

elasticsearch_cluster_masters:
  children:
    elasticsearch_cluster_india_masters:
    elasticsearch_cluster_kyrgyzstan_masters:

elasticsearch_cluster_clients:
  children:
    elasticsearch_cluster_india_clients:
    elasticsearch_cluster_kyrgyzstan_clients:

elasticsearch_cluster:
  children:
    elasticsearch_cluster_masters:
    elasticsearch_cluster_clients:

然后您可以在您的剧本中有更多的粒度:

---
- name: A play on all cluster hosts
  hosts: elasticsearch_cluster
  gather_facts: false

  tasks:
    - name: A task played on all hosts
      debug:
        msg: "Task played on all hosts"

    - name: A task played on masters only
      debug:
        msg: "I will play on masters only"
      when: inventory_hostname in groups['elasticsearch_cluster_masters']

- name: A play targeted to cluster masters only
  hosts: elasticsearch_cluster_masters
  gather_facts: false

  tasks:
    - name: A task for all master hosts
      debug:
        msg: "I don't need a when since play targets masters only"

    - name: An other tasks for masters only
      debug:
        msg: "Yet an other task"