云端自动化(下):使用Ansible和Heat进行软件部署

Ansible是一个使用Python开发的自动化运维管理开源工具,适用于批量管理服务器资源,基本概念包括:

  • Inventory:描述服务器资源,服务器资源以分组的模式放置在Inventory中,默认目录为 /etc/ansible/hosts
  • Dynamic Inventory:如云计算平台基础设施平台,在ansible执行时目标服务器资源可能还未创建,可以使用脚本动态创建资源列表写入Inventory路径
  • Playbook:Playbook译为“剧本”,顾名思义,它提供了ansible如何自动化执行的所有场景和任务描述
  • Modules:ansible是一个模块化平台,官方提供的模块库非常全面,包括cloud、command、database、network、packaging,也可以开发自己的自定义模块
    Ansible的安装,可以通过pip完成:
    >> pip install ansible

    接下来创建一个Inventory:
    >> sudo mkdir /etc/ansible
    >> touch /etc/ansible/hosts
    >> vim /etc/ansible/hosts

    在hosts中描述一组服务器和IP地址,我们指定组名openstack,两台OpenStack虚拟机IP:
    [openstack]
    10.74.149.12
    10.74.149.13

    验证访问:
    >> ansible openstack -m ping

    Playbook使用yaml语法描述,通常为一个主文档和多个同级目录下多个子文件夹和文档组成。

Ansible-Heat模块开发

Ansible是基于模块的架构,每个模块都是独立的Python文件,可以轻松地进行扩展。引入自定义模块文件有三种方法:

  1. 定义环境变量 ANSIBLE_LIBRARY 指向文件所在的目录路径;
  2. 在使用 ansible 命令时带上参数 –module-path 和目录路径;
  3. 在Playbook的根目录下创建 library 文件夹并放入模块文件。
    由于官方还未提供对OpenStack Heat的支持,在这里需要自己开发一个Heat的模块。Ansible Module的实现接口主要分为参数获取、实例化模块类、输出结果三部分,模块的输入接收一个dict对象,接收参数键值对,输出是接收一个JSON对象,在输出屏幕上打印出字符串:
  • 定义模块需要的参数组:参数组决定Ansible配置文件的键值对
  • 使用参数构建模块实例:调用 AnsibleModule 方法
  • 输出模块执行结果:JSON格式输出
    # 模块参数接收
    argument_spec = openstack_argument_spec()
    argument_spec.update(dict(
        stack_name=dict(required=True),
        template_parameters=dict(required=False, type='dict', default={}),
        action=dict(default='create', choices=['create', 'delete']),
        template=dict(default=None, required=True),
        disable_rollback=dict(default=False, type='bool')
    )
    
    )

构建模块实例

module = AnsibleModule(
argument_spec=argument_spec,
)

模块执行出错,返回错误信息

module.fail_json(msg={“error”:”can’t connect the server.”})

模块执行完成退出

result = {}
module.exit_json(**result)

了解基本知识后,现在开始我们的Heat模块开发。

配置约束结构定义

首先根据Heat Template的配置需求,定义一个Ansible Heat的配置文件结构:

- name: launch ansible heat example
  heat:
    stack_name: "ansible-heat"
    action: "create"
    disable_rollback: "false"
    template: "files/heat-example.yaml"
    template_parameters:
      KeyName: "keypair"
      DiskType: "ephemeral"
      InstanceType: "m1.small"
      Images: ["uuid", "uuid"]
配置说明如下: * heat - 指定执行这个配置时的模块名 * action - 对Stack的操作,创建或删除 * stack_name - 被创建的Stack的名称,是Heat必需的参数 * disable_rollback - 创建失败时的回滚标志,默认为false * template - 指定Heat Template文件的位置 * template_parameters - 命令行参数,提供灵活的调用 接下来对 ansible-module-core 项目源代码进行分析,它已经提供了一些OpenStack的模块如用户身份、计算和网络资源请求等,也提供了针对OpenStack的一些公共方法。 ### **开始编码** 创建一个heat.py文件,在底部引用公共模块:
# import module snippets
from ansible.module_utils.basic import *
from ansible.module_utils.openstack import *
引用Heat的Python包并检查,由于身份认证比较简单,我们就直接引用KeyStone:
try:
    from heatclient.client import Client
    from heatclient.common import template_utils
    from heatclient.common import utils
    from keystoneclient.v2_0 import client as ksclient
