ansible-playbook

  • 8.1 优化
  • 8.1.1 调试debug(-v/-vv/-vvv)
  • 8.1.2 SSH关闭密钥检测(hot_key_checking = False)
  • 8.1.3 OpenSSH链接优化(UseDNS no)
  • 8.1.4 开启SSH的流水线(pipelining = True)
  • 8.1.5 禁用gather_facts
  • 8.1.6 Facts缓存到jsonfile
  • 8.1.7 Facts缓存到redis
  • 8.1.8 执行策略(strategy)
  • 8.1.9 异步(-B 2 -P2 ,async poll)
  • 8.1.10 yum安装优化
  • 8.1.11 使用混合模式的inventory
  • 8.1.12 使用inventory脚本
  • 8.1.13 目录结构介绍


8.1 优化

相比于其他的自动化配置工具,Ansible的一个突出特性就是它是基于SSH链接对下游设备进行控制的,这样做的突出好处就是方便,下游设备不需要安装客户端软件。但是这也不可避免的带来一个问题,即Ansible的执行速度较慢。并且,随着Ansible控制设备的增多,Ansible的执行速度会越来越慢。

关于Ansible执行速度的问题,尽管是Ansible的硬伤,但是我们还是可以对其进行部分的优化,尽量的加快Ansible的执行速度。对Ansible的优化可以有两个思路:

  1. 优化SSH链接,使得SSH的传输速度变快。
    修改连接时间
    减少put get操作
  2. 禁用gather_facts,或更改模式
    每次Ansible Playbook在执行时,都会收集下游设备的信息,这个过程通常要耗费较长的时间。因此,我们可以考虑使用Redis对这些信息进行缓存,从而加快收集信息的速度,如果业务环境允许,我们也可以直接控制Ansible设备跳过该步骤。

配置文件ansible.cfg:

[defaults]

#通用默认配置段

inventory = /etc/ansible/hosts

#被控制端IP或者DNS列表

library = /usr/share/my_modules/

#ansible默认搜寻模块的位置

remote_tmp = $HOME:/.ansible/tmp

#ansible远程执行临时文件

forks = 100

#并行进程数

sudo_user = root

#sudo远程执行用户名

ask_sudo_pass = True

#使用sudo,是否需要输入密码

ask_pass = True

#是否需要输入密码

remote_port = 22

#远程SSH端口

module_lang = C

#模块和系统之间通信的语言

host_key_checking = False

#检查远程主机密钥

#sudo_exec = sudo

#sudo远程执行命令

#sudo_flags = -H

#传递sudo之外的参数

timeout = 10

#SSH超时时间

remote_user = root

#远程登陆用户名

log_path = /var/log/ansible.log

#日志文件存放路径

module_name = command

#ansible命令执行默认的模块

#executable = /bin/bash

#执行的shell环境,使用shell模块

#system_marnings = True

#禁用系统运行ansible潜在问题警告

#command_warnings = False

#command模块ansible模块默认发出的警告

#nocolor = 1

#输出带上颜色区别,开启/关闭: 0/1

pipelining = False

#开启pipe SSH通道优化

8.1.1 调试debug(-v/-vv/-vvv)

调试的时候可以通过-v显示详细信息,-vv/-vvv显示更详细的信息

[root@dbc-server-554 ansible]# ansible server -i hosts -m ping -v
Using /etc/ansible/ansible.cfg as config file
192.168.20.3 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
[root@dbc-server-554 ansible]# cat checkhosts.yml
---
- name: check servers
  hosts: all
  tasks:
    - name: check hosts
      ping:
[root@dbc-server-554 ansible]# ansible-playbook -i hosts checkhosts.yml --limit server

PLAY [check servers] ***********************************************************

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

TASK [check hosts] *************************************************************
ok: [192.168.20.3]

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

8.1.2 SSH关闭密钥检测(hot_key_checking = False)

在默认情况下,以SSH登录远程设备时,该设备会检查远程主机的公钥,并且将该公钥记录在~/.ssh/known_hosts文件中,当下次该主机访问时,OpenSSH会核对公钥。如果公钥不同,则OpenSSH会发出警告,如果公钥相同,则OpenSSH则会提示输入密码。

