在 Ansible 中,ansible_hostname、inventory_hostname 和 ansible_fqdn 是三个常用的内部变量,它们在实际使用中可能会让人混淆。下面通过一个实际的 Ansible Playbook 示例来解释它们的区别。

1. ansible_hostname

  • 来源:从目标主机的系统信息(facts)中读取。
  • 特点:等同于在目标主机上运行 uname -n 或 hostname 命令的结果。
  • 依赖:需要在 Playbook 中启用 gather_facts,否则无法使用。
  • 适用场景:当你需要获取目标主机的实际主机名时使用。

2. inventory_hostname

  • 来源:从 Ansible 的主机清单(inventory)文件中读取。
  • 特点:这是你在主机清单中为每个主机指定的名称,可能与目标主机的实际主机名不同。
  • 适用场景:当你需要引用主机清单中的主机名时使用,例如在动态生成任务或条件判断中。

3. ansible_fqdn

  • 来源:从目标主机的系统信息(facts)中读取,表示目标主机的完全限定域名(FQDN)。
  • 特点:通常包含域名部分,例如 demo.example.com。
  • 适用场景:当你需要获取目标主机的完整域名时使用。

示例:通过 Ansible Playbook 展示区别

Playbook 文件:hostnames.yml

---
- name: hostnames demo
  hosts: all
  gather_facts: true
  tasks:
    - name: print inventory_hostname
      ansible.builtin.debug:
        var: inventory_hostname

    - name: print ansible_hostname
      ansible.builtin.debug:
        var: ansible_hostname

    - name: print ansible_fqdn
      ansible.builtin.debug:
        var: ansible_fqdn

主机清单文件:inventory

foo.example.com ansible_host=192.168.0.190

[all:vars]
ansible_connection=ssh
ansible_user=devops
ansible_ssh_private_key_file=~/.ssh/id_rsa

执行命令

$ ansible-playbook -i inventory hostnames.yml

执行结果

PLAY [hostnames demo] ***********************************
TASK [Gathering Facts] **********************************
ok: [foo.example.com]
TASK [print inventory_hostname] *************************
ok: [foo.example.com] => {
    "inventory_hostname": "foo.example.com"
}
TASK [print ansible_hostname] ***************************
ok: [foo.example.com] => {
    "ansible_hostname": "demo"
}
TASK [print ansible_fqdn] *******************************
ok: [foo.example.com] => {
    "ansible_fqdn": "demo.example.com"
}
PLAY RECAP **********************************************
foo.example.com            : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

解释结果

  1. inventory_hostname
    • 输出:foo.example.com
    • 解释:这是从主机清单文件中读取的名称,可能与目标主机的实际主机名不同。
  2. ansible_hostname
    • 输出:demo
    • 解释:这是目标主机的实际主机名,等同于在目标主机上运行 hostname 命令的结果。
  3. ansible_fqdn
    • 输出:demo.example.com
    • 解释:这是目标主机的完全限定域名(FQDN),通常包含域名部分。

执行前的状态

$ ssh devops@192.168.0.190
[devops@demo ~]$ uname -a
Linux demo.example.com 4.18.0-348.el8.x86_64 #1 SMP Mon Oct 4 12:17:22 EDT 2021 x86_64 x86_64 x86_64 GNU/Linux
[devops@demo ~]$ uname -n
demo.example.com
[devops@demo ~]$ hostname
demo.example.com
[devops@demo ~]$

总结

  • ansible_hostname:目标主机的实际主机名,需要启用 gather_facts。
  • inventory_hostname:从主机清单文件中读取的主机名,始终可用。
  • ansible_fqdn:目标主机的完全限定域名(FQDN),需要启用 gather_facts。

根据你的需求选择合适的变量。例如:

  • 如果需要引用主机清单中的主机名,使用 inventory_hostname。
  • 如果需要获取目标主机的实际主机名,使用 ansible_hostname。
  • 如果需要获取目标主机的完整域名,使用 ansible_fqdn。