except ImportError:
    print("failed=True msg='heatclient and keystoneclient is required for this module'")
实现身份认证和创建删除Stack的代码可以参考之前的文章《[云端自动化(上):使用Heat对OpenStack进行流程管理](http://www.justinablog.com/archives/1278 "云端自动化(上):使用Heat对OpenStack进行流程管理")》,在这里我们只需要与Ansible Module调用进行集成:
result = {}
action = module.params['action']
stack_name = module.params['stack_name']

if action == 'create':
    try:
        heat.stacks.create(**fields)
        operation = 'CREATE'
    except Exception, err:
        module.fail_json(msg=err.message)
    result = stack_operation(heat, stack_name, operation)

if action == 'delete':
    heat.stacks.delete(**fields)
    operation = 'DELETE'
    result = stack_operation(heat, stack_name, operation)

module.exit_json(**result)
完整的模块代码参见:[https://github.com/RCFans/ansible-modules-extras/tree/devel/cloud/openstack](https://github.com/RCFans/ansible-modules-extras/tree/devel/cloud/openstack) 开发完成后,先对模块进行测试,测试工具包含在Ansible项目源码中,需要从GitHub上下载:
>> git clone git@github.com:ansible/ansible.git --recursive
>> source ansible/hacking/env-setup
>> chmod +x ansible/hacking/test-module

>> ansible/hacking/test-module -m ./heat.py
测试结果是参数缺失,由于还没有进行配置文件编写,这里可以认为代码实现已经正确:
PARSED OUTPUT
{
    "failed": true,
    "msg": "missing required arguments: stack_name,template"
}

Heat Playbook编写

在自动化部署时,基础设施如果已经创建,先需要对之前创建的资源进行检查和回收,再创建新一批基础设施。对文件目录结构可定义为:

- openstack-heat
  - roles
    - delete
      - files
      - tasks
    - create
      - files
      - tasks
由于我们操作的是基础设施而非目标服务器,hosts可指定为本机。roles下定义的delete、create为文件夹名称,files用于放置Heat Template文件。Ansible会查找文件夹下的.yml文档并执行。根目录下的文档 auto-deploy.yml 编写如下:
---
# This playbook deploys a simple standalone openstack server.

- hosts: localhost
  users: root

  roles:
    - delete
    - create
Tasks文件夹下为我们在Heat模块中定义的结构,下面是示例:
---
- name: launch ansible heat example
  heat:
    stack_name: "ansible-heat"
    action: delete
    disable_rollback: false
    template: roles/delete/files/single-instance.yaml
现在模块和Playbook配置已经完成,先在命令行中进行检查,我们把模块拷贝到了/usr/share/ansible目录下并使用环境变量方式引入:
>> ANSIBLE_LIBRARY=/usr/share/ansible/
>> ansible-playbook --syntax-check ansible-examples/openstack-heat/auto-deploy.yml
执行整个脚本:
>> ansible-playbook ansible-examples/openstack-heat/auto-deploy.yml
在输出和OpenStack的栈上都可以看到基础设施的创建了。 完整配置参见:[https://github.com/RCFans/ansible-examples/tree/master/openstack-heat](https://github.com/RCFans/ansible-examples/tree/master/openstack-heat) ## 部署脚本集成 Ansible提供Shell命令模块,只需要将软件的安装编写为脚本并集成到Playbook中即可:
- name: Install
  shell: sh files/application-install.sh
,
© 2018 Silent River All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero