使用动态清单

如果您的 Ansible 清单随着时间的推移而波动,主机会根据业务需求启动和关闭,那么如何构建清单中描述的静态清单解决方案将无法满足您的需求。您可能需要从多个来源跟踪主机:云提供商、LDAP、Cobbler和/或企业 CMDB 系统。

Ansible 通过动态外部清单系统集成了所有这些选项。Ansible 支持两种连接外部清单的方式: 清单插件清单脚本

Inventory 插件利用 Ansible 核心代码的最新更新。我们建议使用插件而不是脚本来进行动态库存。您可以编写自己的插件来连接到其他动态库存源。

如果您愿意,您仍然可以使用清单脚本。当我们实现库存插件时,我们通过脚本库存插件确保了向后兼容性。下面的示例说明了如何使用清单脚本。

如果您需要 GUI 来处理动态清单,红帽 Ansible Tower清单数据库会与您的所有动态清单源同步,提供对结果的 Web 和 REST 访问,并提供图形清单编辑器。通过所有主机的数据库记录,您可以关联过去的事件历史记录并查看哪些主机在上次运行手册时出现故障。

清单脚本示例:Cobbler

Ansible 与Cobbler无缝集成,Cobbler是一个 Linux 安装服务器,最初由 Michael DeHaan 编写,现在由为 Ansible 工作的 James Cammarata 领导。

虽然主要用于操作系统安装和管理 DHCP 和 DNS,Cobbler 有一个通用层,可以代表多个配置管理系统(甚至同时)的数据,并充当“轻量级 CMDB”。

要将您的 Ansible 库存与 Cobbler配合起来,复制这个脚本/etc/ansible并chmod +x授予文件执行权限。可以使用 Ansible的命令行-i选项随时运行cobblerd,(例如 -i /etc/ansible/cobbler.py),并通过Cobbler 的 XMLRPC API 与 Cobbler 通信。

/etc/ansible下,添加一个cobbler.ini文件,以便 Ansible 知道 Cobbler 服务器的位置,并且可以使用一些缓存特性。例如:

[cobbler]

# Set Cobbler's hostname or IP address
host = http://127.0.0.1/cobbler_api

# API calls to Cobbler can be slow. For this reason, we cache the results of an API
# call. Set this to the path you want cache files to be written to. Two files
# will be written to this directory:
#   - ansible-cobbler.cache
#   - ansible-cobbler.index

cache_path = /tmp

# The number of seconds a cache file is considered valid. After this many
# seconds, a new API call will be made, and the cache file will be updated.

cache_max_age = 900

首先通过直接运行/etc/ansible/cobbler.py来测试脚本。您应该会看到一些 JSON 数据输出,但其中可能还没有任何内容。

让我们探索一下这是做什么的。在 Cobbler 中,假设一个类似于以下的场景:

cobbler profile add --name=webserver --distro=CentOS6-x86_64
cobbler profile edit --name=webserver --mgmt-classes="webserver" --ksmeta="a=2 b=3"
cobbler system edit --name=foo --dns-name="foo.example.com" --mgmt-classes="atlanta" --ksmeta="c=4"
cobbler system edit --name=bar --dns-name="bar.example.com" --mgmt-classes="atlanta" --ksmeta="c=5"

在上面的例子中,系统 'foo.example.com' 可以由 ansible 直接寻址,但在使用组名 'webserver' 或 'atlanta' 时也可以寻址。由于 Ansible 使用 SSH,它通过“foo.example.com”联系系统 foo,而不仅仅是“foo”。类似地,如果您尝试“ansible foo”,它不会找到系统……但“ansible 'foo*'”会,因为系统 DNS 名称以“foo”开头。

该脚本提供的不仅仅是主机和组信息。此外,作为奖励,当“setup”模块运行时(使用剧本时会自动发生),变量“a”、“b”和“c”都将自动填充到模板中:

# file: /srv/motd.j2
Welcome, I am templated with a value of a={{ a }}, b={{ b }}, and c={{ c }}

可以像这样执行:

ansible webserver -m setup
ansible webserver -m template -a "src=/tmp/motd.j2 dest=/etc/motd"

名称“websevers”来自 Cobbler,配置文件的变量也是如此。您仍然可以像在 Ansible 中一样传入您自己的变量,但是来自外部清单脚本的变量将覆盖任何具有相同名称的变量。

因此,使用上面的模板 ( motd.j2),这将导致/etc/motd为系统 'foo'写入以下数据:

Welcome, I am templated with a value of a=2, b=3, and c=4

在系统“bar”(bar.example.com)上:

Welcome, I am templated with a value of a=2, b=3, and c=5

从技术上讲,虽然没有充分的理由这样做,但这也有效:

ansible webserver -m shell -a "echo {{ a }}"

因此,换句话说,您也可以在参数/操作中使用这些变量。

清单脚本示例:AWS EC2

如果您使用 Amazon Web Services EC2,维护清单文件可能不是最好的方法,因为主机可能会随着时间的推移来来去去,由外部应用程序管理,或者您甚至可能使用 AWS 自动扩展。因此,您可以使用EC2 外部清单脚本。

您可以通过以下两种方式之一使用此脚本。最简单的是使用 Ansible 的-i命令行选项并在将其标记为可执行后指定脚本的路径:

ansible -i ec2.py -u ubuntu us-east-1d -m ping

第二个选项是将脚本复制到/etc/ansible/hosts并chmod +x它。您还必须将ec2.ini文件复制到/etc/ansible/ec2.ini。然后你可以像往常一样运行 ansible。

要成功调用 AWS 的 API,您必须配置 Boto(AWS 的 Python 接口)。您可以通过多种可用方式执行此操作,但最简单的是导出两个环境变量:

export AWS_ACCESS_KEY_ID='AK123'
export AWS_SECRET_ACCESS_KEY='abc123'

您可以自行测试脚本以确保您的配置正确:

cd contrib/inventory
./ec2.py --list

片刻之后,您应该会在 JSON 中看到所有区域的整个 EC2 清单。

如果您使用 Boto 配置文件来管理多个 AWS 账户,您可以将--profile PROFILE名称传递给ec2.py脚本。示例配置文件可能是:

[profile dev]
aws_access_key_id = <dev access key>
aws_secret_access_key = <dev secret key>

[profile prod]
aws_access_key_id = <prod access key>
aws_secret_access_key = <prod secret key>

然后您可以运行ec2.py --profile prod以获取 prod 帐户的清单,尽管ansible-playbook还不支持此选项. 您还可以使用AWS_PROFILE变量,例如:AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml

由于每个区域都需要自己的 API 调用,如果您只使用一小部分区域,您可以编辑ec2.ini文件并注释掉您不使用的区域。

ec2.ini中还有其他配置选项,包括缓存控制和目标变量。默认情况下,该ec2.ini文件是为所有 Amazon 云服务配置的,但您可以注释掉任何不适用的功能。例如,如果您没有RDSelasticache,则可以将它们设置为False

[ec2]
...

# To exclude RDS instances from the inventory, uncomment and set to False.
rds = False

# To exclude ElastiCache instances from the inventory, uncomment and set to False.
elasticache = False
...

从本质上讲,清单文件只是从某个名称到目标地址的映射。默认的 ec2.ini 设置被配置为从 EC2 外部(例如从您的笔记本电脑)运行 Ansible——这不是管理 EC2 的最有效方式。

如果您在 EC2 中运行 Ansible,则内部 DNS 名称和 IP 地址可能比公共 DNS 名称更有意义。在这种情况下,您可以将ec2.ini中的destination_variablein修改为实例的私有 DNS 名称。在 VPC 内的私有子网中运行 Ansible 时,这一点尤为重要,其中访问实例的唯一方法是通过其私有 IP 地址。对于 VPC 实例,ec2.ini 中的 vpc_destination_variable 提供了一种使用 boto.ec2.instance 变量对您的用例最有意义的方法。

EC2 外部清单提供到来自多个组的实例的映射:

Global

在 ec2 group 中的所有实例都。

Instance ID

这些是一组一组,因为实例 ID 是唯一的。例如 i-00112233 i-a1b1c1d1

region

AWS 区域中所有实例的组。例如 us-east-1 us-west-2

Availability Zone

一个可用区中的所有实例的组。例如 us-east-1a us-east-1b

Security Group

实例属于一个或多个安全组。为每个安全组创建一个组,其中除字母数字外的所有字符都转换为下划线 (_)。每个组都以 security_group_为前缀。目前,破折号 (-) 也转换为下划线 (_)。您可以使用 ec2.ini 中的 replace_dash_in_groups 设置进行更改(这已在多个版本中更改,因此请查看 ec2.ini 以了解详细信息)。例如 security_group_default security_group_webservers security_group_Pete_s_Fancy_Group

Tags

每个实例都可以有多种与之关联的键/值对,称为标签。最常见的标签键是“名称”,尽管一切皆有可能。每个键/值对是它自己的组的实例,再次用特殊字符转换为下划线,在格式tag_KEY_VALUE 例如 tag_Name_Web可被用作是 tag_Name_redis-master-001tag_Name_redis_master_001 tag_aws_cloudformation_logical-id_WebServerGrouptag_aws_cloudformation_logical_id_WebServerGroup

当 Ansible 与特定服务器交互时,将使用该--host HOST选项再次调用 EC2 清单脚本。这会在索引缓存中查找 HOST 以获取实例 ID,然后向 AWS 发出 API 调用以获取有关该特定实例的信息。然后,它将有关该实例的信息作为变量提供给您的剧本。每个变量都以ec2_为前缀。以下是一些可用的变量: 

  • ec2_architecture

  • ec2_description

  • ec2_dns_name

  • ec2_id

  • ec2_image_id

  • ec2_instance_type

  • ec2_ip_address

  • ec2_kernel

  • ec2_key_name

  • ec2_launch_time

  • ec2_monitored

  • ec2_ownerId

  • ec2_placement

  • ec2_platform

  • ec2_previous_state

  • ec2_private_dns_name

  • ec2_private_ip_address

  • ec2_public_dns_name

  • ec2_ramdisk

  • ec2_region

  • ec2_root_device_name

  • ec2_root_device_type

  • ec2_security_group_ids

  • ec2_security_group_names

  • ec2_spot_instance_request_id

  • ec2_state

  • ec2_state_code

  • ec2_state_reason

  • ec2_status

  • ec2_subnet_id

  • ec2_tag_Name

  • ec2_tenancy

  • ec2_virtualization_type

  • ec2_vpc_id

ec2_security_group_ids 和 ec2_security_group_names 都是所有安全组的逗号分隔列表。每个 EC2 标签都是一个格式为ec2_tag_KEY的变量。

要查看可用于实例的完整变量列表,请自行运行脚本:

cd contrib/inventory
./ec2.py --host ec2-12-12-12-12.compute-1.amazonaws.com

请注意,AWS 清单脚本将缓存结果以避免重复 API 调用,并且此缓存设置可在 ec2.ini 中配置。要明确清除缓存,您可以使用以下--refresh-cache参数运行 ec2.py 脚本:

./ec2.py --refresh-cache

清单脚本示例:OpenStack

如果您使用基于 OpenStack 的云,则无需手动维护自己的清单文件,您可以使用openstack_inventory.py动态清单直接从 OpenStack 中提取有关计算实例的信息。

您可以在此处下载最新版本的 OpenStack 清单脚本。

您可以显式使用清单脚本(通过将-i openstack_inventory.py参数传递给 Ansible)或隐式使用(通过将脚本放置在/etc/ansible/hosts)。