SSH对主机公钥的检查是根据StrictHostKeyChecking变量来设定的,StrictHostKeyChecking的检查级别包括:no(不检查),ask(是否检查要询问),yes(每次都检查),False(关闭检查)。
我们可以在Ansible的配置文件中defaults模块下加入如下代码:
host_key_checking = False

[root@dbc-server-554 ansible]# cat /etc/ansible/ansible.cfg |grep hot
hot_key_checking = False

8.1.3 OpenSSH链接优化(UseDNS no)

在使用OpenSSH服务时,默认情况下服务器端会根据客户端的IP地址进行DNS反向解析,得到客户端的主机名,然后根据获取到的主机名再次进行DNS查询得到IP地址,比较这两个IP地址是否一样。这样做可以在一定程度上提高安全性,但是却会浪费时间,因此,我们可以通过关闭这一特性,来实现加速SSH链接速度的目的。
关闭该特新需要进入到/etc/ssh/sshd_config目录下,找到UseDNS的参数,将其修改为no,笔者配置文件默认是注释掉的,这种情况不改即可

[root@dbc-server-554 ansible]# cat /etc/ssh/sshd_config |grep UseDNS
UseDNS no
[root@dbc-server-554 ansible]# cat /etc/ssh/sshd_config |grep UseDNS
#UseDNS yes

8.1.4 开启SSH的流水线(pipelining = True)

  1. 减少put get操作
[root@dbc-server-554 ansible]# cat /etc/ansible/ansible.cfg|grep pipelining
# Enabling pipelining reduces the number of SSH operations required to
#pipelining = False
# The -tt argument is passed to ssh when pipelining is not enabled because sudo

pipeline是openssh的一个特性,ssh pipelining是一个加速Ansible执行速度的一个简单方法。

[root@dbc-server-554 ansible]# cat /etc/ansible/ansible.cfg|grep pipelining
# Enabling pipelining reduces the number of SSH operations required to
pipelining = True
  1. 为何要开启pipelining
    在ansible执行每一个任务的整个流程中,有一个过程是将临时任务文件put到远程的ansible客户机上,然后通过ssh连接过去远程执行这个任务,如果开启了pipelining,一个任务的所有动作都在一个ssh会话中完成,也会省去sftp到远端的过程,它会直接将要执行的任务在ssh会话中进行。
[root@dbc-server-554 ansible]# ansible-playbook -i hosts checkhosts.yml

PLAY [check servers] ***********************************************************

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

TASK [check hosts] *************************************************************
ok: [192.168.71.183]

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

开启了pipelining之后,ansible的执行整个流程就少了一个PUT脚本去远程服务端的流程,然后就可以批量对机器执行命令,可以明显感受到速度的提升。

ssh pipelining默认是关闭的,默认关闭是为了兼容不同的sudo配置,主要是requiretty选项,如果不使用sudo,建议开启ssh pipelining选项。打开此选项可以减少ansible执行没有传输时ssh在被控机器上执行任务的连接数。但是如果使用sudo,必须关闭requiretty选项。
如果在ansible中使用sudo命令的话,需要在被控节点的 /etc/sudoer 中禁用 “requiretty”,这样设置是因为ssh远程执行命令时,它的环境是非登录式非交互式shell,默认不会分配tty,没有tty,ssh的sudo就无法关闭密码回显(使用 -tt 选项前置ssh分配tty)。所以出于安全考虑,/etc/sudoers 中默认是开启 requiretty的,它要求只有拥有tty的用户才能使用sudo,也就是说ssh连接过去不允许执行sudo。

8.1.5 禁用gather_facts

为了减少Ansible在收集客户端信息时的时间,我们首先想到的就是直接删除这一选项。我们可以在palybook文件中添加一行:

gather_facts: no

8.1.6 Facts缓存到jsonfile

facts是获取主机信息的
需求:不想每次获取task,但想用fact变量
解决:fact缓存到本地文件
smart模式,希望收集,如果有缓存,不再收集,因此 gathering 要改为 gathering = smart

在Ansible的配置文件中,关于facts的重要配置项有以下几个:
gathering:facts的开关,默认是开启的;有以下三个取值:

  • smart:开启facts信息收集,但是会优先使用facts缓存信息,可以使用gather_facts: False禁用facts收集;
  • implicit:开启facts信息收集,要禁止收集,必须使用gather_facts: False;
  • explicit:关闭facts信息收集,要显式收集,必须使用gather_facts: Ture。

