云端自动化(上):使用Heat对OpenStack进行流程管理

对于云计算平台,涉及到虚拟化、存储、网络、监控等多种资源的管理和分配,以OpenStack为例,它由多个开源子项目组成,管理虚拟化资源的Nova、身份认证的KeyStone、仪表板的Horizon等。

Screen Shot 2015-01-21 at 3.33.25 PM

而对于一个虚拟机实例的启动、IP绑定、软件部署等一系列操作,如果完成由人工来完成,过程是非常繁杂和浪费时间的。AWS提供了一个好用的业务流程操作和资源分配工具CloudFormation,可以通过配置的模板来完成一系列的任务操作,如启动虚拟机实例、指定IP地址、开启端口、下载安装软件,最后成功完成一台Web服务器的搭建。OpenStack这边也提供了一个类似的框架Heat,来支持业务流程的管理。

Heat的基本概念包括StackTemplate。其中Stack是一组云基础设施的容器,被创建的虚拟机实例、网络资源和存储资源都会跟创建时Stack的ID相关联,当需要对这一批资源进行回收时,仅需要对这个Stack进行删除操作即可。所以Stack非常适合用于批量资源的创建和销毁。

Template则描述了这一批需要被创建的资源的细节,在Heat工作时,它会读取Template中的描述,向OpenStack发出请求完成操作,如下图所示:

Screen Shot 2015-01-21 at 3.42.33 PM

 

对Heat项目来说,由于它参考了AWS CloudFormation的实现,所以除了自己的格式之外,CloudFormation的Template它也是兼容的。

Heat Template

#
# This is a HOT template just defining a single compute server.
#
heat_template_version: 2013-05-23

description: >
  Defines a single server.

parameters:
  key_name:
    type: string
    description: Name of an existing key pair to use for the server
    default: ''
  flavor:
    type: string
    description: Flavor for the server to be created
    default: m1.large
  image:
    type: string
    description: Image ID or image name to use for the server
    default: a13349a4-fba5-4791-8db4-de82672311a6

resources:
  server:
    type: OS::Nova::Server
    properties:
      key_name: { get_param: key_name }
      image: { get_param: image }
      flavor: { get_param: flavor }
      networks: [{'network':'48afdbad-ba45-48d7-9b01-29ca6203cc01'}]

outputs:
  server_networks:
    description: The networks of the deployed server
    value: { get_attr: [server, networks] }
Heat Template文件后缀名为.yaml,parameters定义的是一组Key-Value pair,Key值可自由声明,Value的结构根据声明的Key实际类型来定义。声明的Key值可以在resources节点中进行调用。以上面的代码为例,image指定了镜像的ID和描述,在resources的server.properties.image节点,使用 get_param : image 对已定义的 image 进行了值的调用。 server.type指定的OS::Nova::Server,是由OpenStack提供的资源类型定义,使用时需要参考[HOT手册](http://www.justinablog.com/wp-content/uploads/2015/01/hot-reference.pdf)。 ### AWS CloudFormation Template
{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Parameters" : {
    "KeyName" : {
      "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instance",
      "Type" : "String",
      "Default" : "keypair-172"
    }
  },

  "Resources" : {
    "MyInstance" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "KeyName" : { "Ref" : "KeyName" },
        "ImageId" : "F17-x86_64-cfntools",
        "InstanceType": "m1.small",
        "UserData" : { "Fn::Base64" : "80" }
      }
    }
  },
  "Outputs" : {
    "InstanceIp" : {
      "Value" : { "Fn::Join" : ["", ["ssh ec2-user@",
                                     {"Fn::GetAtt": ["MyInstance",
                                     "PublicIp"]}]]},
      "Description" : "My ssh command"
    }
  }
}
CloudFormation Template后缀名为.template,如果企业使用私有云平台,通常会定义多个网络资源,使用CloudFormation Template创建基础设施时,会提示“寻找到多个网络资源,请指定”的错误。由于查找兼容的Template配置比较花费时间,在私有云平台上,我们更推荐使用Heat自己的Template进行资源描述管理。 ## Heat客户端管理工具 在OpenStack上安装并启用之后,可以通过管理界面上的“编配-栈”对Stack进行创建和删除。另外我们也可以使用heat-client提供的命令行工具进行管理。OpenStack使用Python进行开发,先需要安装Python的包管理工具pip,接下来使用pip安装heat-client.
pip install heat-client
如果使用的是Mac Yosemite并且没有为Python创建虚拟环境的话,需要删除 heat-client 并使用easy_install重新安装相关的依赖包,否则调用 heat 时会出现 no module named xmlrpc_client 的错误。 ### **命令行工具** 安装好后,先需要配置OpenStack的API认证信息到环境变量中,然后可以使用以下命令查看帮助、创建或删除Stack:
export OS_PASSWORD=password
export OS_TENANT_NAME=admin
export OS_AUTH_URL=http://openstack.example.org/v2.0
export OS_USERNAME=ADMIN

heat --help
heat list
heat stack-create -f hello_world.yaml mytest
heat stack-delete mytest
如果遇到找不到Controller机器的错误,还需要在本地机器hosts中添加Controller的DNS解析,这算是开源项目的一个Bug:
10.10.0.1    Controller
创建或删除Stack后Heat都会返回当前Stacks的状态,同时在OpenStack的仪表板中可以看到被创建的Stack和虚拟机实例:
+--------------------------------------+--------------+--------------------+----------------------+
| id                                   | stack_name   | stack_status       | creation_time        |
+--------------------------------------+--------------+--------------------+----------------------+
| 8d874f5c-6c6d-430a-8b9e-695be68e5972 | test-stack   | CREATE_IN_PROGRESS | 2015-01-21T06:21:19Z |
| bfbaea3b-185e-41d3-941b-f329aeb3425e | ansible-heat | DELETE_IN_PROGRESS | 2015-01-21T06:31:30Z |
+--------------------------------------+--------------+--------------------+----------------------+

使用编程方式访问API

Heat本身提供了Naive API可通过Http进行请求,默认端口是8004,在通过身份认证取得tenat_id后,通过以下Url进行请求:

http://heat.example.org:8004/v2/{tenant_id}
官方提供的Python Client类只提供了通过token的方式调用,先需要解决KeyStone身份认证的问题,在身份认证之后,可以在返回的Auth对象中取得Heat的API Url。示例代码如下:
from heatclient.client import Client as heatClient
from keystoneclient.v2_0 import client as keyStoneClient

username = 'admin'
password = 'password'
tenant_name = 'ADMIN'
auth_url = 'http://heat.example.org:35357/v2.0'
keystone = keyStoneClient.Client(username=username, password=password,
                                 tenant_name=tenant_name, auth_url=auth_url)

auth_token = keystone.auth_ref['token']['id']
heat_url = ''
services = keystone.auth_ref['serviceCatalog']
for service in services:
    if service['name'] == 'heat':
        heat_url = service['endpoints'][0]['publicURL']

heat = heatClient('1', endpoint=heat_url, token=auth_token)
创建一个Stack
from heatclient.common import template_utils
path = "/var/tmp/hello_world.yaml"
tpl_files, template = template_utils.get_template_contents(path)
create_fields = {
    'stack_name': 'test_stack',
    'disable_rollback': 'false',
    'parameters': '',
    'template': template,
    'files': dict(list(tpl_files.items()))
}
heat.stacks.create(**create_fields)
删除Stack
delete_fields = {
    'stack_id': 'test_stack'
}
heat.stacks.delete(**delete_fields)
,
© 2018 Silent River All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero