Inventory文件扩展

7.1 Inventory文件实战

    实际生产环境中,根据业务量的规模差异,Inventory文件中的主机数量会从几十台到上百台不等。通常这些主机会按照其所服务的应用类型进行分组,比如database、webserver和caching组等。

    下面我们来看一个现实生产中的案例。该案例中,我们使用Check.in服务来对服务器的uptime进行监控,其Inventory文件内容如下所示。

# 代码清单7-1 Inventory文件内容
# Check.in 服务器端主机组
[servercheck-web]
www1.servercheck.in
www2.servercheck.in

[servercheck-web:vars]
ansible_ssh_user=serverchekc_svc

[servercheck-db]
db1.servercheck.in

[servercheck-log]
log.servercheck.in

[servercheck-backup]
backup.servercheck.in

[servercheck-nodejs]
atl1.servercheck.in
atl2.servercheck.in
nyc1.servercheck.in
nyc2.servercheck.in
nyc3.servercheck.in
ned1.servercheck.in
ned2.servercheck.in

[servercheck-nodejs:vars]
ansible_ssh_user=servercheck_svc
foo=bar

# 按操作系统类型对主机组进行分组
[centos:children]
servercheck-web
servercheck-db
servercheck-nodejs
servercheck-backup

[ubuntu:children]
servercheck-log
    一眼看过去,这个Inventory文件让人有点不知该如何下手,但是当我们把它拆开来看的话,会发现它其实表述的是一幅简单的系统架构图。

    图7.1为Check.in服务器架构图,可将其与Inventory文件对照。

下面一个例子是Playbook利用组变量,在一个Playbook文件中对整套架构中的所有主机进行了配置,如下所示。

代码清单7-2 利用组变量对所有主机进行配置
---
#对所有主机进行基础配置
- hosts: all
  sudo: true
  roles:
      - security
      - logging
      - firewall
#配置web主机
- hosts: servercheck-web
  roles:
      - nginx
      - php
      - servercheck-web
#配置数据库主机
- hosts: servercheck-db
  roles:
      - pgsql
      - db-tuning
#配置日志主机
- hosts: servercheck-log
  roles:
      - java
      - elasticsearch
      - logstash
      - kibana
# 配置备份主机
- hosts: servercheck-backup
  roles:
       - backup
#配置Node.js主机
- hosts: servercheck-nodejs
  roles:
       - servercheck-node

7.2 独立的Inventory文件

    上节中,代码清单7-1使用的是全局生效的Inventory文件,这种集中管理的方法对线上生产环境来说是可行的。但是,在和线上生产环境极其相似的测试环境中,我们需要另外一种Inventory的管理方法:将集中管理的Inventory文件进行分隔,独立管理。

    还以代码清单7-1所在Inventory文件为例,创建如下结构的两个目录:servercheck/inventories,我们将代码清单7-1所在Inventory文件复制一份并重命名为inventory-prod,这表明生产环境中我们就使用inventory-prod作为Inventory文件。再将文件inventory-prod复制一份并重命名为inventory-dev,然后将其中的线上生产服务器的主机名替换为测试开发环境的主机名,比如:将[servercheck-web]主机组下面的www1.servercheck.in改为与其对应的测试主机www1-dev.servercheck.in,这样就为测试开发环境创建了一份单独的Inventory文件。最后目录结构如下:

servercheck/
    inventories/
        inventory-prod
        invenrory-dev
    playbook.yml 
    现在要想对开发环境进行操作,则只需要指定对应的Inventory文件就可以了。比如:

ansible-playbook playbook.yml -i inventories/inventory-dev
    此外,针对第一个独立的Inventory文件,我们可以在文件中为不同的环境指定不同的Inventory变量、任务或者角色,甚至根据需要对整个Inventory的架构进行变动都是可以的。

7.3 Inventory变量

我们先来回顾一下在Inventory文件中为主机和主机组定义变量的简单例子,代码如下所示:

[www]
# 为主机单独定义变量
www1.example.com ansible_ssh_user=johndoe
www2.example.com

[db]
db1.example.com
db2.example.com

# 为一组主机定义变量,这些变量对组内所有主机生效
[db:vars]
ansible_ssh_prot=5222
database_performance_mode=true
    通常,我们建议不要在静态的Inventory文件中定义过多的变量,因为这样定义的变量不仅识别度低,而且维护起来也比较麻烦,尤其是在一行内一台主机定义多个变量的时候。

    幸运的是,Ansible为用户提供了一种弹性很高且易于维护的变量管理方法。

