抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

21. 动态Inventory管理

目录

动态主机管理模块

add_host

在playbook执行的过程中,动态的添加主机到指定的主机组中

常用参数:

  • groups:添加主机至指定的组

  • name:要添加的主机名或IP地址

示例:

- name: add a host to group webservers
  hosts: webservers
  tasks:
    - add_host:
        name: "{{ item }}" 
        group: webservers 
        foo: 42 #添加主机到webservers组中,主机的变量foo的值为42
      loop:
        - host1
        - host2

    - debug:
        msg: "{{ groups.webservers }}"

group_by

在playbook执行的过程中,动态的创建主机组

示例:

- name: Create operating system group
  hosts: all
  tasks:
    #在playbook中设置一个新的主机组
    - group_by: 
        key: "os_{{ ansible_distribution }}"

- name: Run on CentOS hosts only
  hosts: os_CentOS
  tasks:
    - name: Install Apache
      yum: 
        name: httpd 
        state: latest

- name: Run on Ubuntu hosts only
  hosts: os_Ubuntu
  tasks:
    - name: Install Apache
      apt: 
        name: apache2 
        state: latest

动态inventory管理

动态inventory简介

在前面我们所有的选取主机组的操作都是通过维护inventory文件来完成的。而事实上,当在大规模应用当中,如果主机达成千上万台,这个时候还手动维护inventory文件将会给运维工作带来巨大的挑战。

在这种大规模的应用场景中,通常的做法是,将所有的主机都存储在cmdb当中。当需要对某一组主机或者某一类型的主机执行相应操作时,通过cmdb将相应主机取出来,动态的生成inventory,然后交由ansible处理即可。

所以其实Ansible Inventory包含静态inventory和动态inventory两部分。而我们前面通过手动在inventory文件中维护主机列表的方式即称之为静态inventory。而动态inventory则是指通过外部脚本获取主机列表,并按照ansible所要求的格式返回给ansible指令的操作方式。

动态inventory一般都会结合cmdb或者云计算平台等获取主机信息,由于主机资源一般会动态的进行增减,而这些系统一般会智能更新。我们需要通过这些工具提供的api或者接入库查询等方式返回主机列表。

动态inventory脚本规约

动态inventory脚本最终返回的满足ansible输出格式的json数据。ansible对于使用什么语言来实现动态inventory没有要求。但脚本必须支持两个参数:

  • --list:用于返回所有的主机组信息,每个组所包含的主机列表hosts、子组列表children、主机变量列表vars都应该是字典形式的,而_meta则用于存放主机变量

  • --host \:返回指定主机的变量列表,也可返回一个空字典

动态inventory脚本示例

#cat dynamic_inventory.py

#!/usr/bin/env python
# coding: utf-8
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()

        # Called with `--list`.
        if self.args.list:
            self.inventory = self.inventory_groups()
        # Called with `--host [hostname]`.
        elif self.args.host:
            # Not implemented, since we return _meta info `--list`.
            self.inventory = self.inventory_hosts(self.args.host)
        # If no groups or vars are present, return empty inventory.
        else:
            self.inventory = self.empty_inventory()

        print json.dumps(self.inventory);

    # Example inventory for testing.

    def inventory_groups(self):
        return {
            "webserver":  # 定义webserver组
            {
                "hosts": ["10.10.0.112"],  # webserver 组内主机
                "vars": {  # 组变量
                    "ansible_ssh_pass": "123456",  # Inventory 内置变量
                    "ansible_ssh_port": "27100"
                }
            },
            "dbserver":
            {
                "hosts": ["10.10.0.109"],
                "vars": {
                    "ansible_ssh_pass": "123456",
                    "ansible_ssh_port": "27100"
                    }
            },
            '_meta': {
                'hostvars': {
                    '10.10.0.112': {
                        'host_specific_var': 'foo'
                    },
                    '10.10.0.109': {
                        'host_specific_var': 'bar'
                    }
                }
            }
        }

    def inventory_hosts(self,host):
        if host == "10.10.0.112":
            return {
              '_meta': {
                'hostvars': {
                    '10.10.0.112': {
                        'host_specific_var': 'foo'
                    }
                }
              }
            }
        elif host == "10.10.0.109":
            return {
              '_meta': {
                'hostvars': {
                    '10.10.0.109': {
                        'host_specific_var': 'bar'
                    }   
                }   
              }   
            }      
        else:
            return {'_meta': {'hostvars': {}}}

    # Read the command line args passed to the script.
    def read_cli_args(self):
        parser = argparse.ArgumentParser()
        parser.add_argument('--list', help="list hosts", action = 'store_true')
        parser.add_argument('--host', help="display hostvars for host",action = 'store')
        self.args = parser.parse_args()

# Get the inventory.
ExampleInventory()

脚本需要设置x权限,否则ansible会提示没有权限调用:

chmod +x ./dynamic_inventory.py

执行该脚本,返回如下:

#  ./dynamic_inventory.py --list
{"webserver": {"hosts": ["10.10.0.112"], "vars": {"ansible_ssh_port": "27100", "ansible_ssh_pass": "123456"}}, "_meta": {"hostvars": {"10.10.0.112": {"host_specific_var": "foo"}, "10.10.0.109": {"host_specific_var": "bar"}}}, "dbserver": {"hosts": ["10.10.0.109"], "vars": {"ansible_ssh_port": "27100", "ansible_ssh_pass": "123456"}}}

# ./dynamic_inventory.py --host 10.10.0.109
{"_meta": {"hostvars": {"10.10.0.109": {"host_specific_var": "bar"}}}}

# ./dynamic_inventory.py --host 192.168.0.1
{"_meta": {"hostvars": {}}}

通过ansible操作示例如下:

# ansible -i dynamic_inventory.py webserver --list-hosts
  hosts (1):
    10.10.0.112

# ansible -i dynamic_inventory.py all --list-hosts
  hosts (2):
    10.10.0.112
    10.10.0.109

评论