[Ansible系列⑦]ansible fact变量

一.  简介

        facts组件是Ansible用于采集被管理机器设备信息的一个功能,采集的机器设备信息主要包含IP地址,操作系统,以太网设备,mac 地址,时间/日期相关数据,硬件信息等。

         ansible有一个模块叫setup,用于获取远程主机的相关信息,并可以将这些信息作为变量在playbook里进行调用。而setup模块获取这些信息的方法就是依赖于fact。

 二.  Fact的使用

 2.1    获取fact的系统信息

        setup获取的这些信息,都是可用于该主机的变量。 可直接在playbook中调用。

[root@clinet ansible_1]# ansible test -m setup
192.168.194.129 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.194.129"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::867a:fa0d:3e62:1ce4"
        ], 
        "ansible_apparmor": {
            "status": "disabled"
        }, 
        "ansible_architecture": "x86_64", 
        "ansible_bios_date": "07/29/2019", 
        "ansible_bios_version": "6.00", 
        "ansible_cmdline": {
            "BOOT_IMAGE": "/vmlinuz-3.10.0-1160.76.1.el7.x86_64", 
            "LANG": "en_US.UTF-8", 
            "crashkernel": "auto", 
            "quiet": true, 
            "rd.lvm.lv": "centos/swap", 
            "rhgb": true, 
            "ro": true, 
            "root": "/dev/mapper/centos-root"
        }, 
        "ansible_date_time": {
            "date": "2022-11-08", 
            "day": "08", 
            "epoch": "1667890437", 
            "hour": "14", 
            "iso8601": "2022-11-08T06:53:57Z", 
            "iso8601_basic": "20221108T145357782975", 
            "iso8601_basic_short": "20221108T145357", 
            "iso8601_micro": "2022-11-08T06:53:57.782975Z", 
            "minute": "53", 
            "month": "11", 
            "second": "57", 
            "time": "14:53:57", 
            "tz": "CST", 
            "tz_offset": "+0800", 
            "weekday": "Tuesday", 
            "weekday_number": "2", 
            "weeknumber": "45", 
            "year": "2022"
        }, 
        "ansible_default_ipv4": {
            "address": "192.168.194.129", 
            "alias": "ens33", 
            "broadcast": "192.168.194.255", 
            "gateway": "192.168.194.2", 
            "interface": "ens33", 
            "macaddress": "00:0c:29:b2:52:5b", 
            "mtu": 1500, 
            "netmask": "255.255.255.0", 
            "network": "192.168.194.0", 
            "type": "ether"
        }, 

        ...output omitted...
}

    2.1.1    setup模块其他用法示例

setup模块其他用法示例:
# 查看主机内存信息
ansible 10.212.52.252 -m setup -a 'filter=ansible_*_mb'

# 查看地接口为eth0-2的网卡信息
ansible 10.212.52.252 -m setup -a 'filter=ansible_eth[0-2]'

    2.1.2    playbook调用示例

[root@clinet ansible_1]# cat fact_test.yml
- hosts: test

  tasks:
    - name: debug message....
      debug:
        msg: 
        - '{{ ansible_all_ipv4_addresses }}'
        - '{{ ansible_ens33.ipv4 }}'



执行结果:
[root@clinet ansible_1]# ansible-playbook fact_test.yml 

PLAY [test] *********************************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************************
ok: [192.168.194.129]

TASK [debug message....] ********************************************************************************************************************************************************************************
ok: [192.168.194.129] => {
    "msg": [
        [
            "192.168.194.129"
        ], 
        {
            "address": "192.168.194.129", 
            "broadcast": "192.168.194.255", 
            "netmask": "255.255.255.0", 
            "network": "192.168.194.0"
        }
    ]
}

PLAY RECAP **********************************************************************************************************************************************************************************************
192.168.194.129            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@clinet ansible_1]# 

注意: fact变量是通过setup模块来获取的,在playbook中调用的时候要以ansib_xxx开始,往下获取字典中的值,不要误以为是以ansible_facts开始往下取值的,不然会提示没有定义该变量。错误示例:ansible_facts.ansible_all_ipv4_addresses 

三.  自定义fact 

