循环组 IP

Loop over group IP's

我有一个主机组,要用 GlusterFS 探测这些主机,我需要将该组变成 IP 列表。

我在这里和 Google 上进行了搜索,并尝试了很多方法来完成这项工作,其中一些包含大量代码,而另一些包含模板和正则表达式等等。

目前我还没有找到仅列出一组主机 IP 的单一解决方案。 这是我自己做的,它带组,把这个字典变成一个列表,然后在列表上循环,太棒了!但是当我遍历它时,结果是字符串(为什么?!)而且我无法再获取 IP。

- name: workit
  vars:
    main_nodes_ips: "{{ groups['glusterpeers'] | list }}"
  loop: "{{ main_nodes_ips }}"
  debug:
    msg: "{{ item['hostvars'] }}"

我找到了这个

- debug: var=hostvars[inventory_hostname]['ansible_default_ipv4']['address']

但是如何把它变成这个(例子不工作)

- debug: var=groups['glusterpeers']['ansible_default_ipv4']['address']

我不明白为什么主机列表会突然变成字符串列表,但也许我不应该将其视为对象。


我的结果
这就是我最终为 GlusterFS 探测所有对等点的结果。在 'when' 块中,我对第一个节点的主机名进行了硬编码,这不是很好。我仍然想知道是否有更优雅的方式来探测对等点,这一定是所有 GlusterFS 用户都会做的事情。 当此 IP 顺序更改时,使用第二个 IP 可能会带来麻烦,因此主机名可能更好。

- hosts: all
  gather_facts: true
  tasks:
    - set_fact:
        main_nodes_ips: "{{ groups.zicluster|
                            map('extract', hostvars, 'ansible_all_ipv4_addresses')|
                            map(attribute='1')|
                            list }}"
      run_once: true
    - debug:
        var: main_nodes_ips[1:]
      when: inventory_hostname == 'zi01'

    - name: probe the peers
      gluster.gluster.gluster_peer:
            state: present
            nodes: "{{ main_nodes_ips[1:] }}"
      when: inventory_hostname == 'zi01'

例如,下面的剧本获取远程主机的第一个 IP 地址并创建列表

- hosts: glusterpeers
  gather_facts: true
  tasks:
    - debug:
        var: ansible_all_ipv4_addresses
    - set_fact:
        main_nodes_ips: "{{ groups.glusterpeers|
                            map('extract', hostvars, 'ansible_all_ipv4_addresses')|
                            map('first')|
                            list }}"
      run_once: true
    - debug:
        var: main_nodes_ips
      run_once: true

给予

PLAY [glusterpeers] ***************************************

TASK [Gathering Facts] ************************************
ok: [host02]
ok: [host01]
ok: [host03]

TASK [debug] **********************************************
ok: [host01] => 
  ansible_all_ipv4_addresses:
  - 10.1.0.61
ok: [host02] => 
  ansible_all_ipv4_addresses:
  - 10.1.0.62
ok: [host03] => 
  ansible_all_ipv4_addresses:
  - 10.1.0.63

TASK [set_fact] *******************************************
ok: [host01]

TASK [debug] **********************************************
ok: [host01] => 
main_nodes_ips:
  - 10.1.0.61
  - 10.1.0.62
  - 10.1.0.63

备注

  • 如果您想从列表 map 属性中获取任何其他索引。例如,要获得第二项,替换
  map('first')|

来自

  map(attribute='1')|
  • 在您的代码中,您从特定主机的列表中删除了第一个 IP。这仅适用于第一台主机
    - debug:
        msg: "{{ main_nodes_ips[1:] }}"
      when: inventory_hostname == 'host01'

如果要删除任何主机的 IP,请创建字典。例如

    - set_fact:
        main_nodes: "{{ dict(groups.glusterpeers|zip(main_nodes_ips)) }}"
      run_once: true

给予

  main_nodes:
    host01: 10.1.0.61
    host02: 10.1.0.62
    host03: 10.1.0.63

然后,使用这个字典从列表中删除特定主机的 IP

    - debug:
        msg: "{{ main_nodes_ips|difference(main_nodes[inventory_hostname]) }}"
      when: inventory_hostname == 'host01'

给予

TASK [debug] **************************************************
skipping: [host02]
skipping: [host03]
ok: [host01] => 
  msg:
  - 10.1.0.62
  - 10.1.0.63