为什么 Ansible 运行 在多个主机上,而条件假设在单个主机上 运行?

Why Ansible run on multiple hosts when condition is suppose to run on single host?

我已经在 Ansible 中多次注意到这一点,当有类似的 IP,如“10.142.175.153”和“10.142.175.15”时,如下例的条件采用两个 IP 并尝试执行。这是使用 when 条件、inventory_hostname 和组的正确方法吗?如果不是,正确的方法是什么。

我有这样的库存文件:

[m_nodes]
10.142.175.42 hostname=mss-mdpha2-mn1
10.142.175.77 hostname=mss-mdpha2-mn2
10.142.175.183 hostname=mss-mdpha2-mn3
10.142.175.57 hostname=mss-mdpha2-mn4
10.142.175.98 hostname=mss-mdpha2-mn5

[u_nodes]
10.142.175.153 hostname=mss-mdpha2-un1
10.142.175.104 hostname=mss-mdpha2-un2

[e_nodes]
10.142.175.51 hostname=mss-mdpha2-en1
10.142.175.85 hostname=mss-mdpha2-en2

[r_nodes]
10.142.175.15 hostname=mss-mdpha2-rn1
10.142.175.108 hostname=mss-mdpha2-rn2

我的剧本如下

---
- hosts: all
  gather_facts: yes
  tasks:
  - name: Here we are checking ansible_hostname
    debug:
      msg: "hostname is {{ ansible_hostname }}"
    when: inventory_hostname in groups['u_nodes'][0]
  - name: Here we are checking inventory_hostname
    debug:
      msg: "hostname is {{ inventory_hostname }}"
    when: inventory_hostname in groups['u_nodes'][0]

输出如下

TASK [Here we are checking ansible_hostname] *********************************************************************************************************************************************************************************************************************************
skipping: [10.142.175.42]
skipping: [10.142.175.77]
skipping: [10.142.175.98]
skipping: [10.142.175.183]
skipping: [10.142.175.57]
ok: [10.142.175.153] => {
    "msg": "hostname is mss-mdpha2-un1"
}
skipping: [10.142.175.104]
skipping: [10.142.175.51]
ok: [10.142.175.15] => {
    "msg": "hostname is mss-mdpha2-rn1"
}
skipping: [10.142.175.85]
skipping: [10.142.175.108]

TASK [Here we are checking inventory_hostname] *******************************************************************************************************************************************************************************************************************************
skipping: [10.142.175.42]
skipping: [10.142.175.77]
skipping: [10.142.175.183]
skipping: [10.142.175.57]
skipping: [10.142.175.98]
skipping: [10.142.175.104]
ok: [10.142.175.153] => {
    "msg": "hostname is 10.142.175.153"
}
skipping: [10.142.175.51]
skipping: [10.142.175.85]
skipping: [10.142.175.108]
ok: [10.142.175.15] => {
    "msg": "hostname is 10.142.175.15"
}

问题是您使用的是 in 比较而不是 == 比较。 groups['u_nodes'][0] 的值是一个字符串 (10.142.175.153)。当您询问是否 stringA in stringB 时,您是在询问 stringB 是否在其值的任何位置包含 stringA。比如stringB是一个包含词组this is a test的变量,下面都是true:

  • "test" in stringB
  • "this" in stringB
  • "s a t" in stringB

所以当你有一个字符串 10.142.175.153 并且你问是否 "10.142.175.15" in "10.142.175.153" 时,答案是肯定的,它是。

您想要进行相等性检查:

when: inventory_hostname == groups['u_nodes'][0]

只有当两个字符串完全相等时才会true


如果所有游戏中的任务应该只运行在一台主机上,更好的解决方案是只针对游戏中的主机:

- hosts: u_nodes[0]
  tasks:
     ...