Ansible 可同时操作属于一个组的多台主机,组和主机之间的关系通过 inventory 文件配置. 默认的文件路径为 /etc/ansible/hosts。
除默认文件外,还可以同时使用多个 inventory 文件,也可以从动态源,或云上拉取 inventory 配置信息。
4.1 静态Inventory文件
静态Inventory指的是在文件/etc/ansible/hosts中指定的主机和组,其格式类似于Windows的ini配置文件。如:
[webservers]
foo.example.com
bar.example.com
[dbservers]
one.example.com
two.example.com
three.example.com
- 方括号[]中是组名,用于对主机进行分类,便于对不同类别进行分别管理。
- 一个主机可以属于不同的组。如果有主机的SSH端口不是标准的22端口,可以在主机名之后加上端口号,用冒号分割。如:
badwolf.example.com:5309
- 假设你有一些静态IP地址,希望设置一些别名,但不是在系统的 host 文件中设置,又或者你是通过隧道在连接,那么可以设置如下:
jumper ansible_ssh_port=5555 ansible_ssh_host=192.168.1.50
- 一组相似的 hostname , 可简写如下:
[webservers] www[01:50].example.com 或者 [webservers] 10.152.35.[100:110]
4.1.1 主机变量
分配变量给主机,只需要将变量定义在主机的host之后,就可在 playbooks 中使用。如:
[atlanta] host1 http_port=80 maxRequestsPerChild=808 host2 http_port=303 maxRequestsPerChild=909
4.1.2 组变量
也可以定义属于整个组的变量:
[atlanta] host1 host2 [atlanta:vars] ntp_server=ntp.atlanta.example.com proxy=proxy.atlanta.example.com
4.1.3 把一个组作为另一个组的子成员
可以把一个组作为另一个组的子成员,以及分配变量给整个组使用。这些变量可以给 /usr/bin/ansible-playbook 使用,但不能给 /usr/bin/ansible 使用:
[atlanta] host1 host2 [raleigh] host2 host3 [southeast:children] atlanta raleigh [southeast:vars] some_server=foo.southeast.example.com halon_system_timeout=30 self_destruct_countdown=60 escape_pods=2
这里,southeast有两个子成员atlanta和raleigh,这样southeast组里面的变量,可以给子成员使用。
4.1.4 分文件定义 Host 和 Group 变量
在 inventory 主文件中保存所有的变量并不是最佳的方式。还可以保存在独立的文件中,这些独立文件与 inventory 文件保持关联。
假设在inventory文件中有一个主机名为 ‘foosball,主机同时属于两个组,一个是 ‘raleigh’,另一个是 ‘webservers’:
[raleigh]
foosball
[webservers]
foosball
那么以下配置文件(YAML 格式)中的变量可以为 ‘foosball’ 主机所用。依次为 ‘raleigh’ 的组变量,’webservers’ 的组变量,’foosball’ 的主机变量:
/etc/ansible/group_vars/raleigh /etc/ansible/group_vars/webservers /etc/ansible/host_vars/foosball
优先级最高的是host_vars中定义的变量,其次组的变量是根据组的名字排序来进行优先级排序的,组名称靠后的优先级高。
4.1.5 Inventory 参数的说明
通过设置下面的参数,可以控制 ansible 与远程主机的交互方式:
1)ansible_ssh_host
将要连接的远程主机名.与你想要设定的主机的别名不同的话,可通过此变量设置。
2)ansible_ssh_port
ssh端口号.如果不是默认的端口号,通过此变量设置.
3)ansible_ssh_user
默认的 ssh 用户名
4)ansible_ssh_pass
ssh 密码(这种方式并不安全,我们强烈建议使用 --ask-pass 或 SSH 密钥)
5)ansible_sudo_pass
sudo 密码(这种方式并不安全,我们强烈建议使用 --ask-sudo-pass)
6)ansible_sudo_exe (new in version 1.8)
sudo 命令路径(适用于1.8及以上版本)
7)ansible_connection
与主机的连接类型.比如:local, ssh 或者 paramiko. Ansible 1.2 以前默认使用 paramiko.1.2 以后默认使用 'smart','smart' 方式会根据是否支持 ControlPersist, 来判断'ssh' 方式是否可行.
8)ansible_ssh_private_key_file
ssh 使用的私钥文件.适用于有多个密钥,而你不想使用 SSH 代理的情况.
9)ansible_shell_type
目标系统的shell类型.默认情况下,命令的执行使用 'sh' 语法,可设置为 'csh' 或 'fish'.
10)ansible_python_interpreter
目标主机的 python 路径.适用于的情况: 系统中有多个 Python, 或者命令路径不是"/usr/bin/python",比如/usr/bin/python
不是 2.X 版本的 Python.我们不使用 "/usr/bin/env" 机制,因为这要求远程用户的路径设置正确,且要求 "python" 可执行程序名不可为 python以外的名字(实际有可能名为python26).
与 ansible_python_interpreter 的工作方式相同,可设定如 ruby 或 perl 的路径....
4.2 动态inventory
Dynamic Inventory指通过外部脚本获取主机列表,并按照ansible 所要求的格式返回给ansilbe命令的。
这部分一般会结合CMDB资管系统、zabbix 监控系统、crobble安装系统、云计算平台等获取主机信息。由于主机资源一般会动态的进行增减,而这些系统一般会智能更新。我们可以通过这些工具提供的API 或者接入库查询等方式返回主机列表。
4.2.1最简单示例
由于Ansible在接受脚本动态获取主机信息时支持的是json格式,这里直接通过一段代码打印一个段json格式的主机信息:
#!/usr/bin/env python # coding=utf-8 import json host1ip = ['10.212.52.252', '10.212.52.14'] host2ip = ['10.212.52.16'] group1 = 'test1' group2 = 'test2' hostdata = {group1: {"hosts": host1ip}, group2: {"hosts": host2ip} } print json.dumps(hostdata, indent=4)
注:
- 主机部分必须是列表格式的;
- hostdata行,其中的"hosts" 部分可以省略,但如果使用时,必须是"hosts" ,不能是其他如‘‘hostlist’’ 等字符串。
- 脚本中一定要加上解释器,如 #!/usr/bin/python #!/bin/bash
省略后可以这样写:
hostdata = {group1:host1ip, group2:host2ip}
直接执行该段代码结果如下:
上面定义了两个主机组,test1组内包含主机10.212.52.252、10.212.52.14,test2组内包含主机10.212.52.16 。ansible可以通过如下方法调用:
4.2.2 复杂示例
在静态主机配置文件示例中,会有组变量(vars),组之间的包含,如下图:
如果以上部分想要通过脚本获取实现,实现后返回的json格式应该如下图:
像上面这种复杂的返回格式,一般不会用在ad-hoc环境中,多数会用在ansible-playbook 中,应为playbook文件中有时假会涉及到vars 参数的传参。
4.2.3其他
- ansible -i 参数后调用的脚本并非一定是py文件,也可以是其他脚本输出的结果,这里做了个简单的测试:
- -i 参数指定的脚本需要有可执行权限 ,不然会报错,如下:
[root@361way.com yaml]# ansible -i hostjson.py AA -a 'uptime' ERROR: The file hostjson.py looks like it should be an executable inventory script, but is not marked executable. Perhaps you want to correct this with `chmod +x hostjson.py`?
4.2.4 _meta
如果inventory脚本返回的顶级元素为”_meta”,它可能会返回所有主机的变量,其可以包含一个名为”hostvars”的value,表示每个主机的变量。字典_meta中定义的是主机变量,如:
主机变量并不是Inventory文件中所必需的,所以_meta字典也不是必须生成的。当Inventory脚本中生成_meta字典时,Ansible会将_meta信息存放在缓存中,当任务中需要调用这些主机变量时,会直接从缓存中读取,而不是调用一次变量就执行一次Inventory脚本。这就大大提高了运行效率。