7.3.1 host_vars目录

    在很多项目中,同一主机组中的各个主机可能由于自身硬件性能的差异或运行服务的不同,对同一项性能指标有着不同的要求。比如在Apache Slor集群中,我们有一个名为slor的主机组,里面各主机对内存有着不同的需求。我们可以使用host_vars目录对每一台主机进行变量设置。host_vars目录可以将Hosts文件一同放置在/var/ansible目录下,也可以与Playbook文件放在同一个目录下,host_vars目录内放置和主机同名的YAML文件,用来为主机设置变量。

    下面我们来看一个简单的host_vars目录的应用实例。我们当前有如下的目录结构:

hostedapachesolr/
    host_vars/
        nyc1.hostedapachesolr.com
    inventory/
        hosts
    main.yml 
    本例中inventory目录下的文件hosts定义主机组,其内容如下:

[solr]
nyc1.hostedapachesolr.com
nyc2.hostedapachesolr.com
jap1.hostedapachesolr.com
...
[log]
log.hostedapachesolr.com
    在Ansible运行时,Ansible会搜索hostedapachesolr/host_vars/nyc1.hostedapachesolr.com或者hostedapachesolr/inventory/host_vars/nyc1.hostedapachesolr.com(本例中未使用该文件),在这两个文件中定义的变量只对文件名所对应的主机名生效,并且将覆盖在其他任何Playbook和Role中定义的同名变量的值。

    文件nyc1.hostedapachesolr.com的内容如下:

---
tomcat_xmx: "1024m"
    默认情况下,tomcat_xmx的值为640m,我们在nyc1.hostedapachesolr.com进行的设置将会覆盖其默认值,使其最终结果为1024m。

    使用host_vars目录的方法来管理和定义主机变量非常便于维护,并且由于文件名是由主机名命名的YAML文件,所以维护起来也不容易搞混。

7.3.2 group_vars目录

    group_vars目录管理组变量的方法与host_vars目录非常相似,存放路径也是在/etc/ansible目录下或者与所要执行的Playbook相同的目录下,用于定义组变量的文件也要使用YAML语法,且文件应以主机组名来命名。

    我们继续使用上面的例子,只是在原有的目录结构中加了一个hostedapachesolr/group_vars目录。结构如下所示:

hostedapachesolr/
    group_vars/
        solr
    host_vars/
        nyc1.hostedapachesolr.com
    inventory/
        hosts
    main.yml
    在文件group_vars/solr中,使用YAML语法为主机组slor定义组变量,内容如下:

---
do_something_amazing=true
foo=bar

7.4 动态Inventory

    在大多数情况下,静态Inventory文件可以很好地描述主机间的关系。尤其是服务器规模不大的情况下,即便是手动来编辑、更新Inventory文件也非常方便快捷。

    然而,我们所生活的时代是云计算和大规模集群的时代。在实际生产应用中,经常会遇到业务的快速发展或者流量的急剧增加等情况,需要在短时间内向架构中添加几十台甚至上百台服务器来提高整个架构的处理能力。这个时候,手动管理Inventory文件不仅没有效率,而且非常乏味。

    此时,动态Inventory应运而生。Ansible通过调用第三方脚本来动态地配置Inventory文件。目前,一些知名的云主机供应商,如亚马逊AWS、Cobbler、gitalOcean、Lnode、OpenStack等,提供了现成的脚本供Ansible直接调用,其具体的用法在对应的官方文档说明。

    Ansible启用动态Inventory的机制是通过调用外部脚本(任何脚本都可以,二进制文件也可以,只要运行结果返回的是JSON串就行)生成指定格式的JSON串。Ansible可以对JSON格式的字符串进行解析,并最终将其转化为Ansible可用的Inventory文件格式。所以,所谓的动态Inventory文件脚本开发,其实就是编写脚本根据具体环境将主机信息及关系(这些数据可以通过抓取数据库,调用API或者直接读取文件获得)以JSON格式来表示出来,并将其作为脚本输出结果传给Ansible。

    需要注意的是,用于生成JSON代码的脚本必须支持两个选项:--list和--host。

  • --list:返回所有的主机组信息,每个组都应该包括字典形式的主机列表、子组列表,如果需要的话还应该有组变量,最简单的信息是只包含主机列表。返回的数据格式是JSON格式。
  • --host<hostname>:返回该主机的变量列表,或者是返回一个空的字典,使用JSON格式。

    Ansible使用-i选项来调用脚本。命令格式如下:

ansible all -i my-inventory-script -m ping
    虽然在命令中并未体现,但Ansible默认是通过调用脚本的--list选项来获取JSON代码的。下面是一段由脚本生成的JSON代码。

{
    "databases": {
        "hosts": [
             "192.168.230.235",
             "192.168.230.238"
        ],
        "vars": {
            "ansible_ssh_user": "johndoe",
            "ansible_ssh_private_key_file": "~/.ssh/mykey",
            "example_variable": "value"
        }
    },
    "_meta": {
        "hostvars": {
            "192.168.230.235": {
                "host_specific_var": "bar"
            },
            "192.168.230.238": {
                "host_specific_var": "foo"
            }
        }
    }
} 
    在本例中,databases为主机组名,可自定义。hosts为固定字段,用于以列表形式定义主机组的主机。vars也为固定字段,用于为主机组设置主机组变量。字典_meta中定义的是主机变量。

    主机变量并不是Inventory文件中所必需的,所以_meta字典也不是必须生成的。当Inventory脚本中生成_meta字典时,Ansible会将_meta信息存放在缓存中,当任务中需要调用这些主机变量时,会直接从缓存中读取,而不是调用一次变量就执行一次Inventory脚本。这就大大提高了运行效率。

    1.动态Inventory脚本的Python实现

    Vagrant:https://www.cnblogs.com/davenkin/p/vagrant-virtualbox.html

    我们通过Vagrant创建虚拟机,来演示动态Inventory脚本的基本写法。当然其他虚拟化平台的虚拟机或其他测试主机也都是可以的。首先在一个空目录下创建Vagrant的配置文件Vagrantfile,内容如下:

VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
    config.ssh.insert_key = false
    config.vm.provider :virtualbox do |vb|
        vb.customize ["modifyvm", :id, "--memory", "256"]
    end

    # Application server 1.
    config.vm.define "inventory1" do |inventory|
        inventory.vm.hostname = "inventory1.dev"
        inventory.vm.box = "geerlingguy/ubuntu1404"
        inventory.vm.network :private_network, ip: "192.168.230.223"
    end

    # Application server 2.
    config.vm.define "inventory2" do |inventory|
        inventory.vm.hostname = "inventory2.dev"
        inventory.vm.box = "geerlingguy/ubuntu1404"
        inventory.vm.network :private_network, ip: "192.168.230.224"
    end
end
    然后运行vagrant up来启动这两台虚拟机,按照我们Vagrantfile中的配置,两台虚拟机都采用Ubuntu14.04系统,IP地址分别为192.168.230.223和192.168.230.224。

    要求最终产生的JSON代码需要等效于这样一份Inventory文件:

[group]
192.168.230.223 host_specific_var=foo
192.168.230.224 host_specific_var=bar

[group:vars]
ansible_ssh_user=vagrant
ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key
example_variable=value
    下面我们来看一个最基本的基于Python开发的动态Inventory脚本,如代码清单7-3所示。

#!/usr/bin/env python
#encoding=utf-8
'''
基于Python的动态Inventory脚本举例
'''

import os
import sys
import argparse

try:
     import json
except ImportError:
     import simplejson as json

class ExampleInventory(object):

     def __init__(self):
         self.inventory = {}
         self.read_cli_args()

         # 定义`--list`选项
         if self.args.list:
             self.inventory = self.example_inventory()
         # 定义`--host [hostname]`选项
         elif self.args.host:
             # 未部署,我们这里只演示--list选项功能
             self.inventory = self.empty_inventory()
         # 如果没有主机组或变量要设置,就返回一个空Inventory
         else:
             self.inventory = self.empty_inventory()

         print json.dumps(self.inventory);

     # 用于展示效果的JSON格式的Inventory文件内容
     def example_inventory(self):
         return {
             'group': {
                 'hosts': ['192.168.230.223', '192.168.230.224'],
                 'vars': {
                     'ansible_ssh_user': 'vagrant',
                     'ansible_ssh_private_key_file':
                         '~/.vagrant.d/insecure_private_key',
                     'example_variable': 'value'
                 }
             },
             '_meta': {
                 'hostvars': {
                     '192.168.230.223': {
                         'host_specific_var': 'foo'
                     },
                     '192.168.230.224': {
                         'host_specific_var': 'bar'
                     }
                 }
             }
         }

     # 返回仅用于测试的空Inventory
     def empty_inventory(self):
         return {'_meta': {'hostvars': {}}}

     # 读取并分析读入的选项和参数
     def read_cli_args(self):
         parser = argparse.ArgumentParser()
         parser.add_argument('--list', action = 'store_true')
         parser.add_argument('--host', action = 'store')
         self.args = parser.parse_args()

