现代 IT 人一定要知道的 Ansible系列教程:Ansiable配置

image-20240107173840916

配置文件

Ansible 中的某些设置可通过配置文件 (ansible.cfg) 进行调整。 库存配置对于大多数用户来说应该足够了,但您可能出于某些原因想要更改它们。

可以在配置文件中进行更改并使用该更改,该文件将按以下顺序搜索:

  • ANSIBLE_CONFIG(如果设置了环境变量)
  • ansible.cfg(在当前目录中)
  • ~/.ansible.cfg(在主目录中)
  • /etc/ansible/ansible.cfg

获取最新配置

如果从软件包管理器安装 Ansible,则最新的 ansible.cfg 文件可能会出现在 /etc/ansible 中 作为 .rpmnew 文件(或其他文件)(视更新情况而定)。

如果您从 pip 或源安装 Ansible,您可能需要创建此文件来覆盖 Ansible 中的默认设置。

您可以生成 Ansible 配置文件ansible.cfg,其中列出了所有默认设置,如下所示:

$ ansible-config init --disabled > ansible.cfg

包含可用插件以创建更完整的 Ansible 配置,如下所示:

$ ansible-config init --disabled -t all > ansible.cfg

更多配置请参考:https://docs.ansible.com/ansible/latest/reference_appendices/config.html#ansible-configuration-settings

构建 Ansiable inventories

Ansible 使用称为清单的列表或列表组自动执行基础架构中的托管节点或“主机”上的任务。可以在命令行传递主机名,但大多数 Ansible 用户都会创建清单文件。清单文件定义了自动化的托管节点,并带有组,以便我们可以同时在多个主机上运行自动化任务。 定义清单后,我们可以使用模式来选择我们希望 Ansible 运行的主机或组。

最简单的清单是包含主机和组列表的单个文件。此文件的默认位置是 /etc/ansible/hosts。 我们可以在命令行中使用 选项指定不同的清单文件,或在配置中使用 指定不同的清单文件。-i <path> inventory

Ansible 库存插件支持多种格式和来源,使我们的库存灵活且可定制。随着我们的库存扩展,可能需要多个文件来组织主机和组。以下是 /etc/ansible/hosts 文件之外的三个选项:

  • 可以创建一个包含多个清单文件的目录。它们可以使用不同的格式(YAML、ini 等)。
  • 可以动态提取库存。例如,您可以使用动态库存插件来列出一个或多个云提供商中的资源。
  • 可以使用多个清单源,包括动态清单和静态文件。

inventories 基础知识

清单将托管节点组织在集中式文件中,为 Ansible 提供系统信息和网络位置。使用清单文件,Ansible 可以通过单个命令管理大量主机。

INI 或 YAML 格式的清单

您可以在 INI 文件或 中创建 YAML 清单。在大多数情况下,例如前面步骤中的示例,对于少量受管节点来说, INI 文件是简单明了且易于阅读的。

随着托管节点数量的增加,以 YAML 格式创建清单成为明智的选择。例如,以下内容等 inventory.ini 效于声明受管节点的唯一名称并使用该 ansible_host 字段:

myhosts:
  hosts:
    my_host_01:
      ansible_host: 192.168.2.129
    my_host_02:
      ansible_host: 192.168.2.130

我们在创建一个目录/root/ansible_quickstart并创建文件 inventory.ini ,将新 [myhosts] 组添加到该文件中 inventory.ini ,并指定每个主机系统的 IP 地址。

[myhosts]                                                                                                     192.168.2.129                                                                                                 192.168.2.130 

使用以下命令来验证 inventory.ini

ansiable-inventory -i inventory.ini --list
root@master:~/ansible_quickstart# ansible-inventory -i inventory.ini --list
{
    "_meta": {
        "hostvars": {}
    },
    "all": {
        "children": [
            "ungrouped",
            "myhosts"
        ]
    },
    "myhosts": {
        "hosts": [
            "192.168.2.129",
            "192.168.2.130"
        ]
    }
}

对清单中的 myhosts 组执行 Ping 操作。

如果控制节点和受管节点上的用户名不同,则通过 ansible 命令传递该 -u 选项。

root@master:~/ansible_quickstart# ansible myhosts -m ping -i inventory.ini 
192.168.2.129 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
192.168.2.130 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}

我们可以看到已经成功建立 inventory 。通过创建 playbook 继续开始使用 Ansible。

上面已经提到过构建清单 inventory 可以使用 ini 格式的文件,同时也是可以使用 yml 文件的。我们可以区分场景使用,如果构建的清单是比较复杂的,那么建议使用 yml文件构建,因为yml文件的语义更强,不过需要以下几点:

  • 确保组名称有意义且唯一。组名称也区分大小写。
  • 在组名称中避免使用空格、连字符和前面的数字(use floor_19 、not 19th_floor )。
  • 根据清单中的主机的内容、位置和时间对主机进行逻辑分组。
  • 根据拓扑对主机进行分组,例如:db、web、leaf、spine。
  • 按地理位置对主机进行分组,例如:数据中心、区域、楼层、建筑物。
  • 按阶段对主机进行分组,例如:开发、测试、暂存、生产。

