模式:定位主机和组

当您通过 ad-hoc 命令或运行 playbook 执行 Ansible 时,您必须选择要执行的管理节点或组。模式可以让您对清单中的特定主机和/或组运行命令和 playbook。Ansible 模式可以引用单个主机、IP 地址、清单组、一组组或清单中的所有主机。模式非常灵活 - 您可以在排除或要求主机子集、使用通配符或正则表达式等方面。Ansible 在模式中包含的所有清单主机上执行。

使用模式

您几乎在每次执行 ad-hoc 命令或 playbook 时都会使用模式。模式是 ad-hoc 命令 的唯一没有标志的元素,它通常是第二个元素

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,因此模式通常会引用清单组。上面的 ad-hoc 命令和 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

模式和 ad-hoc 命令

您可以使用命令行选项更改在 ad-hoc 命令中定义的模式的行为。您还可以使用 --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 通信指南