用例子解释 Ansible 事实

本教程解释了什么 可靠的事实 是,以及如何收集系统信息,即事实 Ansible 剧本.

内容

  1. Ansible Facts 简介
  2. 禁用事实收集
  3. 如何使用设置模块
  4. 事实数据类型
  5. 事实过滤和收集子集
  6. 将事实写入文件
  7. 在 Playbook 中使用设置模块
  8. 有和没有事实收集的运行时间变化
  9. 结论

Ansible Facts 简介

Facts 是有关托管主机的信息。

当你运行 playbook 时,ansible 会尝试收集有关托管主机的系统相关信息并将其存储在内存中,直到 playbook 完成。

这些信息可以是 IP 地址、操作系统、文件系统等。 此信息收集由 “设置” 模块。

您不需要定义设置模块。 相反,ansible 将自动使用 setup 模块并收集事实。

看看下面的例子。

创建一个剧本并添加以下剧本定义。 播放定义仅包含播放名称和目标主机。 没有为此剧本创建任务。

- name: Stats collection   hosts: all

从下面的输出可以看出,当我运行 playbook 时,收集事实作为第一个任务提交,即使我们没有在 playbook 中定义任何任务。

PLAY [Stats collection] *******************************************************************************************  TASK [Gathering Facts] ******************************************************************************************** ok: [rocky.anslab.com] ok: [master.anslab.com] ok: [ubuntu.anslab.com]  PLAY RECAP ******************************************************************************************************** master.anslab.com          : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  rocky.anslab.com           : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  ubuntu.anslab.com          : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

事实也被称为 剧本变量.

如何在 Ansible Playbook 中使用变量

禁用事实收集

并非每本剧本都需要收集事实。 您可以通过添加跳过事实收集 gather_facts: false 到播放定义。

- name: Stats collection   hosts: all   gather_facts: false

如何使用设置模块

正如我在上一节中所说,ansible 使用 setup 模块来收集事实。 让我们看看一些将 setup 模块用作 adhoc 命令的方法,然后我们将看到如何在 playbook 中明确使用 setup 模块。

设置命令的输出将在 JSON 格式。 对目标主机运行以下命令以获取事实输出。

$ ansible m1 -m setup | less
使用 Ansible 收集事实

从上图中可以看出,收集了大量的系统相关信息。 有些信息可能有用,有些可能没有。

事实数据类型

事实中存储的信息分为三种不同的数据类型。

  • AnsibleUnsafeText
  • 字典
  • 列表

以下剧本用于演示事实输出的数据类型。 我在用 type_debug 查找数据类型。

- name: Facts Data type   hosts: m2   gather_facts: true   tags: datatype    tasks:      - name: AnsibleUnsafeText       debug:          var: ansible_facts['distribution'] | type_debug       - name: dict       debug:         var: ansible_facts['eth0']['ipv4'] | type_debug      - name: List       debug:         var: ansible_facts['eth0']['ipv6'] | type_debug

样本输出:

$ ansible-playbook facts_data_type.yml  TASK [AnsibleUnsafeText] **************************************************************************************************************************************************************************************** ok: [rocky.anslab.com] => {     "ansible_facts['distribution'] | type_debug": "AnsibleUnsafeText" }  TASK [dict] ***************************************************************************************************************************************************************************************************** ok: [rocky.anslab.com] => {     "ansible_facts['eth0']['ipv4'] | type_debug": "dict" }  TASK [List] ***************************************************************************************************************************************************************************************************** ok: [rocky.anslab.com] => {     "ansible_facts['eth0']['ipv6'] | type_debug": "list" }

事实过滤和收集子集

您可以应用过滤器从事实输出中获取一部分数据。 假设我想抓取机器架构,那么命令如下。

$ ansible m2 -m setup -a "filter=ansible_architecture"  rocky.anslab.com | SUCCESS => {     "ansible_facts": {         "ansible_architecture": "x86_64",         "discovered_interpreter_python": "/usr/libexec/platform-python"     },     "changed": false }

