Ansible系列(5):Inventory介绍,如何管理主机组
这是Ansible系列课程第五节,Ansible Inventory介绍。介绍一下Inventory是什么,以及如何管理主机组。
该系列课程前后章节都是有关联性的,对于初学者建议按顺序阅读。也可以选择特定的章节了解单个知识点。
Ansible可以远程操作一台或一组主机,这些主机的清单是在称为inventory的文件中配置的。默认的inventory文件是/etc/ansible/hosts,也可以在命令行中通过参数-i来指定其他路径下的inventory文件,或者从其他系统中动态获取相同格式的清单,比如CMDB。
Inventory文件示例
inventory文件有INI和YAML两种格式,建议INI格式。一个基本的inventory文件内容如下:
mail.example.com #单个主机地址
[webservers] #主机组, []内为组名
foo.example.com http_port=80 maxRequests=30 #定义主机变量
bar.example.com ansible_connection=ssh ansible_user=myuser #指定连接信息
[dbservers]
db-[1:5].example.com #定义1-5范围的主机
bar-[a:f].example.com #定义a-f范围的主机
[all:vars] #定义全局变量
ansible_ssh_private_key_file=/root/.ssh/id_rsa
ansible_ssh_port=22
ansible_ssh_user=root
[dbservers:vars] #定义dbservers组的变量
mysql_port=3806
[server:children] #定义server组的子成员
webservers
dbservers
上面对文件配置做个介绍:
主机可以单独配置、可以属于一个或多个主机组
主机组定义的格式是:[groupname],如:[webservers],[dbservers]
主机组变量定义的格式是:[groupname:vars],如:[webservers:vars],[all:vars]
主机组嵌套定义的格式是:[parentgroup:children],如:[server:children]
自定义主机变量定义格式:如:foo.example.com http_port=80 maxRequests=30
内置主机变量定义格式:如:bar.example.com ansible_connection=ssh ansible_user=myuser
默认组
在inventory中,有2个默认组:all和ungrouped。
all:包含所有的主机
ungrouped:包含不属于组的主机
尽管all和ungrouped永远存在,但他们是隐式的,不会出现在任何组列表中。
多组共存
为了满足不同的场景,会定义不同的组名,比如:
What:是什么,应用程序、数据库还是缓存。
Where:在哪里,哪个数据中心或者区域,如Beijing,ShangHai
When:开发阶段,开发环境、测试环境、生产环境
每个主机也可能会同时属于多个组,如下面inventory所示,foo.example.com同时属于webservers和east,one.example.com同时属于dbservers和east等。
mail.example.com
[webservers]
foo.example.com
bar.example.com
[dbservers]
one.example.com
two.example.com
three.example.com
[east]
foo.example.com
one.example.com
[west]
bar.example.com
three.example.com
[prod:children]
east
[test:children]
west
Inventory中的变量
我们可以在Inventory文件中指定特定主机或特定组相关的变量,这些在前面的示例中也有说明。但随着inventory中管理的节点越来越多,也可以通过变量文件的方式有效管理。
主机变量
添加主机变量很简单,直接在主机后面添加key=value键值对,如下所示:
[webservers]
foo.example.com http_port=80 maxRequests=30
bar.example.com ansible_connection=ssh ansible_user=myuser
另外,也可以直接给主机起个别名,在后续playbook中直接使用别名即可,使用别名的主机,需要指定ansible_host参数。
jumper ansible_port=5555 ansible_host=192.0.2.50
组变量
如果组里的所有主机都需要相同的变量值,可以将变量添加到组上,格式如下:
[dbservers]
db-[1:5].example.com
bar-[a:f].example.com
[dbservers:vars]
mysql_port=3806
组变量是一种可以将变量同时应用到多个主机的方法。但是,在执行之前,Ansible需要将变量展平到host级别。如果一个主机同时属于多个组,如果为不同组中的同一个变量指定了不同的值,该按什么规则选择呢?在后面变量优先级部分会介绍。
嵌套组变量
inventory文件中对组的管理非常灵活,可以将多个组在封装成一个新组,可以对这个新组指定变量。
[webservers]
foo.example.com
bar.example.com
[dbservers]
db-[1:5].example.com
bar-[a:f].example.com
[server:children] #利用已有的组封装成新的组
webservers
dbservers
[server:vars] #嵌套组变量
connect_timeout=30
变量文件
虽然在Inventory文件中可以指定变量,但如果变量多了管理成本会很高,也会很混乱。Ansible中可以通过变量文件来管理组变量或主机变量,文件内容也是YAML语法。
Ansible通过搜索相对于inventory和playbook文件的路径来加载host和group变量文件。假如:在/etc/ansible/hosts的inventory文件中包含一个名为foo.example.com的主机,分别属于webservers和dbservers两个组,那么该主机将从以下位置获取变量:
/etc/ansible/group_vars/dbservers
/etc/ansible/group_vars/webservers
/etc/ansible/host_vars/foo.example.com
文件的格式如下:
---
ntp_server: acme.example.org
database_server: storage.example.org
有可以在playbook目录下添加group_vars/和host_vars/目录,ansible-playbook命令默认会从当前工作目录下查找这些目录。但其他的ansible命令只会从inventory目录下查找group_vars和host_vars,如ansible,ansible-console。如果要想让这些命令也能从playbook目录下查找,需要在命令行提供--playbook-dir参数。如果想从playbook和inventory这两个地方加载变量,那么playbook目录下的变量会覆盖inventory目录下的变量。
变量的优先级
默认情况下,在任务执行之前,所有的变量都会进行合并和铺平然后应用到特定的host上,这就涉及到如果从多个数据源获取变量,那么变量的优先级是什么样的。
由低到高的顺序:
默认情况下,ansible在同一级别按照字母的顺序进行合并,后面加载的组覆盖之前加载的组。比如,a_group和b_group进行合并,那么b_group组的变量将覆盖a_group中的变量。
多源Inventory
在Ansible的最佳实践中,建议按不同的环境划分inventory文件,如果有个任务想同时在不同的环境中执行,这个时候就可以指定多个inventory文件,格式如下:
$ansible-playbookget_logs.yml-istaging-iproduction
当这两个inventory文件中存在相同的变量时,也是按上面的优先级进行取舍。如:staging中变量a=1,production中a=2,那么按上面的命令,合并后的结果是a=2,如果想让a=1,需要改变传入的顺序。
$ansible-playbookget_logs.yml-iproduction-istaging
主机内置变量清单
下面是ansible内置的变量清单,可以收藏备用。
主机连接配置
ansible_connection:与主机的连接类型。可以是ansible的连接插件的名称。SSH协议类型为smart、ssh或paramiko。默认值是smart。
所有连接配置
ansible_host:要连接到远程主机的名称。
ansible_port:要连接到远程主机的端口,默认为22。
ansible_user:连接到远程主机的用户名。
ansible_password:连接到远程主机的用户名密码。
SSH连接配置
ansible_ssh_private_key_file:ssh使用的私有文件,适用于有多个秘钥,但不想使用ssh agent情况。
ansible_ssh_common_args:该设置附加到默认的sftp、scp和ssh命令行上。
ansible_sftp_extra_args:该设置总是附加到默认的sftp命令行上。
ansible_scp_extra_args:该设置总是附加到默认的scp命令行上。
ansible_ssh_extra_args:该设置总是附加到默认的ssh命令行上。
ansible_ssh_pipelining:确定是否使用SSH pipelining,该参数会覆盖ansible.cfg中的pipelining设置。
ansible_ssh_executable:此设置会覆盖使用系统ssh的默认行为,会覆盖ansible.cfg中的ssh_executable参数。
特权提升配置
ansible_become:允许特权升级,等同于ansible_sudo、ansible_su。
ansible_become_method:设置特权提升的方法,比如sudo。
ansible_become_user:设置特权提升的用户,等同于ansible_sudo_user,`ansible_su_user
ansible_become_password:设置特权用户的密码,等同于ansible_sudo_password,ansible_su_password
ansible_become_exe:设置提权方法所用的可执行文件,等同于ansible_sudo_exe,ansible_su_exe
ansible_become_flags:设置提权方法所用的参数,等同于ansible_sudo_flags,ansible_su_flags
远程主机环境配置
ansible_shell_type:目标系统的shell类型.默认情况下,命令的执行使用 'sh' 语法,可设置为 'csh' 或 'fish'。
ansible_python_interpreter:目标主机的 python 路径.适用于的情况: 系统中有多个 Python, 或者命令路径不是"/usr/bin/python",比如 *BSD, 或者 /usr/bin/python。
ansible_*_interpreter:这里的"*"可以是 ruby 或 perl 或其他语言的解释器,作用和ansible_python_interpreter 类似。
ansible_shell_executable:这将设置ansible控制器将在目标机器上使用的shell,覆盖ansible.cfg中的配置,默认为/bin/sh。
总结
这篇文章主要介绍了inventory文件以及inventory中涉及的group变量和host变量的设置。inventory文件在Ansible中是非常重要的一个组件,如何更有效、合理的管理主机,对于ansible的任务执行有很大帮助。