模式:目标主机和组
当你通过临时命令或运行 playbook 执行 Ansible 时,你必须选择要执行哪些托管节点或组。模式允许你针对清单中的特定主机和/或组运行命令和 playbook。Ansible 模式可以引用单个主机、IP 地址、清单组、一组组或清单中的所有主机。模式非常灵活 - 你可以排除或需要主机的子集,使用通配符或正则表达式等等。Ansible 会对模式中包含的所有清单主机执行操作。
使用模式
你几乎在每次执行临时命令或 playbook 时都会使用模式。模式是临时命令中唯一没有标记的元素。它通常是第二个元素
ansible <pattern> -m <module_name> -a "<module options>"
例如
ansible webservers -m service -a "name=httpd state=restarted"
在 playbook 中,模式是每个 play 的 hosts:
行的内容
- name: <play_name>
hosts: <pattern>
例如
- name: restart webservers
hosts: webservers
由于你通常希望同时对多个主机运行命令或 playbook,因此模式通常引用清单组。上面所示的临时命令和 playbook 都将针对 webservers
组中的所有机器执行。
常用模式
此表列出了用于定位清单主机和组的常用模式。
描述 |
模式 |
目标 |
---|---|---|
所有主机 |
all(或 *) |
|
一台主机 |
host1 |
|
多台主机 |
host1:host2(或 host1,host2) |
|
一个组 |
webservers |
|
多个组 |
webservers:dbservers |
webservers 中的所有主机加上 dbservers 中的所有主机 |
排除组 |
webservers:!atlanta |
webservers 中的所有主机,除了 atlanta 中的主机 |
组的交集 |
webservers:&staging |
webservers 中的任何主机,同时也在 staging 中 |
注意
可以使用逗号 (,
) 或冒号 (:
) 分隔主机列表。在处理范围和 IPv6 地址时,首选逗号。
一旦你了解了基本模式,你就可以将它们组合起来。此示例
webservers:dbservers:&staging:!phoenix
将目标设置为“webservers”和“dbservers”组中的所有机器,这些机器也在“staging”组中,但排除“phoenix”组中的任何机器。
只要主机在你的清单中以 FQDN 或 IP 地址命名,你就可以将通配符模式与 FQDN 或 IP 地址一起使用
192.0.*
*.example.com
*.com
你可以同时混合使用通配符模式和组
one*.com:dbservers
模式的限制
模式依赖于清单。如果清单中未列出主机或组,则无法使用模式将其作为目标。如果你的模式包含清单中未出现的 IP 地址或主机名,你将看到类似这样的错误
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: Could not match supplied host pattern, ignoring: *.not_in_inventory.com
你的模式必须与你的清单语法匹配。如果你将主机定义为别名
atlanta:
hosts:
host1:
http_port: 80
maxRequestsPerChild: 808
ansible_host: 127.0.0.2
你必须在模式中使用该别名。在上面的示例中,你必须在模式中使用 host1
。如果你使用 IP 地址,你将再次收到错误
[WARNING]: Could not match supplied host pattern, ignoring: 127.0.0.2
模式处理顺序
处理方式有点特殊,并且按照以下顺序进行
:
和,
&
!
此位置仅考虑每个操作内部的处理顺序:a:b:&c:!d:!e == &c:a:!d:b:!e == !d:a:!e:&c:b
所有这些都会导致以下结果
主机在/是 (a 或 b) 并且主机在/是 all(c) 并且主机不在/不是 all(d, e)。
现在 a:b:!e:!d:&c
有细微变化,因为 !e
在 !d
之前处理,尽管这没有太大区别
主机在/是 (a 或 b) 并且主机在/是 all(c) 并且主机不在/不是 all(e, d)。
高级模式选项
上面描述的常用模式将满足你的大部分需求,但 Ansible 提供了几种其他方法来定义你想要定位的主机和组。
在模式中使用变量
你可以使用变量来启用使用 -e
参数传递组规范符到 ansible-playbook
webservers:!{{ excluded }}:&{{ required }}
在模式中使用组位置
你可以通过其在组中的位置来定义主机或主机的子集。例如,给定以下组
[webservers]
cobweb
webbing
weber
你可以使用下标在 webservers 组中选择单个主机或范围。
切片特定项目
**操作:**
s[i]
**结果:**
s
的第i-th
个项目,其中索引起点为0
如果 *i* 为负数,则索引相对于序列 *s* 的末尾:len(s) + i
将被替换。但是 -0
为 0
。
webservers[0] # == cobweb
webservers[-1] # == weber
使用起点和终点切片
**操作:**
s[i:j]
**结果:** 从
i
到j
的s
切片
从 *i* 到 *j* 的 *s* 切片定义为索引为 *k* 的项目序列,使得 i <= k <= j
。如果省略 *i*,则使用 0
。如果省略 *j*,则使用 len(s)
。省略 *i* 和 *j* 的切片会导致无效的主机模式。如果 *i* 大于 *j*,则切片为空。如果 *i* 等于 *j*,则替换 *s[i]*。
webservers[0:2] # == webservers[0],webservers[1],webservers[2]
# == cobweb,webbing,weber
webservers[1:2] # == webservers[1],webservers[2]
# == webbing,weber
webservers[1:] # == webbing,weber
webservers[:3] # == cobweb,webbing,weber
在模式中使用正则表达式
可以通过在模式开头使用 ~
将模式指定为正则表达式
~(web|db).*\.example\.com
模式和临时命令
你可以使用命令行选项更改临时命令中定义的模式的行为。你还可以使用 --limit
标记限制特定运行中定位的主机。
限制到一台主机
$ ansible all -m <module> -a "<module options>" --limit "host1"
限制到多台主机
$ ansible all -m <module> -a "<module options>" --limit "host1,host2"
取反限制。请注意,必须使用单引号以防止 bash 插值。
$ ansible all -m <module> -a "<module options>" --limit 'all:!host1'
限制到主机组
$ ansible all -m <module> -a "<module options>" --limit 'group1'
模式和 ansible-playbook 标记
你可以使用命令行选项更改 playbook 中定义的模式的行为。例如,你可以运行一个 playbook,该 playbook 将 hosts: all
定义在单个主机上,方法是指定 -i 127.0.0.2,
(注意尾随逗号)。即使你定位的主机未在你的清单中定义,这也有效,但此方法不会读取你的清单以获取与该主机绑定的变量,并且 playbook 所需的任何变量都需要在命令行手动指定。你还可以使用 --limit
标记限制特定运行中定位的主机,该标记将引用你的清单
ansible-playbook site.yml --limit datacenter2
最后,你可以使用 --limit
从文件读取主机列表,方法是在文件名前面加上 @
ansible-playbook site.yml --limit @retry_hosts.txt
如果 RETRY_FILES_ENABLED 设置为 True
,则在 ansible-playbook
运行后将创建一个 .retry
文件,其中包含来自所有 play 的失败主机列表。每次 ansible-playbook
运行完成后,都会覆盖此文件。
ansible-playbook site.yml --limit @site.retry
要应用您在 Ansible 命令和 playbook 中的模式知识,请阅读 临时命令简介 和 Ansible playbook。
另请参阅
- 临时命令简介
基本命令示例
- 使用 playbook
学习 Ansible 配置管理语言
- 通信
有问题?需要帮助?想分享您的想法?请访问 Ansible 通信指南