# 获取Inventory
ExampleInventory()


使用Ansible命令调用这个脚本来测试两台虚拟机的网络是否正常。

ansible all -i inventory.py -m ping
192.168.230.223 | success >> {
    "changed": false,
    "ping": "pong"
}
192.168.230.224 | success >> {
    "changed": false,
    "ping": "pong"
}
ansible all -i inventory.py -m debug -a "var=host_specific_var"
运行结果如下:

192.168.230.223 | success >> {
    "var": {
        "host_specific_var": "foo"
    }
}
192.168.230.224 | success >> {
    "var": {
        "host_specific_var": "bar"
    }
}
    2.动态Inventory脚本的PHP实现

#!/usr/bin/php
<?php

/**
* @file
*基于PHP的动态Inventory脚本举例
*/

/**
*
*
* @return array
*生成用于展示效果的JSON格式的Inventory文件内容
*/
function example_inventory() {
return [
'group' => [
'hosts' => ['192.168.28.71', '192.168.28.72'],
'vars' => [
'ansible_ssh_user' => 'vagrant',
'ansible_ssh_private_key_file' => '~/.vagrant.d/insecure_private_key',
'example_variable' => 'value',
],
],
'_meta' => [
'hostvars' => [
'192.168.28.71' => [
'host_specific_var' => 'foo',
],
'192.168.28.72' => [
'host_specific_var' => 'bar',
],
],
],
];
}

/**
*
*
* @return array
* 生成用于测试的空Inventory
*/
function empty_inventory() {
return ['_meta' => ['hostvars' => new stdClass()]];
}

/**
* 获取Inventory
*
* @param array $argv
* 以数组形式传入变量(as returned by $_SERVER['argv']).
*
* @return array
*
*/
function get_inventory($argv = []) {
$inventory = new stdClass();

// 设置`--list`选项
if (!empty($argv[1]) && $argv[1] == '--list') {
$inventory = example_inventory();
}
// 定义`--host [hostname]` 选项
elseif ((!empty($argv[1]) && $argv[1] == '--host') && !empty($argv[2])) {
//未部署,我们这里只演示--list选项功能
$inventory = empty_inventory();
}
//如果没有主机组或变量要设置,就返回一个空Inventory
else {
$inventory = empty_inventory();
}

print json_encode($inventory);
}

// 获取Iventory.
get_inventory($_SERVER['argv']);

?>





   







  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Ansible的配置文件是一个YAML文件,其中可以包含一些全局变量,用于控制Ansible的运行。例如,控制Ansible的插件,配置连接方式,设置连接超时时间,设置系统模块的路径,以及其他的一些配置。 ### 回答2: Ansible是一种自动化工具,用于配置、管理和部署服务器和网络设备。Ansible的配置文件是一个文本文件,通常名为ansible.cfg。下面是ansible.cfg配置文件的一些说明: 1. [defaults]部分:这是配置文件的默认部分,包含了一些全局配置选项。例如,可以通过设置inventory(主机清单文件)的路径、定义日志文件位置、设置远程用户等。 2. [inventory]部分:这个部分用于配置主机清单文件inventory)。可以通过设置inventory参数来指定清单文件的位置,如inventory = /etc/ansible/hosts。还可以通过设置常用选项,如指定要连接的主机范围,指定动态清单脚本等。 3. [privilege_escalation]部分:这个部分用于配置特权升级。可以通过设置参数become来指定是否使用特权升级,默认值为False。还可以设置特权升级的用户、密码、路径等。 4. [paramiko_connection]部分:这个部分用于配置Paramiko连接选项。可以设置ssh连接的超时时间、重试次数等。 5. [ssh_connection]部分:这个部分用于配置SSH连接选项。可以设置SSH连接的超时时间、重试次数,以及控制是否加载系统的环境变量等。 6. [galaxy]部分:这个部分用于配置Ansible Galaxy,可用于管理和共享Ansible角色。可以通过设置参数路径、服务器等。 7. [callback_plugins]部分:这个部分用于配置回调插件。可以指定回调插件的路径,用于在任务执行过程中生成日志、指标、报告等。 通过修改ansible.cfg配置文件,可以对Ansible的行为和功能进行定制和扩展。可以根据实际需求,修改相关的配置选项,以满足特定的运维需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值