3.1    手动设置fact 

         ansible除了能获取到预定义的fact的内容,还支持手动为某个主机定制fact。称之为本地fact。本地fact默认存放于被控端的/etc/ansible/facts.d目录下,如果文件为ini格式或者json格式,ansible会自动识别。以这种形式加载的fact是key为ansible_local的特殊变量。

    3.1.1  创建custom.fact文件

 在ansible的被控主机上创建/etc/ansible/facts.d/custom.fact文件,(目录不存在则创建)

[general]
package = nginx
service = nginx_server
state = started

以下是通过ansible来批量在被控端上创建/etc/ansible/facts.d/custom.fact文件。

---
- name: Install remote facts
  hosts: test
  vars: 
    remote_dir: /etc/ansible/facts.d
    facts_file: custom.fact
  tasks:
    - name: Create the remote directory
      file:
        state: directory
        recurse: yes
        path: "{{ remote_dir }}"
    - name: Install the new facts
      copy:
        src: "{{ facts_file }}"
        dest: "{{ remote_dir }}"



执行playbook
[root@clinet ansible_1]#ansible-playbook setup_facts.yml

 3.1.2    通过setup查看变量

[root@clinet ansible_1]# ansible test -m setup
192.168.194.129 | SUCCESS => {
    "ansible_facts": {

    ...output omitted...

"ansible_local": {
            "custon": {
                "general": {
                    "package": "nginx", 
                    "service": "nginx_server", 
                    "state": "started"
                }
            }
        }, 

    ...output omitted...
}

3.1.3    playbook调用该变量

[root@clinet ansible_1]# cat fact_test.yml 
- hosts: test

  tasks:
    - name: debug message....
      debug:
        msg: 
        - '{{ ansible_local }}'


执行结果:
[root@clinet ansible_1]# ansible-playbook fact_test.yml 

PLAY [test] *********************************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************************
ok: [192.168.194.129]

TASK [debug message....] ********************************************************************************************************************************************************************************
ok: [192.168.194.129] => {
    "msg": [
        {
            "custon": {
                "general": {
                    "package": "nginx", 
                    "service": "nginx_server", 
                    "state": "started"
                }
            }
        }
    ]
}

PLAY RECAP **********************************************************************************************************************************************************************************************
192.168.194.129            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@clinet ansible_1]# 

3.2    set_fact模块定义变量

         set_fact模块可以自定义facts,这些自定义的facts可以通过template或者变量的方式在playbook中使用。例如:如果你想要获取一个进程使用的内存的百分比,则必须通过set_fact来进行计算之后得出其值,并将其值在playbook中引用。

    3.2.1    set_fact变量传递

         通过set_fact模块可以将一个变量的值传递给set_fact定义的变量中。

---
- hosts: test
  vars:
    vars_1: 10

  tasks:
    - name: set_fct..
      set_fact:
        test_fact_1: "{{ ansible_all_ipv6_addresses }}"
        test_fact_2: "{{ ansible_memtotal_mb * 2}}"
    - name: debug message....
      debug:
        msg: 
        - '{{ test_fact_1 }}'
        - '{{ ansible_memtotal_mb }}'
        - '{{ test_fact_2 }}' 
        - "{{ vars_1 * 2}}"


执行结果:
[root@clinet ansible_1]# 
[root@clinet ansible_1]# ansible-playbook fact_test.yml 

PLAY [test] *********************************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************************
ok: [192.168.194.129]

TASK [set_fct..] ****************************************************************************************************************************************************************************************
ok: [192.168.194.129]

TASK [debug message....] ********************************************************************************************************************************************************************************
ok: [192.168.194.129] => {
    "msg": [
        [
            "fe80::867a:fa0d:3e62:1ce4"
        ], 
        1819, 
        "3638", 
        "20"
    ]
}

PLAY RECAP **********************************************************************************************************************************************************************************************
192.168.194.129            : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@clinet ansible_1]# 

注意:vars定义的变量,在调用的时候也可以进行计算。此处vars和set_fact的主要区别在于set_fact可以将经过计算的变量赋给新的变量。

       3.2.2    set_fact跨playbook使用

         在前面的playbook中定义的set_fact变量,可以在后面的playbook变量中直接调用。

