动态Inventory

Ansible使用配置管理系统经常有一种需求,可能要在其他的软件系统中保存自己的 inventory 配置信息. Ansible本身通过基于文本的方式来记录 inventory 配置信息,这在前面已介绍过除此之外,Ansible 也支持用其他方式保存配置信息.在其他软件系统保存配置信息的例子有:

1, 从云端拉取 inventory2, LDAP(Lightweight Directory Access Protocol,轻量级目录访问协议)
3, `Cobbler <http://cobbler.github.com>`_
4, 或者是一份昂贵的企业版的 CMDB(配置管理数据库) 软件.

对于这些需求,Ansible 可通过一个外部 inventory 系统来支持.在 ansible 的 “/plugins” 插件目录下已经含有一些选项 – 包括EC2/Eucalyptus, Rackspace Cloud,and OpenStack,我们稍后会详细介绍它们.

 

Ansible Tower提供了一个数据库来存储 inventory 配置信息, 这个数据库可以通过 web 访问,或通过 REST 访问. Tower 与所有你使用的 Ansible 动态 inventory 源保持同步,并提供了一个图形化的 inventory 编辑器. 有了这个数据库,便可以很容易的关联过去的事件历史,可以看到在上一次 playbook 运行时,哪里出现了运行失败的情况.

 

关于如何编写你自己的动态 inventory 源,请参见 .

 

Cobbler 外部Inventory 脚本

当管理的物理机器到达了一定数量的时,很多使用 Ansible 的用户可能同时也会使用到 Cobbler .(注: Cobbler 最初由 Michael DeHaan 编写,现在项目主导人是 James Cammarata, 他目前在 Ansible 公司工作).

 

Cobbler 主要用于操作系统的 kickoff 安装,以及管理 DHCP 和 DNS,除此之外,它有一个通用层,可为多种配置管理系统(甚至是同时的)提供数据. 所以 Cobbler 也被一些管理员称为是轻量级的 CMDB.

如何将 Ansible 的 inventory 与 Cobbler 联系起来呢?方法是: 将脚本 script 拷贝到 /etc/ansible,通过 chmod+x 赋予可执行权限.

 

在使用 Ansible 之前,先启动 cobblerd 进程.

 

现在使用 Ansible 要加上 -i 选项 ( 例如:-i /etc/ansible/cobbler.py).cobbler.py这个脚本使用 Cobbler 的 XMLRPC API 与 Cobbler 通信.

 

执行脚本 /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 可以通过这个域名寻址找到对应的主机foo,对其进行操作.也可以通过组名 ‘webserver’ 或者 ‘atlanta’ 寻址找到这个主机,只要这个主机是属于这两个组的.直接使用 foo 是不行的.例如执行命令 “ansible foo” ,无法找到该主机,但使用 “ansible ‘foo*’” 却可以,因为域名 ‘foo.example.com’ 以foo开头.

 

这个脚本不仅提供主机和组的信息.如果运行了 ‘setup’ 模块(只要使用 playbooks,’setup’ 模块会自动运行),变量 a, b, c 可按照以下模板自动填充:

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

模板的使用如下:

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

Note

组名 ‘webserver’ 是 cobbler 中定义的.你仍然可以在 Ansible 的配置文件中定义变量. 但要注意,变量名相同时,外部 inventory 脚本中定义的变量会覆盖 Ansible 中的变量.

 

执行上面命令后,主机 foo 的/etc/motd文件被写入如下的内容:

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

主机 ‘bar’ (bar.example.com)的 /etc/motd 中写入如下内容:

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

你也可以通过下面这个命令测试变量的替换:

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

也就是说,你可以在参数或命令操作中使用变量的替换.


AWS EC2 外部inventory 脚本

使用 AWC EC2时,维护一份 inventory 文件有时不是最好的方法.因为主机的数量有可能发生变动,或者主机是由外部的应用管理的,或者使用了 AWS autoscaling.这时,使用 EC2external inventory 脚本是更好的选择.

 

脚本的使用方式有两种,最简单的是直接使用 Ansible 的命令行选项 -i ,指定脚本的路径(脚本要有可执行权限):

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

第二种方式,把脚本拷贝为 /etc/ansible/hosts ,并赋予可执行权限.还需把 ec2.ini 文件拷贝到 /etc/ansible/ec2.ini,然后运行 ansible.

 

要成功的调用 API 访问 AWS,需要配置 Boto (Boto 是 AWS 的 Python 接口).可用的方法有多种,请参见: methods .

 

最简单的方法是定义两个环境变量:

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

如何知道配置是否正确,执行脚本来测试:

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

你可以看到以 JSON 格式表示的覆盖所有 regions 的 inventory 信息.

 

因为每一个 region 需要自己的 API 调用,如果你仅使用了所有 regions 中的一个子集,可以编辑 ec2.ini ,使之仅显示你所感兴趣的那些 regions. 在配置文件 ec2.ini 中,包含了其他配置选项,包括缓存控制和目的地址变量.

 

inventory 文件的核心部分,是一些名字到目的地址的映射.默认的 ec2.ini 设置适用于在 EC2 之外运行 Ansible(比如一台笔记本电脑),但这不是最有效的方式.

在 EC2 内部运行 Ansible 时,内部的 DNS 名和 IP 地址比公共 DNS 名更容易理解.你可以在 ec2.ini文件中修改 destination_variable 变量, 改为一个实例的私有 DNS 名.对于在私有子网的 VPC 上运行 Ansible ,这种设置很重要,使得我们可以使用内部IP地址之外的方式访问到一个VPC.在 ec2.ini 文件中, vpc_destination_variable 可以命名为任意一个 boto.ec2.instance 变量.

 

EC2 外部 inventory 提供了一种从多个组到实例的映射:

 

全局 实例都属于 ec2 这个组.

 

实例ID

例如: i-00112233 i-a1b1c1d1

 

Region

属于一个 AWS region 的所有实例构成的一个组. 例如: us-east-1 us-west-2

 

可用性区域

所有属于 availabilityzone 的实例构成一个组. 例如: us-east-1a us-east-1b

 

安全组

实例可属于一个或多个安全组.每一个组的前缀都是 security_group_ ,符号(-) 已被转换为(_). with all charactersexcept alphanumerics (这句没明白)

例如: security_group_default security_group_webservers security_group_Pete_s_Fancy_Group

 

标签

每一个实例可有多个不同的 key/value 键值对,这些键值对被称为标签.标签名可以随意定义,最常见的标签是 ‘Name’.每一个键值对是这个实例自己的组. 特殊字符已转换为下划线,格式为 tag_KEY_VALUE 例如: tag_Name_Web tag_Name_redis-master-001tag_aws_cloudformation_logical-id_WebServerGroup

 

使用 Ansible 与指定的服务器进行交互时,EC2 inventory 脚本被再次调用(调用时加上了命令行选项--host HOST ),这个调用会在索引缓存中进行查找,获取实例 ID,然后调用 API 访问 AWS,获取指定实例的所有信息.这些信息被转换为 playbooks 中的变量,可以进行访问.每一个变量的前缀为 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 plugins/inventory./ec2.py --host ec2-12-12-12-12.compute-1.amazonaws.com

注意,AWS inventory 脚本会将结果进行缓存,以避免重复的 API 调用,这个缓存的设置可在 ec2.ini 文件中配置.要显式地清空缓存,你可以加上 --refresh-cache 选项,执行脚本如下:

# ./ec2.py --refresh-cache


其它 inventory 脚本

除了 Cobbler 和 EC2 之外,还有以下的系统可以使用 inventory 脚本:

BSD JailsDigitalOceanGoogle Compute EngineLinodeOpenShiftOpenStack NovaRed Hat's SpaceWalkVagrant (not to be confused with the provisioner in vagrant, which is preferred)Zabbix

关于这些系统还没有专门的章节讲述如何操作,但步骤与上面所讲述的 AWS 一样,具体可看看Ansible checkout 的 “plugins/” 目录.

如果你开发了一个通用的 inventory 脚本,请提交一个 pull request,我们可能会把它放入项目中.

 

使用多个 inventory 源

如果 -i 选项后给出的地址是一个目录 (or as so configured in ansible.cfg),Ansible 可以同一时间使用多个 inventory 源.这样在同一个 ansible 运行操作中,可混合的使用动态和静态的 inventory 源.

 

动态组作为静态组的子组

在静态 inventory 文件中,如果定义一个由一些组作为子成员的组,这些子组也需要定义(译者注:即包含具体的 host),否则执行时 ansible 会返回一个错误. 如果定义一些动态组作为一个静态组的子组,也需在静态 inventory 文件中定义动态组,但是动态组定义为一个空的组即可:

[tag_Name_staging_foo] [tag_Name_staging_bar] [staging:children]tag_Name_staging_footag_Name_staging_bar

  • 发表于 2022-07-29 14:51
  • 阅读 ( 4852 )
  • 分类:Ansible

0 条评论

请先 登录 后评论
乐维君
乐维君

9 篇文章

作家榜 »

  1. YOHOHO 14 文章
  2. 细雨闲花 13 文章
  3. 机灵小和尚 13 文章
  4. 我是一只小菜鸡 12 文章
  5. 。。。 9 文章
  6. 御前侍卫张五哥 9 文章
  7. 乐维君 9 文章
  8. 小黄人 8 文章