Heat的两个生产实例

Heat的两个生产实例_第1张图片

Why Heat

关于Heat是什么东西,我已经在前面的文章《在Keystoen v2的Mitaka上部署HEAT服务》中有所提及。既然Heat 是一个基于模板来编排复合云应用的服务,那么引入编排会对我现在有什么改变呢?我想了下,改变大致如下:

  • 更快更有效的管理OpenStack的资源

目前大部分业务场景都是研发或测试的同事在申请虚拟机的同时会额外申请数据卷作为日志盘。在不引入Heat前,虚拟机和数据卷的映射挂载方式为用户手动确立。所以线上数据卷的维护往往都会出现利用ip地址作为映射关系的标准。

Heat的两个生产实例_第2张图片
Volume管理页面

不是说这样不好,只是做一方面是用户体验方面不太友好,数据卷少还好,一旦出现批量创建的情况,需要人为一个一个去挂载连接虚拟机,需要时间。另一方面也不利于虚拟机开机后的初始化的,我们知道正常情况下创建卷的速度是快于虚拟机的,要让虚拟机开机初始化数据卷,还是用传统的人为方式,明显是不可靠的。这方面,Heat的作用就比较大了。

  • 更小的研发成本

大部分不是做云计算的公司往往不会有专门从事这方面的研发人员,而往往他们处于成本的综合考量会倾向于选择OpenStack来作为自己的私有云解决方案。引入Heat,对于之前不了解OpenStack的研发者来说可以更快的接入现有的业务系统。对于开发者更关心的是授权认证和对虚拟资源的增删改,而对于底层的状态并不用太多关系。

Heat 编排

Heat 目前支持两种格式的模板,一种是基于 JSON 格式的 CFN 模板;另外一种是基于 YAML 格式的 HOT 模板。CFN 模板主要是为了保持对 AWS 的兼容性。HOT 模板是 Heat 自有的,资源类型更加丰富,更能体现出 Heat 特点的模板。

一个典型的 HOT 模板由下列元素构成:

  • 模板版本:必填字段,指定所对应的模板版本,Heat 会根据版本进行检验。
  • 参数列表:选填,指输入参数列表。
  • 资源列表:必填,指生成的 Stack 所包含的各种资源。可以定义资源间的依赖关系,比如说生成 Port,然后再用 port 来生成 VM。
  • 输出列表:选填,指生成的 Stack 暴露出来的信息,可以用来给用户使用,也可以用来作为输入提供给其它的 Stack。

本文会主要用 HOT 模板。HOT 模板的全称是 Heat Orchestration Template,是 Heat 发展的重心。

一个简单的官方demo如下:

#模板版本模板版本
heat_template_version: 2015-10-15
description: Launch a basic instance with Debian image using the
             ``m1.mediumtiny`` flavor``  one network.

#参数列表
parameters:
  NetID:
    type: string
    description: Network ID to use for the instance.

#资源列表
resources:
  server:
    type: OS::Nova::Server
    properties:
      image: Debian-Wheezy-7.11
      flavor: m1.medium
      networks:
      - network: { get_param: NetID }

#输出列表
outputs:
  instance_name:
    description: Name of the instance.
    value: { get_attr: [ server, name ] }
  instance_ip:
    description: IP address of the instance.
    value: { get_attr: [ server, first_address ] }
  novnc_console_url:
    value: { get_attr: [server, console_urls, novnc] }
    description: all available console URLs for the server

模板版本参数列表没什么讲的,这里最重要的资源列表输出列表,这两个东西直接影响你创建资源的类型以及资源返回的信息。

我们首先简单看下OS::Nova::Server的资源类型

$ openstack orchestration resource type show OS::Nova::Server

- Field: support_status
  Value: {message: null, previous_status: null, status: SUPPORTED, version: null}
