模式:目标主机和组

当你通过临时命令或运行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中,模式是每个任务的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

模式处理顺序

处理方式有点特殊,按照以下顺序进行:

  1. :,

  2. &

  3. !

此位置仅考虑每个操作内的处理顺序:a:b:&c:!d:!e == &c:a:!d:b:!e == !d:a:!e:&c:b

所有这些都导致以下结果:

主机位于/属于 (a 或 b) 并且主机位于/属于所有(c) 并且主机不位于/属于所有(d, e)。

现在a:b:!e:!d:&c略有不同,因为!e!d之前处理,但这并没有什么区别。

主机位于/属于 (a 或 b) 并且主机位于/属于所有(c) 并且主机不位于/属于所有(e, d)。

高级模式选项

上面描述的常用模式将满足你的大部分需求,但Ansible提供了其他几种定义要定位的主机和组的方法。

在模式中使用变量

你可以使用变量来启用使用-e参数传递组说明符到ansible-playbook。

webservers:!{{ excluded }}:&{{ required }}

在模式中使用组位置

你可以通过其在组中的位置来定义主机或主机的子集。例如,给定以下组:

[webservers]
cobweb
webbing
weber

你可以使用下标来选择webservers组中的单个主机或范围。

切片特定项目

  • 操作: s[i]

  • 结果: s的第i个项目,其中索引原点为0

如果*i*为负数,则索引相对于序列*s*的末尾:len(s) + i将被替换。但是-00

webservers[0]       # == cobweb
webservers[-1]      # == weber

使用起始点和结束点进行切片

  • 操作: s[i:j]

  • 结果:ijs切片。

从*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标志

您可以使用命令行选项更改在剧本中定义的模式的行为。例如,您可以通过指定-i 127.0.0.2,(注意尾随逗号)在一个主机上运行定义了hosts: all的剧本。即使目标主机未在您的清单中定义,此方法也能正常工作,但此方法**不会**读取与该主机绑定的清单变量,并且剧本所需的任何变量都需要在命令行手动指定。您还可以使用--limit标志限制在特定运行中目标主机,这将引用您的清单。

ansible-playbook site.yml --limit datacenter2

最后,您可以使用--limit通过在文件名前面加上@来从文件中读取主机列表。

ansible-playbook site.yml --limit @retry_hosts.txt

如果RETRY_FILES_ENABLED设置为True,则在ansible-playbook运行后将创建一个.retry文件,其中包含所有剧集中失败的主机列表。每次ansible-playbook运行结束后,此文件都会被覆盖。

ansible-playbook site.yml --limit @site.retry

要将您对 Ansible 命令和剧本中模式的了解应用于实践,请阅读临时命令简介Ansible 剧本

另请参见

临时命令简介

基本命令示例

使用剧本

学习 Ansible 配置管理语言

沟通

有问题?需要帮助?想分享您的想法?请访问 Ansible 沟通指南