[root@clinet ansible_1]#  cat   fact_test.yml
---
- hosts: test
  vars:
    vars_1: 10

  tasks:
    - name: set_fct..
      set_fact:
        test_fact_1: "{{ ansible_all_ipv6_addresses }}"
        test_fact_2: "{{ ansible_memtotal_mb * 2}}"
    - name: debug message....
      debug:
        msg: 
        - '{{ test_fact_1 }}'
        - '{{ ansible_memtotal_mb }}'
        - '{{ test_fact_2 }}' 
        - "{{ vars_1 * 2}}"


- hosts: test
  tasks:
    - name: info message。。。
      debug:
        msg:
        - "{{ test_fact_2 }}"


[root@clinet ansible_1]# 
[root@clinet ansible_1]# ansible-playbook fact_test.yml 

PLAY [test] *********************************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************************
ok: [192.168.194.129]

TASK [set_fct..] ****************************************************************************************************************************************************************************************
ok: [192.168.194.129]

TASK [debug message....] ********************************************************************************************************************************************************************************
ok: [192.168.194.129] => {
    "msg": [
        [
            "fe80::867a:fa0d:3e62:1ce4"
        ], 
        1819, 
        "3638", 
        "20"
    ]
}

PLAY [test] *********************************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************************
ok: [192.168.194.129]

TASK [info message。。。] **********************************************************************************************************************************************************************************
ok: [192.168.194.129] => {
    "msg": [
        "3638"
    ]
}

PLAY RECAP **********************************************************************************************************************************************************************************************
192.168.194.129            : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@clinet ansible_1]# ^C
[root@clinet ansible_1]# 

 四.   处理set_fact

4.1    关闭set_fact 

         在执行ansible-playbook的时候,会卡一段时间,此时就是主控端在远程获取被控端的fact信息,如果不想从fact中获取变量,或者说整个playbook当中都没有使用到fact变量,可以通过如下方法关闭fact以提升执行效率:

- hosts: test
  gather_facts: no

  tasks:
    ....

也可以在ansible.cfg中添加如下配置:

[defaults] 
gathering = explicit
....

 4.2    启动fact缓存

        如果在play中需要引入fact,则可以开启fact缓存。fact缓存目前支持三种存储方式,分别为JSON、memcached、redis。 

       4.2.1     json文件存储fact缓存

        使用JSON文件作为fact缓存后端的时候,ansible将会把采集的fact写入到控制主机的文件中。

ansible.cfg配置如下:

[defaults] 
#smart:  表示默认收集facts,但是facts已有的情况下不会收集,即使使用缓存facts
#implicit: 表示默认收集facts,要禁止收集,必须使用gather_facts:Flase
#explicit:表示默认不收集,要是收集,必须使用gather_facts:True
gathering = smart 



#缓存时间,单位为秒 
fact_caching_timeout = 86400
fact_caching = jsonfile 
#指定ansible包含fact的json文件位置,如果目录不存在,会自动创建 
fact_caching_connection = /tmp/ansible_fact_cache

        4.2.2    redis存储fact缓存

首先:
##先ansible --version查看python版本是多少,如果是python2.x则:
[root@clinet ansible_1]# yum  -y  install  python2-redis
[root@clinet ansible_1]# pip install --upgrade pip
[root@clinet ansible_1]# pip  install  redis


其次:
[root@clinet ansible_1]# cat ansible.cfg |grep -v ^# |grep -v ^$
[defaults]
gathering = smart
fact_caching_timeout = 86400
fact_caching = redis
fact_caching_connection = 192.168.194.128:6379 

#  若设置了redis的密码则:
fact_caching_connection = 192.168.194.128:6379:admin(密码)

随后:
# 执行ansible-playbook后查看redis
[root@clinet ansible_1]# redis-cli 
127.0.0.1:6379> 
127.0.0.1:6379> 
127.0.0.1:6379> KEYS *
1) "ansible_cache_keys"
2) "ansible_facts192.168.194.129"
127.0.0.1:6379> 

 4.2.3    Memcached fact存储fact缓存

        使用memcached作为fact缓存后端,需要在控制主机上安装Memcached服务并保持运行,需要安装python操作memcached的软件包。 

ansible.cfg配置如下:
[defaults]
gathering = smart
fact_caching_timeout = 86400 
fact_caching = memcached 

你可能感兴趣的:(运维,ansible系列,ansible,linux,运维,架构,服务器)