fact_caching:缓存facts信息的方式;可以配置成jsonfile或者redis;
fact_caching_connection:缓存插件的配置,针对不同的fact_caching方式,取值含义则不同:

  • 如果fact_caching为jsonfile,则此处应配置存储缓存文件的目录;
  • 如果fact_caching为redis,则此处应按照host:port:database的格式配置redis的信息。

gather_timeout:收集超时时间,默认为86400;
fact_caching_timeout:设置facts缓存的过期时间,默认是86400秒。

修改前:

[root@dbc-server-554 ansible]# cat /etc/ansible/ansible.cfg|grep fact_caching
#fact_caching = memory
#For the redis plugin, the value is a host:port:database triplet: fact_caching_connection = localhost:6379:0
#fact_caching_connection=/tmp

修改后:

[root@dbc-server-554 ansible]# cat /etc/ansible/ansible.cfg|grep fact_caching
fact_caching = jsonfile
#For the redis plugin, the value is a host:port:database triplet: fact_caching_connection = localhost:6379:0
fact_caching_connection=/tmp
fact_caching_timeout=10
[root@dbc-server-554 ansible]# cat /etc/ansible/ansible.cfg |grep gathering
gathering = smart
[root@dbc-server-554 ansible]# ansible-playbook -i hosts checkhosts.yml
...
[root@dbc-server-554 ansible]# head -10 /tmp/192.168.71.183
{
    "_ansible_facts_gathered": true,
    "ansible_all_ipv4_addresses": [
        "192.168.71.183",
        "172.17.0.1"
    ],
    "ansible_all_ipv6_addresses": [
        "fe80::3872:4f8b:dbfc:1aa2"
    ],
    "ansible_apparmor": {

第二次运行playbook明显要快很多

8.1.7 Facts缓存到redis

  1. 安装redis,启动redis
[root@dbc-server-554 ansible]# yum install redis
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
epel/x86_64/metalink    
...
systemctl start redis
  1. 安装python的redis插件
yum install python-pip
pip install redis==3.4.1

安装redis插件的时候要指定版本,否则会报错,笔者的python版本是2.7.5,redis插件版本为3.4.1:

[root@dbc-server-554 ansible]# pip install redis
Collecting redis
  Downloading https://files.pythonhosted.org/packages/7a/05/671367bb466b3301bc45                                                        43fdad6ac107214ca327c8d97165b30246d87e88/redis-4.4.0.tar.gz (4.5MB)
    100% |████████████████████████████████| 4.5MB 131kB/s
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-build-nEa59A/redis/setup.py", line 21, in <module>
        "redis.commands.graph",
    TypeError: find_packages() got an unexpected keyword argument 'include'

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-nE                                                        a59A/redis/
You are using pip version 8.1.2, however version 22.3.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
  1. 运行playbook,生成缓存文件
ansible-playbook -i hosts checkhosts.yml
  1. 查看、验证
[root@dbc-server-554 ansible]# redis-cli
127.0.0.1:6379> keys *
1) "ansible_facts192.168.71.183"
2) "ansible_cache_keys"
127.0.0.1:6379> get ansible_facts192.168.71.183
"{\n    \"_ansible_facts_gathered\": true, \n    \"ansible_all_ipv4_addresses\": [\n        \"192.168.71.183\", \n        \"172.17.0.1\"\n    ], \n    \"ansible_all_ipv6_addresses\": [\n        \"fe80::3872:4f8b:dbfc:1aa2\"\n    ], \n    \"ansible_apparmor\": {\n        \"status\": \"disabled\"\n    },
...

8.1.8 执行策略(strategy)

  1. 设置并行主机数量,-f 5 指定每次并发5个主机执行。5个主机都执行完毕,结果都返回了再执行下批次的5个主机
# ansible-playbook -i hosts checkhosts.yml -f 5
  1. 配置文件/etc/ansible/ansible.cfg中forks选项用于设置默认并行主机数量