您还可以使用模式过滤数据。

$ ansible m2 -m setup -a "filter=*architecture"  rocky.anslab.com | SUCCESS => {     "ansible_facts": {         "ansible_architecture": "x86_64",         "ansible_userspace_architecture": "x86_64",         "discovered_interpreter_python": "/usr/libexec/platform-python"     },     "changed": false }

你也可以使用 gather_subset 获取指定的事实子集。 例如,如果您只想要网络相关信息,您可以使用 gather_subset=network.

$ ansible m2 -m setup -a "gather_subset=network"

同样,还有其他子集,例如 all, min, hardware, network, 和 virtual 等等。默认情况下“all“已设置。

你可以加前缀 ! 象征 与不会收集特定子集的任何子集。 例如,以下命令将收集除网络相关信息之外的所有事实。

$ ansible m2 -m setup -a "gather_subset=!network"

将事实写入文件

您可以使用 --tree 旗帜。 目录路径应作为参数传递给 --tree 旗帜。

$ ansible all -m setup --tree /home/vagrant/facts

这里 ansible 将收集所有组的事实并将输出与服务器名称一起存储在目录中 /home/vagrant/facts.

$ ls -l ~/facts total 68 -rw-rw-r-- 1 vagrant vagrant 21092 Apr 27 05:36 master.anslab.com -rw-rw-r-- 1 vagrant vagrant 18336 Apr 27 05:36 rocky.anslab.com -rw-rw-r-- 1 vagrant vagrant 21093 Apr 27 05:36 ubuntu.anslab.com

在 Playbook 中使用设置模块

并非事实中收集的所有数据都将用于您的剧本。 因此,您可以明确使用设置模块并收集您感兴趣的数据。

如果你看一下下面的剧本,我感兴趣的唯一数据是托管节点分布信息。 使用这些信息,我写了一个条件语句。

- name: Explicitly using setup module   hosts: all   gather_facts: false      tasks:      - name: Setup Module       setup:         filter: ansible_distribution      - name: Doing something       debug:         msg: "Spotted RHEL based distro. Proceeding with activity..."       when: ansible_distribution | lower in ["rocky","redhat","centos"]

在下面的输出中,您可以看到任务仅在 Rocky Linux 上运行,而在基于 Ubuntu 的发行版中被跳过。

TASK [Setup Module] *********************************************************************************** ok: [rocky.anslab.com] ok: [master.anslab.com] ok: [ubuntu.anslab.com]  TASK [Doing something] ******************************************************************************** skipping: [master.anslab.com] skipping: [ubuntu.anslab.com] ok: [rocky.anslab.com] => {     "msg": "Spotted RHEL based distro. Proceeding with activity..." }

你也可以使用 过滤器收集子集 在剧本中。

- name: Applying filter   setup:     filter:       - 'ansible_distribution'       - 'ansible_eth[0-3]' - name: Using subsets   setup:     gather_subset:       - '!all'       - 'network'

有和没有事实收集的运行时间变化

当您针对大量托管主机运行 playbook 时,事实收集会减慢播放速度。 使用 time 命令您可以检查有无事实的剧本运行时间。

下面的输出显示了有和没有事实的时间差。 我的剧本的任务数量较少,只有 3 个托管主机,因此运行时间不会有太大差异。

# With facts $ time ansible-playbook facts.yml  real0m3.096s user0m1.264s sys    0m0.340s
# Without facts $ time ansible-playbook facts.yml  real0m2.112s user0m0.887s sys    0m0.265s

结论

在本文中,我们讨论了什么是事实以及如何使用 setup 模块运行临时命令,以及如何在 playbook 中明确使用 setup 模块。

当您针对大量目标运行时,事实收集是一个耗时的过程。

AnsibleAnsible 命令Ansible FactsAnsible PlaybooksAnsible 系列Ansible 教程Ansible 变量CLI 命令行DevOpsIT 自动化LinuxLinux 管理系统管理员