乐趣区

细说Ansible主机清单inventory

Ansible 是一个系列文章,我会尽量以通俗易懂、诙谐幽默的总结方式给大家呈现这些枯燥的知识点,让学习变的有趣一些。

前言

关于 Ansible 是什么,我在之前的文章中没有说;当然了,我这里也不会说。当你看到我写的这篇文章时,我想你已经知道了 Ansible 是什么了,如果您还不知道什么是 Ansible 是什么,那我的建议是先去百度一下,知道了 Ansible 是什么了,知道了 Ansible 能干什么了以后,再回过头来继续阅读我这里的总结。

在 Ansible 中,有两个非常重要的概念,就是管理主机和被管理远程主机。

  • 管理主机:就是管理远程主机的主机;说简单点,就是安装 Ansible 整套软件的主机;所有的 Ansible 管理命令都是从这台管理主机发出的,通过这台管理主机,从而实现对其它远程主机的管理;
  • 被管理远程主机:顾名思义,就是执行具体动作的主机;Ansible 管理主机下达的命令,最终都要到被管理远程主机上去落地执行。

上面也说了,管理主机就是安装 Ansible 的主机,那被管理远程主机的信息又在哪里配置呢?下面就细说这个被管理远程主机在 Ansible 中的全套配置和流程。

inventory 简介

inventory,也就是主机清单。在大规模的配置管理工作中,特别是云服务提供商或者 IDC 厂家,需要管理不同业务的不同机器,这些机器的信息都存放在 Ansible 的 inventory 组件里面。在我们使用 Ansible 进行远程主机管理时,必须先将主机信息存放在 inventory 里面,这样才能使用 Ansible 对它进行操作。默认情况下,Ansible 的 inventory 是一个静态的 INI 格式的文件,在上一篇《Ansible 配置文件 ansible.cfg 详解》中说到了 defaults 配置中的 inventory 选项,这个 inventory 选项就是配置 inventory 文件的地方。当然了,我们还可以通过 ANSIBLE_HOSTS 环境变量指定或者运行 ansible 和 ansible-playbook 的时候用 -i 参数临时设置。

定义主机和主机组

先来看个我在测试环境使用的 inventory 文件内容。

192.168.1.2
192.168.1.4

[web]
192.168.1.2
192.168.1.4

[mysql-db]
192.168.1.5
192.168.1.6

[east:children]
web
mysql-db

上述就是我的一个简单配置,将来你在生产环境配置 inventory 的话,大抵上也就是这个样子。下面我们分别细说一下上面的这个 inventory 配置文件。

  • 前两行我们定义了两个单独的主机,对于单个主机,我们可以针对单个主机进行配置,包括变量等;
  • [web][mysql-db] 是我们定义的两个主机组;我们可以根据业务、地理位置等因素,对主机进行按组划分,这样方便统一批量管理;
  • [east:children]是我们定义的一个包含其它组的组;分组是支持嵌套的,这样就更加方便了分组的管理。

定义了主机或主机组以后,我们就可以直接在命令中使用这些主机或主机组,比如这样:

ansible 192.168.1.2 -m ping
ansible web -m ping
ansible east -m ping

定义 inventory 列表

默认情况下,Ansible 的 inventory 文件是一个 INI 的静态文件,其实 Ansible 还支持多个 inventory 文件,这样我们就可以非常方便的管理不同业务或者不同环境的机器了。

要定义 inventory 列表,我们先新建一个存放 inventory 文件的文件夹,然后将 ansible.cfg 配置文件中 inventory 的值修改为这个新建的文件夹的路径。比如我在测试环境新建了一个名为 inventory 文件夹来存放 inventory 配置文件。

使用 tree /home/jelly/ansible/inventory 命令输出结果如下:

/home/jelly/ansible/inventory/
|---web
|---db

在这里,我分别定义了两个 inventory 配置文件,其中 web 文件中的内容如下:

[web]
192.168.1.2
192.168.1.4

其中 db 文件中的内容如下:

[mysql-db]
192.168.1.5
192.168.1.6

接下来,我们就可以正常使用这些 inventory 中的主机配置信息了,比如可以用以下命令来看看分组下的主机进行配置验证:

ansible mysql-db --list-hosts

以后我们就可以使用这种方式来搞定 inventory 的配置了,当然了,对于管理主机少,配置简单的环境,使用这种方式完全是没有问题的。但是对于上千台、上万台的主机,很显然这种方式就大大不方便了,太落后了。对于这种上千台、上万台的主机的环境,我们就需要动态的从 CMDB 中拉去主机配置信息了,此时就要说到下面的动态 inventory 了。

动态 inventory

上面也说到了,对于那些云服务提供商或者 IDC 厂家会有大量的主机列表;如果手动维护这些列表将是一个非常繁琐的事情。其实 Ansible 是支持动态的 inventory 的,动态 inventory 就是 Ansible 所有的 inventory 文件里面的主机列表和变量信息都是从外部拉取的。比如我们可以从 CMDB 系统和 Zabbix 监控系统拉取所有的主机信息,然后使用 Ansible 进行管理。这样一来我们就可以很方便的将 Ansible 与其它运维系统结合起来。关于引用动态 inventory 的功能配置起来是非常简单的;我们只需要把 ansible.cfg 文件中 inventory 的定义值改成一个执行脚本即可。这个脚本的内容不受任何编程语言限制,但是这个脚本使用参数时有一定的规范并且对脚本执行的结果也有要求。这个脚本需要支持两个参数:

  • --list或者-l:这个参数运行后会显示所有的主机以及主机组的信息(JSON 格式);
  • --host或者-H:这个参数后面需要指定一个 host,运行结果会返回这台主机的所有信息(包括认证信息、主机变量等),也是 JSON 格式。

下面就是我写的一个通过 Python 脚本动态获取主机列表和主机信息的脚本,由于脚本是用来演示的,所以没有从数据库中获取主机列表和主机配置信息,在实际开发中,我们可以修改为从数据库获取对应的数据:

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import argparse
import json

def lists():
    r = {}
    h = ['192.168.1.2', '192.168.1.4']
    hosts = {'hosts':h}
    r['web'] = hosts
    return json.dumps(r, indent=4)

def hosts(name):
    r = {'ansible_ssh_user':'jelly', 'ansible_ssh_pass':'123456'}
    return json.dumps(r)

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-l', '--list', help='hosts list', action='store_true')
    parser.add_argument('-H', '--host', help='hosts vars')
    args = vars(parser.parse_args())

    if args['list']:
        print(lists())
    elif args['host']:
        print(hosts(args['host']))
    else:
        parser.print_help()

接下来,我们先不修改 ansible.cfg 中的 inventory 配置,直接在命令行指定配置文件进行运行:

ansible -i inventoryDemo.py web -m ping

输出结果如下:

192.168.1.2 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
192.168.1.4 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

在生产环境,我们需要将 ansible.cfg 中的 inventory 配置指定为这个 python 脚本的路径,后续正常执行各个 ansible 命令即可,比如这样:

ansible web -m ping

inventory 内置参数

Ansible inventory 中可以配置很多内置的一些参数,这些参数在我们实际工作中非常有用,我们可以直接在 inventory 文件中定义它,也可以在动态的 inventory 中使用它们。这里对这些常用 inventory 内置参数进行一下简单的总结:

参数名 参数说明
ansible_ssh_host 定义主机的 ssh 地址
ansible_ssh_port 定义主机的 ssh 端口
ansible_ssh_user 定义主机的 ssh 认证用户
ansible_ssh_pass 定义主机的 ssh 认证密码
ansible_sudo 定义主机的 sudo 用户
ansible_sudo_pass 定义主机的 sudo 密码
ansible_sudo_exe 定义主机的 sudo 路径
ansible_connection 定义主机连接方式;与主机的连接类型. 比如:local,ssh 或者 paramiko;Ansible 1.2 以前默认使用 paramiko。1.2 以后的版本默认使用‘smart’,‘smart’方式会根据是否支持 ControlPersist,来判断 ssh 方式是否可行
ansible_ssh_private_key_file 定义主机私钥文件
ansible_shell_type 定义主机 shell 类型
ansible_python_interpreter 定义主机 python 解释器路径

总结

inventory 是 ansible 中一个非常重要的概念,只有完全掌握了 inventory 的配置,我们才会知道我们需要对哪些主机做哪些事。希望我这里对 inventory 的总结能够更好的帮助你理解 inventory。因为 inventory 是如此的重要,所以在后续的文章中,我还会总结到 inventory 的一些其它用法。最后,如果觉的还不错,可以点击下方的“打赏”哦。

2019 年 6 月 16 日,于内蒙古呼和浩特。


从最基础的编程语法,到高深的编程技巧;从最简单的学习计划,到长远的职业规划;果冻想分享的不仅仅是一篇文章,更多的是对编程的挚爱和执着,对人生的享受和理解;不管你是 IT 菜鸟,还是编程老手,“果冻想”都值得你关注。

退出移动版