[root@dbc-server-554 ansible]# cat /etc/ansible/ansible.cfg|grep forks
#forks          = 5
  1. 默认执行策略为linear,每个主机的单个task执行完成会等待其他都完成后再执行下个任务,设置free可不等待其他主机,继续往下执行。
[root@dbc-server-554 ansible]# cat /etc/ansible/ansible.cfg|grep strategy
#strategy_plugins   = /usr/share/ansible/plugins/strategy
# by default, ansible will use the 'linear' strategy but you may want to try
strategy = free

自由模式,-f 5 ,如果h4先执行完并返回了,那么h6就会补上,接着h3执行完了,h7也会补上。保证队列是5个,交替切换,一直到执行到最后一个

8.1.9 异步(-B 2 -P2 ,async poll)

ansible 命令一旦执行,进程就会卡住,直到主机执行每个节点的任务返回为止,才能进行下一条命令的执行。执行命令时间过长。

[root@dbc-server-554 ansible]# ansible db -i hosts -m shell -a "sleep 10"
192.168.71.183 | CHANGED | rc=0 >>

需求:放在后台执行,通过一个异步机制得到结果

  1. AD-HOC版本
    参数:
    -B 2 ,表示等待命令2秒,-P 2 ,表示每两秒去查询,直到查询到结果
-B SECONDS, --background SECONDS
                        run asynchronously, failing after X seconds
                        (default=N/A)
-P POLL_INTERVAL, --poll POLL_INTERVAL
                        set the poll interval if using -B (default=15)
[root@dbc-server-554 ansible]# ansible db -i hosts -m shell -a "sleep 5;echo hello"
192.168.71.183 | CHANGED | rc=0 >>
hello
[root@dbc-server-554 ansible]# ansible db -i hosts -m shell -a "sleep 5;echo hello" -B 2 -P 0
192.168.71.183 | CHANGED => {
    "ansible_job_id": "20504692971.71791",
    "changed": true,
    "finished": 0,
    "results_file": "/root/.ansible_async/20504692971.71791",
    "started": 1
}

-B 2 -P 0 , 0表示不去轮询不等待,直接拿到ansible_job_id的值,并且保存结果到/root/.ansible_async/99859864834.20884。 通过job_id获取到stdout_lines

ansible提供了一个模块async_staus,通过这个模块可以去获取结果

[root@dbc-server-554 ansible]# ansible db -i hosts -m async_status -a "jid=20504692971.71791"
192.168.71.183 | CHANGED => {
    "ansible_job_id": "20504692971.71791",
    "changed": true,
    "cmd": "sleep 5;echo hello",
    "delta": "0:00:05.103157",
    "end": "2023-01-06 08:24:59.767410",
    "finished": 1,
    "rc": 0,
    "start": "2023-01-06 08:24:54.664253",
    "stderr": "",
    "stderr_lines": [],
    "stdout": "hello",
    "stdout_lines": [
        "hello"
    ]
}

可得知 “ansible_job_id”: “20504692971.71791”,再写一个获取结果的playbook

[root@dbc-server-554 ansible]# cat getresult.yml
---
- name: get result
  hosts: all
  tasks:
    - name: get job result
      async_status:
        jid: "20504692971.71791"
      register: job_result

    - name: print result
      debug:
        var: job_result
...
[root@dbc-server-554 ansible]# ansible-playbook getresult.yml

PLAY [get result] **********************************************************************************************************************

TASK [get job result] ******************************************************************************************************************
changed: [192.168.71.183]

TASK [print result] ********************************************************************************************************************
ok: [192.168.71.183] => {
    "job_result": {
        "ansible_job_id": "20504692971.71791",
        "changed": true,
        "cmd": "sleep 5;echo hello",
        "delta": "0:00:05.103157",
        "end": "2023-01-06 08:24:59.767410",
        "failed": false,
        "finished": 1,
        "rc": 0,
        "start": "2023-01-06 08:24:54.664253",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "hello",
        "stdout_lines": [
            "hello"
        ]
    }
}

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

以上仅用于效果演示,我们当然不可能只用playbook接收结果
2. playbook版本
在playbook的任务中加入两个参数:async和poll。
async:这个任务执行时间的上限值。即任务执行所用时间如果超出这个时间,则认为任务失败。此参数若未设置,则为同步执行。
poll:任务异步执行时轮询的时间间隔。
async_status:查看轮询结果,ansible还提供了这个模块async_status。
官方给出例子:

----
    hosts: all
    remote_user: root
    tasks:
      - name: simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec
        command: /bin/sleep 15
        async: 45
        poll: 5

这时候已经不怕任务超时了。可以执行一个45s的任务,当然也可以根据需要自己设置。另外,如果poll为0,就相当于一个不关心结果的任务。

打印结果版本:

[root@dbc-server-554 ansible]# cat test2.yml
---
  - hosts: all
    remote_user: root
    tasks:
      - name: simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec
        shell: /bin/sleep 15;echo hello
        async: 45
        poll: 5
        register: async_result

      - name: get result
        async_status: jid={{ async_result.ansible_job_id }}
        register: job_result

      - name: print result
        debug:
          var: job_result
[root@dbc-server-554 ansible]# ansible-playbook test2.yml

PLAY [all] *****************************************************************************************************************************

TASK [simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec] ******************************************************
changed: [192.168.71.183]

TASK [get result] **********************************************************************************************************************
changed: [192.168.71.183]

TASK [print result] ********************************************************************************************************************
ok: [192.168.71.183] => {
    "job_result": {
        "ansible_job_id": "103197155909.77221",
        "changed": true,
        "cmd": "/bin/sleep 15;echo hello",
        "delta": "0:00:15.004831",
        "end": "2023-01-06 08:44:29.357021",
        "failed": false,
        "finished": 1,
        "rc": 0,
        "start": "2023-01-06 08:44:14.352190",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "hello",
        "stdout_lines": [
            "hello"
        ]
    }
}

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

官方示例:

---
    # Requires ansible 1.8+
    - name: 'YUM - fire and forget task'
      yum: name=docker-io state=installed
      async: 1000
      poll: 0
      register: yum_sleeper
 
    - name: 'YUM - check on fire and forget task'
      async_status: jid={{ yum_sleeper.ansible_job_id }}
      register: job_result
      until: job_result.finished
      retries: 30
#第一个job执行异步任务,并且注册了一个名字叫yum_sleeper,用于提供给第二个job作为轮询对象,并且poll设为0,它自己不再轮询。
#第二个job使用async_status模块,进行轮询并返回轮询结果。准备检查30次。结果如下:
 
PLAY [all] *********************************************************************
 
TASK [setup] *******************************************************************
ok: [cloudlab001]
 
TASK [YUM - fire and forget task] **********************************************
ok: [cloudlab001]
 