显式使用 OpenStack 清单脚本

下载最新版本的 OpenStack 动态清单脚本并使其可执行:

wget https://raw.githubusercontent.com/ansible/ansible/stable-2.9/contrib/inventory/openstack_inventory.py
chmod +x openstack_inventory.py

不要将其命名为openstack.py。此名称将与来自 openstacksdk 的导入冲突。

获取 OpenStack RC 文件:

source openstack.rc

OpenStack RC 文件包含客户端工具与云提供商建立连接所需的环境变量,例如身份验证 URL、用户名、密码和区域名称。有关如何下载、创建或获取 OpenStack RC 文件的更多信息,请参阅使用 OpenStack RC 文件设置环境变量

您可以通过运行一个简单的命令(例如nova list)并确保它没有返回错误来确认文件已成功获取。

运行nova list命令需要 OpenStack 命令行客户端。有关如何安装它们的更多信息,请参阅安装 OpenStack 命令行客户端

您可以手动测试 OpenStack 动态清单脚本以确认它按预期工作:

./openstack_inventory.py --list

片刻之后,您应该会看到一些 JSON 输出,其中包含有关您的计算实例的信息。

确认动态清单脚本按预期工作后,您可以告诉 Ansible 使用openstack_inventory.py脚本作为清单文件,如下图所示:

ansible -i openstack_inventory.py all -m ping

隐式使用 OpenStack 清单脚本

下载最新版本的 OpenStack 动态清单脚本,使其可执行并将其复制到/etc/ansible/hosts:

wget https://raw.githubusercontent.com/ansible/ansible/stable-2.9/contrib/inventory/openstack_inventory.py
chmod +x openstack_inventory.py
sudo cp openstack_inventory.py /etc/ansible/hosts

下载示例配置文件,修改它以满足您的需要并将其复制到/etc/ansible/openstack.yml:

wget https://raw.githubusercontent.com/ansible/ansible/stable-2.9/contrib/inventory/openstack.yml
vi openstack.yml
sudo cp openstack.yml /etc/ansible/

您可以手动测试 OpenStack 动态清单脚本以确认它按预期工作:

/etc/ansible/hosts --list

片刻之后,您应该会看到一些 JSON 输出,其中包含有关您的计算实例的信息。

刷新缓存

请注意,OpenStack 动态清单脚本将缓存结果以避免重复 API 调用。要明确清除缓存,您可以使用以下--refresh参数运行 openstack_inventory.py(或 hosts)脚本:

./openstack_inventory.py --refresh --list

其他清单脚本

您可以在contrib/inventory 目录中找到所有包含的清单脚本。所有清单脚本的一般用法都相似。您还可以编写自己的清单脚本

使用清单目录和多个清单源

如果Ansible -i中给定的位置是一个目录(或在ansible.cfg中如此配置),Ansible 可以同时使用多个清单源。这样做时,可以在同一个 ansible 运行中混合动态和静态管理的库存源。即时混合云!

在清单目录中,可执行文件将被视为动态清单源,而大多数其他文件将被视为静态源。以下任何一项结尾的文件将被忽略:

~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo

您可以通过在 ansible.cfg 中inventory_ignore_extensions配置一个列表,或设置ANSIBLE_INVENTORY_IGNORE环境变量。任何一种情况下的值都应该是一个以逗号分隔的模式列表,如上所示。

清单目录中的任何目录的group_varshost_vars子目录都将按预期解释,使清单目录成为组织不同配置集的有效方式。有关更多信息,请参阅使用多个清单来源

动态组的静态组

在静态清单文件中定义组的组时,子组也必须在静态清单文件中定义,否则ansible会返回错误。如果要定义动态子组的静态组,请在静态清单文件中将动态组定义为空。例如:

[tag_Name_staging_foo]

[tag_Name_staging_bar]

[staging:children]
tag_Name_staging_foo
tag_Name_staging_bar

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值