- Field: attributes
  Value:
    accessIPv4: {description: The manually assigned alternative public IPv4 address
        of the server., type: string}
    accessIPv6: {description: The manually assigned alternative public IPv6 address
        of the server., type: string}
    addresses: {description: 'A dict of all network addresses with corresponding port_id.
        Each network will have two keys in dict, they are network name and network
        id. The port ID may be obtained through the following expression: "{get_attr:
        [, addresses, , 0, port]}".', type: map}
    console_urls: {description: 'URLs of server''s consoles. To get a specific console
        type, the requested type can be specified as parameter to the get_attr function,
        e.g. get_attr: [ , console_urls, novnc ]. Currently supported types
        are novnc, xvpvnc, spice-html5, rdp-html5, serial.', type: map}
    instance_name: {description: AWS compatible instance name., type: string}
    name: {description: Name of the server., type: string}
    networks: {description: 'A dict of assigned network addresses of the form: {"public":
        [ip1, ip2...], "private": [ip3, ip4], "public_uuid": [ip1, ip2...], "private_uuid":
        [ip3, ip4]}. Each network will have two keys in dict, they are network name
        and network id.', type: map}
    show: {description: Detailed information about resource., type: map}
- Field: properties
  Value:
    admin_pass: {description: The administrator password for the server., immutable: false,
      required: false, type: string, update_allowed: true}
    availability_zone: {description: Name of the availability zone for server placement.,
      immutable: false, required: false, type: string, update_allowed: false}
    block_device_mapping:
      description: Block device mappings for this server.
      immutable: false
      required: false
      schema:
        '*':
          immutable: false
          required: false
          schema:
            delete_on_termination: {description: Indicate whether the volume should
                be deleted when the server is terminated., immutable: false, required: false,
              type: boolean, update_allowed: false}
            device_name: {description: A device name where the volume will be attached
                in the system at /dev/device_name. This value is typically vda., immutable: false,
              required: true, type: string, update_allowed: false}
            snapshot_id:
              constraints:
              - {custom_constraint: cinder.snapshot}
              description: The ID of the snapshot to create a volume from.
              immutable: false
              required: false
              type: string
              update_allowed: false
            volume_id:
              constraints:
              - {custom_constraint: cinder.volume}
              description: The ID of the volume to boot from. Only one of volume_id
                or snapshot_id should be provided.
              immutable: false
              required: false
              type: string
              update_allowed: false
            volume_size: {description: 'The size of the volume, in GB. It is safe
                to leave this blank and have the Compute service infer the size.',
              immutable: false, required: false, type: integer, update_allowed: false}
          type: map
          update_allowed: false
      type: list
      update_allowed: false
    block_device_mapping_v2:
      description: Block device mappings v2 for this server.
      immutable: false
      required: false
      schema:
        '*':
          immutable: false
          required: false
          schema:
            boot_index: {description: Integer used for ordering the boot disks., immutable: false,
              required: false, type: integer, update_allowed: false}
            delete_on_termination: {description: Indicate whether the volume should
                be deleted when the server is terminated., immutable: false, required: false,
              type: boolean, update_allowed: false}
            device_name: {description: A device name where the volume will be attached
                in the system at /dev/device_name. This value is typically vda., immutable: false,
              required: false, type: string, update_allowed: false}
            device_type:
              constraints:
              - allowed_values: [cdrom, disk]
              description: 'Device type: at the moment we can make distinction only
                between disk and cdrom.'
              immutable: false
              required: false
              type: string
              update_allowed: false
            disk_bus:
              constraints:
              - allowed_values: [ide, lame_bus, scsi, usb, virtio]
              description: 'Bus of the device: hypervisor driver chooses a suitable
                default if omitted.'
              immutable: false
              required: false
              type: string
              update_allowed: false
            image_id:
              constraints:
              - {custom_constraint: glance.image}
              description: The ID of the image to create a volume from.
              immutable: false
              required: false
              type: string
              update_allowed: false
            snapshot_id:
              constraints:
              - {custom_constraint: cinder.snapshot}
              description: The ID of the snapshot to create a volume from.
              immutable: false
              required: false
              type: string
              update_allowed: false
            swap_size: {description: 'The size of the swap, in MB.', immutable: false,
              required: false, type: integer, update_allowed: false}
            volume_id:
              constraints:
              - {custom_constraint: cinder.volume}
              description: The volume_id can be boot or non-boot device to the server.
              immutable: false
              required: false
              type: string
              update_allowed: false
            volume_size: {description: 'Size of the block device in GB. If it is omitted,
                hypervisor driver calculates size.', immutable: false, required: false,
              type: integer, update_allowed: false}
          type: map
          update_allowed: false
      type: list
      update_allowed: false
    config_drive: {description: 'If True, enable config drive on the server.', immutable: false,
      required: false, type: boolean, update_allowed: false}
    diskConfig:
      constraints:
      - allowed_values: [AUTO, MANUAL]
      description: Control how the disk is partitioned when the server is created.
      immutable: false
      required: false
      type: string
      update_allowed: false
    flavor:
      constraints:
      - {custom_constraint: nova.flavor}
      description: The ID or name of the flavor to boot onto.
      immutable: false
      required: true
      type: string
      update_allowed: true
    flavor_update_policy:
      constraints:
      - allowed_values: [RESIZE, REPLACE]
      default: RESIZE
      description: Policy on how to apply a flavor update; either by requesting a
        server resize or by replacing the entire server.
      immutable: false
      required: false
      type: string
      update_allowed: true
    image:
      constraints:
      - {custom_constraint: glance.image}
      description: The ID or name of the image to boot with.
      immutable: false
      required: false
      type: string
      update_allowed: true
    image_update_policy:
      constraints:
      - allowed_values: [REBUILD, REPLACE, REBUILD_PRESERVE_EPHEMERAL]
      default: REBUILD
      description: Policy on how to apply an image-id update; either by requesting
        a server rebuild or by replacing the entire server.
      immutable: false
      required: false
      type: string
      update_allowed: true
    key_name:
      constraints:
      - {custom_constraint: nova.keypair}
      description: Name of keypair to inject into the server.
      immutable: false
      required: false
      type: string
      update_allowed: false
    metadata: {description: Arbitrary key/value metadata to store for this server.
        Both keys and values must be 255 characters or less. Non-string values will
        be serialized to JSON (and the serialized string must be 255 characters or
        less)., immutable: false, required: false, type: map, update_allowed: true}
    name: {description: Server name., immutable: false, required: false, type: string,
      update_allowed: true}
    networks:
      description: An ordered list of nics to be added to this server, with information
        about connected networks, fixed ips, port etc.
      immutable: false
      required: false
      schema:
        '*':
          immutable: false
          required: false
          schema:
            fixed_ip:
              constraints:
              - {custom_constraint: ip_addr}
              description: Fixed IP address to specify for the port created on the
                requested network.
              immutable: false
              required: false
              type: string
              update_allowed: false
            floating_ip: {description: ID of the floating IP to associate., immutable: false,
              required: false, type: string, update_allowed: false}
            network:
              constraints:
              - {custom_constraint: neutron.network}
              description: Name or ID of network to create a port on.
              immutable: false
              required: false
              type: string
              update_allowed: false
            port:
              constraints:
              - {custom_constraint: neutron.port}
              description: ID of an existing port to associate with this server.
              immutable: false
              required: false
              type: string
              update_allowed: false
            port_extra_properties:
              description: Dict, which has expand properties for port. Used only if
                port property is not specified for creating port.
              immutable: false
              required: false
              schema:
                admin_state_up: {default: true, description: The administrative state
                    of this port., immutable: false, required: false, type: boolean,
                  update_allowed: true}
                allowed_address_pairs:
                  description: Additional MAC/IP address pairs allowed to pass through
                    the port.
                  immutable: false
                  required: false
                  schema:
                    '*':
                      immutable: false
                      required: false
                      schema:
                        ip_address:
                          constraints:
                          - {custom_constraint: net_cidr}
                          description: IP address to allow through this port.
                          immutable: false
                          required: true
                          type: string
                          update_allowed: false
                        mac_address:
                          constraints:
                          - {custom_constraint: mac_addr}
                          description: MAC address to allow through this port.
                          immutable: false
                          required: false
                          type: string
                          update_allowed: false
                      type: map
                      update_allowed: false
                  type: list
                  update_allowed: false
                binding:vnic_type:
                  constraints:
                  - allowed_values: [normal, direct, macvtap]
                  description: The vnic type to be bound on the neutron port. To support
                    SR-IOV PCI passthrough networking, you can request that the neutron
                    port to be realized as normal (virtual nic), direct (pci passthrough),
                    or macvtap (virtual interface with a tap-like software interface).
                    Note that this only works for Neutron deployments that support
                    the bindings extension.
                  immutable: false
                  required: false
                  type: string
                  update_allowed: true
                mac_address:
                  constraints:
                  - {custom_constraint: mac_addr}
                  description: MAC address to give to this port.
                  immutable: false
                  required: false
                  type: string
                  update_allowed: false
                port_security_enabled: {description: 'Flag to enable/disable port
                    security on the port. When disable this feature(set it to False),
                    there will be no packages filtering, like security-group and address-pairs.',
                  immutable: false, required: false, type: boolean, update_allowed: true}
                qos_policy:
                  constraints:
                  - {custom_constraint: neutron.qos_policy}
                  description: The name or ID of QoS policy to attach to this port.
                  immutable: false
                  required: false
                  type: string
                  update_allowed: true
                value_specs:
                  default: {}
                  description: Extra parameters to include in the request.
                  immutable: false
                  required: false
                  type: map
                  update_allowed: true
              type: map
              update_allowed: false
            subnet: {description: 'Subnet in which to allocate the IP address for
                port. Used for creating port, based on derived properties. If subnet
                is specified, network property becomes optional.', immutable: false,
              required: false, type: string, update_allowed: false}
            uuid:
              constraints:
              - {custom_constraint: neutron.network}
              description: ID of network to create a port on.
              immutable: false
              required: false
              type: string
              update_allowed: false
          type: map
          update_allowed: false
      type: list
      update_allowed: true
    personality:
      default: {}
      description: A map of files to create/overwrite on the server upon boot. Keys
        are file names and values are the file contents.
      immutable: false
      required: false
      type: map
      update_allowed: false
    reservation_id: {description: A UUID for the set of servers being requested.,
      immutable: false, required: false, type: string, update_allowed: false}
    scheduler_hints: {description: Arbitrary key-value pairs specified by the client
        to help boot a server., immutable: false, required: false, type: map, update_allowed: false}
    security_groups:
      default: []
      description: List of security group names or IDs. Cannot be used if neutron
        ports are associated with this server; assign security groups to the ports
        instead.
      immutable: false
      required: false
      type: list
      update_allowed: false
    software_config_transport:
      constraints:
      - allowed_values: [POLL_SERVER_CFN, POLL_SERVER_HEAT, POLL_TEMP_URL, ZAQAR_MESSAGE]
      default: POLL_SERVER_CFN
      description: How the server should receive the metadata required for software
        configuration. POLL_SERVER_CFN will allow calls to the cfn API action DescribeStackResource
        authenticated with the provided keypair. POLL_SERVER_HEAT will allow calls
        to the Heat API resource-show using the provided keystone credentials. POLL_TEMP_URL
        will create and populate a Swift TempURL with metadata for polling. ZAQAR_MESSAGE
        will create a dedicated zaqar queue and post the metadata for polling.
      immutable: false
      required: false
      type: string
      update_allowed: true
    user_data: {default: '', description: User data script to be executed by cloud-init.,
      immutable: false, required: false, type: string, update_allowed: true}
    user_data_format:
      constraints:
      - allowed_values: [HEAT_CFNTOOLS, RAW, SOFTWARE_CONFIG]
      default: HEAT_CFNTOOLS
      description: How the user_data should be formatted for the server. For HEAT_CFNTOOLS,
        the user_data is bundled as part of the heat-cfntools cloud-init boot configuration
        data. For RAW the user_data is passed to Nova unmodified. For SOFTWARE_CONFIG
        user_data is bundled as part of the software config data, and metadata is
        derived from any associated SoftwareDeployment resources.
      immutable: false
      required: false
      type: string
      update_allowed: false
    user_data_update_policy:
      constraints:
      - allowed_values: [REPLACE, IGNORE]
      default: REPLACE
      description: Policy on how to apply a user_data update; either by ignorning
        it or by replacing the entire server.
      immutable: false
      required: false
      type: string
      update_allowed: true
- {Field: resource_type, Value: 'OS::Nova::Server'}

attributes

这里我们就可以看到attributes下主要用来定义Server类型的输出信息,里面包括字符串类型的accessIPv4accessIPv6instance_namename,字典类型的addressesconsole_urlsnetworksshow。关于他们的用法,demo实例里面也可以窥知一二。

demo实例的输出

#输出列表
outputs:
  instance_name:
    description: Name of the instance.
    value: { get_attr: [ server, name ] }
  instance_ip:
    description: IP address of the instance.
    value: { get_attr: [ server, first_address ] }
  novnc_console_url:
    value: { get_attr: [server, console_urls, novnc] }
    description: all available console URLs for the server

很明显,stack创建成功后,他的属性里面就包含虚拟机的名称、虚拟机的ip地址以及novnc的访问地址。

properties

从上面的OS::Nova:Server可以看到Server类型的属性很多,其中我们常用的可能也就几个,例如availability_zoneflavorimagenetworkssecurity_groups

Demo实例中的属性

#资源列表
resources:
  server:
    type: OS::Nova::Server
    properties:
      image: Debian-Wheezy-7.11
      flavor: m1.medium
      networks:
      - network: { get_param: NetID }

这里可以看到,启动一个基本的Server资源至少需要3个属性,imageflavorNetwork

正题

明白了attributesproperties的用途,对于Heat的编排相当重要,那么下面我简单模拟下需要实现的一个需求。

需求1

1.创建一个虚拟机,要求虚拟机自定义镜像、flavor、network、可用域和安全组;
2.创建一个数据卷,要求数据卷自定义存储类型、可用域和块容量;
3.将数据卷挂载给虚拟机;
4.要求所有资源通过参数传入;
5.要求返回属性包含虚拟机uuid、ip地址和vnc地址;

这个需求很简单,我们只需要查下Heat支持的模板类型,很快就可以找到只需要三个类型就可以满足需求

  • type: OS::Nova::Server
  • type: OS::Cinder::Volume
  • type: OS::Cinder::Volume

模板如下:

CREATE_VM_VOLUME_AND_ATTACHE.yaml

heat_template_version: 2013-05-23

description:  Template for Create VM

parameters:
  image_id:
    type: string
    description:  Image ID or image name to use for the server
    constraints:
      - custom_constraint: glance.image
 
  secgroup_id:
    type: string
    description : Id of the security groupe

  network_id:
    type: string
    description: network id
 
  flavor_id:
    type: string
    description: Flavor for the server to be created 
    constraints:
      - custom_constraint: nova.flavor
   
  server_az:
    type: string
    description: Availablity zone of the VM
    default: nova

  volume_size:
    type: number
    description: Size of volume to attach to VM
    default: 1
    constraints:
      - range: { min: 1, max: 200 }
 
  volume_type:
    type: string
    description: If specified, the type of volume to use, mapping to a specific backend.
    
  volume_az:
    type: string

resources:
  server:
    type: OS::Nova::Server
    properties:
      availability_zone: { get_param: server_az }
      image: { get_param: image_id }
      flavor: { get_param: flavor_id }
      networks: 
      - network: { get_param: network_id }
      security_groups: 
      - { get_param: secgroup_id }

  volume:
    type: OS::Cinder::Volume
    properties:
      size: { get_param: volume_size }
      volume_type: { get_param: volume_type }
      availability_zone: { get_param: volume_az }
      description: Volume for stack

  volume_attachment:
    type: OS::Cinder::VolumeAttachment
    properties:
      volume_id: { get_resource: volume }
      instance_uuid: { get_resource: server }
 
outputs:
  server_id:
    value: { get_resource: server }
  server_ip:
    description: Network IP address of server
    value: { get_attr: [ server, first_address ] }
  novnc_console_url:
    value: { get_attr: [server, console_urls, novnc] }
    description: novnc console URLs for the server

创建也很简单

$ openstack stack create -t CREATE_VM_VOLUME_AND_ATTACHE.yaml \
--parameter volume_type=ceph \
--parameter volume_az=nova \
--parameter volume_size=10 \
--parameter image_id=908ea299-8eb2-4c92-b868-10e2c6120d10  \
--parameter secgroup_id=858dbd7e-8dd1-4fdd-8d3f-8c32ccdef07b  \
--parameter network_id=163df3b0-13f2-4f2e-8401-e82088e8dc07 \
--parameter flavor_id=m1.tiny \
--parameter server_az=nova \
cirros

需求2

1.在需求1的基础上添加批量创建资源,要求自定义数量
2.要求引入需求1的模板
3.要求返回一个批次stack里面的虚拟机uuid、虚拟机ip和vnc请求地址

这里我们需要学习一个新的资源类型OS::Heat::ResourceGroup,从名称就能够大概猜到该资源的作用:资源组,组内可以包括一个或多个相同的嵌套资源。

$ openstack orchestration resource type show OS::Heat::ResourceGroup

- Field: support_status
  Value: {message: null, previous_status: null, status: SUPPORTED, version: '2014.1'}
- Field: attributes
  Value:
    attributes: {description: 'A map of resource names to the specified attribute
        of each individual resource. Requires heat_template_version: 2014-10-16.',
      type: map}
    refs: {description: A list of resource IDs for the resources in the group., type: list}
    show: {description: Detailed information about resource., type: map}
- Field: properties
  Value:
    count:
      constraints:
      - range: {min: 0}
      default: 1
      description: The number of resources to create.
      immutable: false
      required: false
      type: integer
      update_allowed: true
    index_var:
      constraints:
      - length: {min: 3}
      default: '%index%'
      description: A variable that this resource will use to replace with the current
        index of a given resource in the group. Can be used, for example, to customize
        the name property of grouped servers in order to differentiate them when listed
        with nova client.
      immutable: false
      required: false
      type: string
      update_allowed: false
    removal_policies:
      default: []
      description: Policies for removal of resources on update.
      immutable: false
      required: false
      schema:
        '*':
          description: Policy to be processed when doing an update which requires
            removal of specific resources.
          immutable: false
          required: false
          schema:
            resource_list:
              default: []
              description: 'List of resources to be removed when doing an update which
                requires removal of specific resources. The resource may be specified
                several ways: (1) The resource name, as in the nested stack, (2) The
                resource reference returned from get_resource in a template, as available
                via the ''refs'' attribute. Note this is destructive on update when
                specified; even if the count is not being reduced, and once a resource
                name is removed, it''s name is never reused in subsequent updates.'
              immutable: false
              required: false
              type: list
              update_allowed: false
          type: map
          update_allowed: false
      type: list
      update_allowed: true
    resource_def:
      description: Resource definition for the resources in the group. The value of
        this property is the definition of a resource just as if it had been declared
        in the template itself.
      immutable: false
      required: true
      schema:
        metadata: {description: Supplied metadata for the resources in the group.,
          immutable: false, required: false, type: map, update_allowed: false}
        properties: {description: Property values for the resources in the group.,
          immutable: false, required: false, type: map, update_allowed: false}
        type: {description: The type of the resources in the group., immutable: false,
          required: true, type: string, update_allowed: false}
      type: map
      update_allowed: true
- {Field: resource_type, Value: 'OS::Heat::ResourceGroup'}

这里可以看到OS::Heat::ResourceGroup的属性如下

properties

  • 定义资源组包含子资源个数的数字类型count
  • 定义索引替换字符串的字符串类型index_var
  • 定义要从资源组中删除的子资源的list类型removal_policies
  • 子资源定义的字典类型resource_def

attributes

  • 输出子资源指定属性信息attributes
  • 输出所有子资源ID列表refs
  • 输出所有子资源详细信息show

模板如下:

**Multi_Num_VM_VOLUME_ATTACHE.yaml **

heat_template_version: 2013-05-23

description:  Template for Create VM Volume,the Volume will be auto Attached by heat.

parameters:
  
  num_resources:
    type: number
    description: Numbers of Resrouce 
    default: 1
    constraints:
      - range: { min: 1, max: 10 }

  image_id:
    type: string
    description: ID of the image to use for the instance to be created.
    constraints:
      - custom_constraint: glance.image

  secgroup_id:
    type: string
    description : Id of the security groupe

  network_id:
    type: string
    description: network id

  flavor_id:
    type: string
    description: Flavor for the server to be created
    constraints:
      - custom_constraint: nova.flavor

  server_az:
    type: string
    description: Availablity Zone of the VM
    default: nova

  volume_size:
    type: number
    description: Size of volume to attach to VM
    default: 1
    constraints:
      - range: { min: 1, max: 200 }

  volume_type:
    type: string
    description: If specified, the type of volume to use, mapping to a specific backend.

  volume_az:
    type: string
    description: Availability Zone of the Volumes


resources:
  resgroup:  
    type: OS::Heat::ResourceGroup  
    properties:  
      count: { get_param: num_resources }
      resource_def:
        type: CREATE_VM_VOLUME_AND_ATTACHE.yaml   #在这里引入了需求1的模板
        properties:
          image_id: { get_param: image_id }
          secgroup_id: { get_param: secgroup_id }
          network_id: { get_param: network_id }
          flavor_id: { get_param: flavor_id }
          server_az: { get_param: server_az }
          volume_size: { get_param: volume_size }
          volume_type: { get_param: volume_type }
          volume_az: { get_param: volume_az }
 
outputs:  
  myrefs:  
    value: {get_attr: [resgroup, refs]}  
  server_ids:
    value: {get_attr: [resgroup, server_id]}
  server_ips:
    value: {get_attr: [resgroup, server_ip]}
  server_novnc_urls:
    value: {get_attr: [resgroup, novnc_console_url]}

创建命令如下:

$ openstack stack create -t Multi_Num_VM_VOLUME_ATTACHE.yaml \
--parameter volume_type=ceph \
--parameter volume_az=nova \
--parameter volume_size=10 \
--parameter image_id=908ea299-8eb2-4c92-b868-10e2c6120d10  \
--parameter secgroup_id=858dbd7e-8dd1-4fdd-8d3f-8c32ccdef07b  \
--parameter network_id=163df3b0-13f2-4f2e-8401-e82088e8dc07 \
--parameter flavor_id=m1.tiny \
--parameter server_az=nova \
--parameter num_resources=3 \
cirros1

更多

经过以上两个实例,我相信大多数人对Heat编排都有一个大致了解,其实编排不难,难的是资源逻辑的整合。现在社区里面有一些开源的Heat模板,里面几乎包含了大部分的高级用法。感兴趣的朋友可以去了解下

$ git clone git://git.openstack.org/openstack/heat-templates

另外,目前最新的Pike版本中Heat的代码的贡献前五其中有两家中国公司HuaweiEasyStack。不简单啊,OpenStack在国内市场的普及,一个重要的指标还是看这家公司在社区里面的贡献,总之还是挺佩服他们的。

Heat的两个生产实例_第3张图片
Heat commit统计

你可能感兴趣的:(Heat的两个生产实例)