TASK [YUM - check on fire and forget task] *************************************
FAILED - RETRYING: TASK: YUM - check on fire and forget task (29 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (28 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (27 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (26 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (25 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (24 retries left).
changed: [cloudlab001]
 
PLAY RECAP *********************************************************************
cloudlab001                : ok=3    changed=1    unreachable=0    failed=0

8.1.10 yum安装优化

yum安装多个包时,用这种方式性能最好:

yum:
  name: [tree,vim]

循环这种影响性能:

yum:
  name: "{{ item }}"
  loop: [tree,vim]

8.1.11 使用混合模式的inventory

多个inventory文件,ansible将多个inventory文件合并成一个进行Playbook执行。

  • ansible-playbook -i 1.yml -i 2.yml -i 3.yml
  • 把1~3.yml文件放到inventory目录,直接 -i inventory
  • 还有种方式修改 vim /etc/ansible/ansible.cfg的inventory
    inventory = /root/inventory/

02-static.yml 会覆盖 01-static.yml

# mkdir -p /root/inventory/
# cd /root/inventory
[root@dbc-server-554 inventory]# cat 01-static.yml
[db]
192.168.71.183

[allservers:children]
db

[allservers:vars]
name=shark
[root@dbc-server-554 inventory]# cat 02-static.yml
[db]
192.168.71.183

[allservers:children]
db

[allservers:vars]
name=leo
[root@dbc-server-554 inventory]# ansible all -m debug -a "var=name"
192.168.71.183 | SUCCESS => {
    "name": "leo"
}

如果出现变量重名的情况,最后执行的生效

[root@dbc-server-554 inventory]# cat group/all.yaml
[db]
192.168.71.183

[allservers:children]
db

[allservers:vars]
name=lucy
[root@dbc-server-554 inventory]# ansible all -m debug -a "var=name"
192.168.71.183 | SUCCESS => {
    "name": "lucy"
}

8.1.12 使用inventory脚本

使用脚本去获取资产清单,清单脚本不限制语言

脚本限制条件:
脚本必须接受 --list --host <hostname> 参数
当使用单个 --list参数调用脚本时,脚本必须输出到标准输出,就是输出到终端,其中包含要管理的所有组的JSON编码的哈希或字典
每个组的值应该是包含每个主机列表,任何子组和潜在组变量的哈希或字典,或者仅是主机列表:

{
    "group001": {
        "hosts": ["hoste01", "hoste02"],
        "vars": {
            "var1": true
        },
        "children": ["groupe02"]
    },
    "group002": {
        "hosts": ["host003", "host004"],
        "vars": {
            "var2": 500
        },
        "children": []
    }
}

如果组中的任何元素为空,则可以从输出中将其省略

当使用host <hostname> 参数(其实是上面的主机)进行调用时,脚本必须打印一个空的JSON哈希/字典或含有这个主机变量的哈希/字典,以使其可用于模板和剧本。例如:

{
  "VAR001": "VALUE",
  "VAR002": "VALUE",
}

打印变量是可选的。如果脚本不执行此操作,则应打印一个空的哈希或字典
一个简单的示例

vim get_hosts.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import json
import argparse

def lists():
    dic = {}
    host_list = ['192.168.71.183','192.168.20.3']
    hosts_dict = {'hosts': host_list}
    dic['computes'] = hosts_dict
    return json.dumps(dic,indent=4)  # 返回json格式,字典,每个层级都是4个空格

def hosts(name):
    dic = {'ansible_ssh_pass': 'yurq'}
    return json.dumps(dic)

if __name__ == '__main__':   # if作为执行文件执行的时候,而不是模块导入。
    parser = argparse.ArgumentParser()  # 调用Parser类产生实例
    parser.add_argument('-l','--list',help='host list',action='store_true')  # 固定写法
    parser.add_argument('-H','--host',help='hosts vars')  # 固定写法
    args = vars(parser.parse_args())  # 调用parser模块的处理参数parse_args,会处理前两条添加的参数。 转为一个字典  args = {'host': None,'list': False}

    if args['list']:  # 如果传了list参数,就执行lists()
        print(lists())
    elif args['host']:
        print(hosts(args['host']))
    else:
        parser.print_help()  # 模块的内置方法

执行脚本

[root@dbc-server-554 inventory]# chmod 655 host.py
[root@dbc-server-554 inventory]# ./host.py -l
{
    "computes": {
        "hosts": [
            "192.168.71.183",
            "192.168.20.3"
        ]
    }
}
[root@dbc-server-554 inventory]# ./host.py -h
usage: host.py [-h] [-l] [-H HOST]

optional arguments:
  -h, --help            show this help message and exit
  -l, --list            host list
  -H HOST, --host HOST  hosts vars
[root@dbc-server-554 inventory]# ./host.py -H 192.168.71.183
{"ansible_ssh_pass": "yurq"}
[root@dbc-server-554 inventory]# ansible all -i host.py --list-host
  hosts (2):
    192.168.71.183
    192.168.20.3
[root@dbc-server-554 inventory]# ansible all -i host.py -m shell -a "hostname"
192.168.20.3 | CHANGED | rc=0 >>
gp-server
192.168.71.183 | CHANGED | rc=0 >>
k8s-node-02

将host.py移动到inventory目录下

[root@dbc-server-554 inventory]# cat 01-static.yml |grep 192
192.168.71.199
[root@dbc-server-554 inventory]# ansible all --list-host
  hosts (3):
    192.168.71.183
    192.168.20.3
    192.168.71.199

ansible可以自动执行脚本,获取资产清单

8.1.13 目录结构介绍

使用官方建议的目录结构来组织很多role和playbook文件是个很棒的建议。
假如你用role 封装了playbook,并且任务依赖文件或者依赖其他的任务时,建议使用目录结构管理。
假如是一个简单的独立任务,只使用playbook文件即可,这样会方便我们在其他地方进行引用。
官网