Inventory和Patterns
知识文档:
Host Inventory
Host Inventory 配置文件:默认文件/etc/ansible/hosts,用来告诉Ansible需要管理哪些主机。并且把这些主机根据按需分类。
可以根据用途分类:数据库节点,服务节点等;根据地点分类:中部,西部机房。
Ansible可以同时操作属于一个组的多台主机,组和主机之间的关系通过 inventory 文件配置。
远程主机和组
简单分组:
方括号[]
中是组名,用于对组进行系统分类,便于对不同系统进行分开的管理
1 | mail.example.com |
一组相似的 hostname简写方法:
1 | [webservers] |
SSH端口不是22的表示方法:
1 | badwolf.example.com:5309 |
单个主机设置别名方式:
1 | jumper ansible_ssh_port=5555 ansible_ssh_host=192.168.1.50 |
在这个例子中,通过 “jumper” 别名,会连接 192.168.1.50:5555
(这是通过 inventory 文件的特性功能设置的变量。一般而言,这不是设置变量(描述你的系统策略的变量)的最好方式)
远程主机的连接参数和变量
参数
指定Server的连接参数,其中包括连接方法,用户等。
1 | [targets] |
可以指定的参数参考:docs.ansible.com
为一个组指定变量:
1 | [atlanta] |
把一个组作为另一个组的子成员
可以把一个组作为另一个组的子成员,以及分配变量给整个组使用,例:
分组usa的子组还可以是其它的组,例如[usa:children]中还可以包含子组southeast, [southeast:children]中还可以包含atlanta和releigh
1 | [atlanta] |
按目录结构 组织Host和Group变量(more)
在 inventory 主文件中保存所有的变量并不是最佳的方式.还可以保存在独立的文件中,这些独立文件与 inventory 文件保持关联. 不同于 inventory 文件(INI 格式),这些独立文件的格式为 YAML.详见 YAML 语法 .
假设 inventory 文件的路径为:
1 | /etc/ansible/hosts |
假设有一个主机名为 ‘foosball’, 主机同时属于两个组,组的名字分别是 ‘raleigh’和 ‘webservers’.
那么以下组变量的配置文件中的变量可以被 ‘foosball’ 主机所用.
下面依次为 ‘raleigh’ 的组变量,’webservers’ 的组变量,’foosball’ 的主机变量 的配置文件:
1 | /etc/ansible/group_vars/raleigh # an optionally end in '.yml', '.yaml', or '.json |
举例来说,假设你有一些主机,属于不同的数据中心,并依次进行划分.每一个数据中心使用一些不同的服务器.比如 ntp 服务器, database 服务器等等. 那么 ‘raleigh’ 这个组的组变量定义在文件 ‘/etc/ansible/group_vars/raleigh’ 之中,可能类似这样:
1 | --- |
这些定义变量的文件不是一定要存在,因为这是可选的特性.
还有更进一步的运用,你可以为一个主机,或一个组,创建一个目录,目录名就是主机名或组名.目录中的可以创建多个文件, 文件中的变量都会被读取为主机或组的变量.如下 ‘raleigh’ 组对应于 /etc/ansible/group_vars/raleigh/ 目录,其下有两个文件 db_settings 和 cluster_settings, 其中分别设置不同的变量:
1 | /etc/ansible/group_vars/raleigh/db_settings |
‘raleigh’ 组下的所有主机,都可以使用 ‘raleigh’ 组的变量.当变量变得太多时,分文件定义变量更方便我们进行管理和组织. 还有一个方式也可参考,详见 Ansible Vault 关于组变量的部分. 注意,分文件定义变量的方式只适用于 Ansible 1.4 及以上版本.
Tip: Ansible 1.2 及以上的版本中,group_vars/ 和 host_vars/ 目录可放在 inventory 目录下,或是 playbook 目录下. 如果两个目录下都存在,那么 playbook 目录下的配置会覆盖 inventory 目录的配置.
Tip: 把你的 inventory 文件 和 变量 放入 git repo 中,以便跟踪他们的更新,这是一种非常推荐的方式.
Inventory 参数的说明
如同前面提到的,通过设置下面的参数,可以控制 ansible 与远程主机的交互方式,其中一些我们已经讲到过:
1 | ansible_ssh_host |
一个主机文件的例子:
1 | some_host ansible_ssh_port=2222 ansible_ssh_user=manager |
Patterns匹配
如何使用Patterns匹配主机或组
首先要知道,我们使用ansible执行任务的两种方法:
- Ad-Hoc:执行一个单行命令,适合于运行单个任务。
- Playbook:
每个playbook 由一个或多个play
组成,它的内容是一个以 plays` 为元素的列表。
在 play 之中,一组机器被映射为定义好的角色.在 ansible中,play 的内容被称为 tasks,即任务。在基本层次的应用中,一个任务是一个对 ansible 模块的调用。
Ansible中的Patterns决定了我们执行任务可以匹配到哪些主机,意思是与哪些主机进行交互。
Ad-Hoc
命令格式如下:
1 | ansible <pattern_goes_here> -m <module_name> -a <arguments> |
使用示例:
1 | ansible webservers -m service -a "name=httpd state=restarted" |
一个pattern通常关联到一系列组(主机的集合) ,如上示例中,所有的主机均在 “webservers” 组中.
不管怎么样,在使用Ansible前,我们需事先告诉Ansible哪台机器将被执行. 能这样做的前提是需要预先定义唯一的 host names 或者 主机组.
匹配所有的主机
1 | all |
精确匹配
可以写IP地址或系列主机名:
1 | one.example.com |
或匹配
Patterns 表示匹配的主机在web组或db组中
1 | web:db |
非模式匹配
命令下需转义特殊符号,以下Patterns 表示匹配的主机在web组,不在db组中,包含在web组,又在db中的用户
1 | web:\!db |
交集匹配
以下Patterns 表示匹配的主机同时在db组和dbservers组中
1 | web:&db |
通配符匹配
*表示所有字符,[0]表示组第一个成员,[0:25] 表示组第1个到第24个成员,类似python中得切片
1 | web-*.com:dbserver |
正则表达式匹配
在开头的地方使用“~”,表示这是一个正则表达式
1 | ~(web|db).*\.example\.com |
组合匹配
在webservers 或者dbservers 组中,必须还存在于staging 组中,但是不在phoenix 组中
1 | webservers:dbservers:&staging:!phoenix |
上面这个例子表示“‘webservers’ 和 ‘dbservers’ 两个组中隶属于 ‘staging’ 组并且不属于 ‘phoenix’ 组的机器才执行命令” … 哟!唷! 好烧脑的说!
ansible-playbook
在ansible-palybook 命令中,你也可以使用变量来组成这样的表达式,但是你必须使用“-e”的选项来指定这个表达式
1 | webservers:!{{excluded}}:&{{required}} |
通过 –limit 标记来添加排除条件
只对 “–limit” 后的主机或组 执行剧本
1 | ansible-playbook site.yml --limit datacenter2 |
如果你想从文件读取hosts,文件名以@为前缀即可.从Ansible 1.2开始支持该功能:
1 | ansible-playbook site.yml --limit @retry_hosts.txt |
1 | # 此时使用认证方式依然使用 Inventory hosts文件中的ssh密码,retry_hosts.txt 中只包含节点ip |