yml 文件示例:

root@master:~/ansible_quickstart# cat inventory.yml 
myhosts:
  hosts:
    node129:
      ansiable_host: 192.168.2.129
    node130:
      ansiable_host: 192.168.2.130
root@master:~/ansible_quickstart# ansible myhosts -m ping -i inventory.yml 
node130 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
node129 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}

使用 metagroups

创建一个元组,使用以下语法组织清单中的多个组:

metagroupname:
  children:

以下清单说明了数据中心的基本结构。此示例清单包含一个 network 包含所有网络设备的元组和一个包含该 network 组和所有 Web 服务器的 datacenter 元组。

leafs:
  hosts:
    leaf01:
      ansible_host: 192.0.2.100
    leaf02:
      ansible_host: 192.0.2.110

spines:
  hosts:
    spine01:
      ansible_host: 192.0.2.120
    spine02:
      ansible_host: 192.0.2.130

network:
  children:
    leafs:
    spines:

webservers:
  hosts:
    webserver01:
      ansible_host: 192.0.2.140
    webserver02:
      ansible_host: 192.0.2.150

datacenter:
  children:
    network:
    webservers:

以上示例仅仅演示

创建变量

变量设置受管节点的值,例如 IP 地址、操作系统和 SSH 用户以及端口,因此我们在运行 Ansible 命令时无需传递它们。

变量可以应用于特定主机。

webservers:
  hosts:
    webserver01:
      ansible_host: 192.0.2.140
      http_port: 80
    webserver02:
      ansible_host: 192.0.2.150
      http_port: 443

变量还可以应用于组中的所有主机。

webservers:
  hosts:
    webserver01:
      ansible_host: 192.0.2.140
      http_port: 80
    webserver02:
      ansible_host: 192.0.2.150
      http_port: 443
  vars:
    ansible_user: root

Inventory 别名

还可以使用主机变量在清单中定义别名

In INI: 在 INI 中:

jumper ansible_port=5555 ansible_host=192.168.2.129

In YAML: 在 YAML 中:

...
  hosts:
    jumper:
      ansible_port: 5555
      ansible_host: 192.168.2.129

在此示例中,针对主机别名 jumper 运行 Ansible 将连接到端口 5555 上的 192.168.2.129。

将变量分配给多台计算机:组变量

如果组中的所有主机共享一个变量值,则可以一次将该变量应用于整个组。

In INI: 在 INI 中:

[atlanta]
host1
host2

[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com

In YAML: 在 YAML 中:

atlanta:
  hosts:
    host1:
    host2:
  vars:
    ntp_server: ntp.atlanta.example.com
    proxy: proxy.atlanta.example.com

组变量是一次将变量应用于多个主机的便捷方法。但是,在执行之前,Ansible 始终将变量(包括清单变量)展平到主机级别。如果主机是多个组的成员,则 Ansible 会从所有这些组中读取变量值。如果为不同组中的同一变量分配不同的值,Ansible 会根据内部合并规则选择要使用的值。

继承变量值:组的组变量

您可以将变量应用于父组(嵌套组或组组)以及子组。

语法相同: :vars 对于 INI 格式和 vars: YAML 格式:

In INI: 在 INI 中:

[atlanta]
host1
host2

[raleigh]
host2
host3

[southeast:children]
atlanta
raleigh

[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2

[usa:children]
southeast
northeast
southwest
northwest

In YAML: 在 YAML 中:

usa:
  children:
    southeast:
      children:
        atlanta:
          hosts:
            host1:
            host2:
        raleigh:
          hosts:
            host2:
            host3:
      vars:
        some_server: foo.southeast.example.com
        halon_system_timeout: 30
        self_destruct_countdown: 60
        escape_pods: 2
    northeast:
    northwest:
    southwest:

子组的变量将比父组的变量具有更高的优先级(覆盖)

变量如何合并

默认情况下,在运行播放之前,变量会合并/展平到特定主机。这使 Ansible 专注于主机和任务,因此组无法在清单和主机匹配之外生存。默认情况下,Ansible 会覆盖变量,包括为组和/或主机定义的变量(参见 DEFAULT_HASH_BEHAVIOUR)。顺序/优先级为(从低到高):

  • all group
  • parent group
  • child group
  • host

默认情况下,Ansible 会按 ASCII 顺序合并同一父/子级别的组,并且加载的最后一个组中的变量会覆盖前一个组中的变量。例如,将合并 b_groupb_group 匹配的变量将 a_group 覆盖 a_group 中的变量。

可以通过设置组变量 ansible_group_priority 来更改同一级别的组的合并顺序(在解析父/子顺序后)来更改此行为。数字越大,合并时间越晚,优先级越高。此变量默认为 1 if un set。

例如:

a_group:
  vars:
    testvar: a
    ansible_group_priority: 10
b_group:
  vars:
    testvar: b

在此示例中,如果两个组具有相同的优先级,则结果通常为 testvar == b ,但由于我们赋予了 a_group 更高的优先级,因此结果将是 testvar == a

类似的帖子