Heat 模板 搭建集羣初探

最近公司要求用heat模板在openstack集羣上部署公司的分佈式數據庫GOS產品,簡單研究了下,記錄之:


在這次使用中heat最主要的功能就是在openstack上搭建起GOS集羣所需的虛擬機以及存儲,然後調用GOS的安裝腳本安裝GOS。
如下是寫好的heat腳本,邊貼邊說明:

首先是模板版本,主要注意的是heat模板支持3種書寫格式(hot,yaml,json),但不能混用,本文以hot爲例。如下 heat_template_version 就是hot的書寫格式,關於每種格式如何書寫請參考http://docs.openstack.org/developer/heat/template_guide/index.html。

heat_template_version: 2012-12-12
 
description: Simple template of gaoxiaoxin

然後是模板的傳參,以parameters開頭,每個參數都至少包含類型和描述;除此之外還可以後默認值,值約束等。
其中有幾個參數非常通用:
image  這個參數這裏用於標識 heat腳本起 nova 虛擬機所用的光盤鏡像,一般要寫光盤資源對應的UUID。
flavor  這個參數這裏用於標識heat腳本所起的nova虛擬機的資源分配策略。
public_net_id  這個參數這裏用於標識heat模板爲nova虛擬機分配對外浮動ip的網卡
private_net_name  這個參數這裏用於標識heat模板爲nova虛擬機分片平臺內部ip的網卡
每個openstack平臺的虛擬機都會分配一個內部ip如10.0.0.x,該ip無法被openstack平臺以外的機器訪問,這時
就需要爲該虛擬機綁定一個浮動ip,該ip與外網機器可以互通,如172.16.90.x

parameters:
  os_user:
    type: string
    description: User name to do operation
  os_password:
    type: string
    hidden: true
    description: Password for os_user
  os_tenant:
    type: string
    description: Tenant name to use this template
  os_auth_url:
    type: string
    description: the ip of auth server
  volume_size:
    type: string
    default: 10
    description: Size of volume for pm (G)
  server_password:
    type: string
    default: abc123
    description: the password to be set as the root user of server
  install_packet_url:
    type: string
    description: the download url of GOS install packet
  key_name:
    type: string
    default: gao
    description: Name of keypair to assign to servers
  pm_num:
    type: number
    default: 2
    min_value: 2
    description: Numof PM servers
  image:
    type: string
    default: 8f0c0332-4d72-424d-9887-ed443e638d30
    description: Name of image to use for servers
  flavor:
    type: string
    default: m1.small
    description: Flavor to use for servers
    constraints:
      - allowed_values: [m1.tiny, m1.small, m1.large]
        description: Value must be one of 'm1.tiny', 'm1.small' or 'm1.large'
  public_net_id:
    type: string
    default: 480a65d1-d934-409c-8c7c-d17d83e18847
    description: >
      ID of public network for which floating IP addresses will be allocated
  private_net_name:
    type: string
    default: 7bffd5aa-bf4c-4e2e-a736-e388573377b5
    description: Name of private network to be created
  install_glusterfs:
    type: string
    default: 0
    description: Whether to install glusterfs for data storage(1/0)

接下來就是最重要的部分,heat模板所以啓動的資源,以resources開頭:
如下的host_um1和host_um2爲2個nova 虛擬機的模板,每個虛擬機都通過port綁定的浮動ip,可以與外網互通訪問。每個虛擬機的模板中都指明瞭這個虛擬所使用的鏡像(參數image)和虛擬機資源分片策略(參數flavor)。另外每個虛擬機都可以通過user_data來指定一段shell腳本,該腳本會在虛擬機啓動並對外提供服務執行執行完成。腳本可以通過使用str_replace來使用heat模板中其他資源作爲參數。


resources:

  host_um1:
    type: OS::Nova::Server
    properties:
      name : server_um1
      image: { get_param: image }
      flavor: { get_param: flavor }
      key_name: { get_param: key_name }
      networks:
        - port: { get_resource: server1_port }
      user_data:
        str_replace:
          template: |
            #!/bin/bash -v
            service iptables stop

            # set root password
            printf "$root_passwd" | passwd --stdin root

          params:
            $root_passwd: {get_param: server_password}


  server1_port:
    type: OS::Neutron::Port
    properties:
      network_id: { get_param: private_net_name }
      fixed_ips:
        - subnet_id: 46bdaaa0-28a4-40a6-a2ca-b881ece5db0b


 server1_floating_ip:
    type: OS::Neutron::FloatingIP
    properties:
      floating_network_id: { get_param: public_net_id }
      port_id: { get_resource: server1_port }

  host_um2:
    type: OS::Nova::Server
    properties:
      name : server_um2
      image: { get_param: image }
      flavor: { get_param: flavor }
      key_name: { get_param: key_name }
      networks:
        - port: { get_resource: server2_port }
      user_data:
        str_replace:
          template: |
            #!/bin/bash -v
            service iptables stop

            # set root password
            printf "$root_passwd" | passwd --stdin root

          params:
            $root_passwd: {get_param: server_password}


  server2_port:
    type: OS::Neutron::Port
    properties:
      network_id: { get_param: private_net_name }
      fixed_ips:
        - subnet_id: 46bdaaa0-28a4-40a6-a2ca-b881ece5db0b

  server2_floating_ip:
    type: OS::Neutron::FloatingIP
    properties:
      floating_network_id: { get_param: public_net_id }
      port_id: { get_resource: server2_port }


如下的資源模板與上面的不同,使用的是AWS::AutoScaling::LaunchConfiguration。通常這與 OS::Heat::InstanceGroup(當然還有其他)配合使用來啓動一組配置相同的虛擬機。
因爲heat是模板語言,它本身不支持如for或while之類的循環,所以如果要啓用一組類似的資源的話,只能使用特殊的模板如
InstanceGroup。InstanceGroup本身有些使用限制,如它目前只能使用
AWS::AutoScaling::LaunchConfiguration來設定instance模板,無法綁定浮動IP(這也是爲什麼我單獨弄了2個獨立的server用於綁定浮動ip以便外網程序可以訪問集羣),無法指定生成內部ip的網卡,所以如果heat模板所在的openstack項目有2個網卡的話,就會報錯。 當然有其他用於定義一組資源的組件可以指定內部ip網卡,如AWS::AutoScaling::AutoScalingGroup, 但目前只有InstanceGroup可以獲取組內資源的ip。(新手冊裏有個resourcegroup,應該也可以獲取組內成員信息,但最新release的heat裏並不包含這個組件,很多官網手冊裏說的組件在最新release裏都找不到或功能不全。。。)

AWS::AutoScaling::LaunchConfiguration定義的server模板中,我通過userdata的啓動腳本來爲虛擬機創建和掛載存儲。亞馬遜的AWS模板AWS::AutoScaling::LaunchConfiguration本身是有自動創建存儲的選項,但heat裏的AWS::AutoScaling::LaunchConfiguration組件還不支持,手冊上說沒有實現。。。



  host_pm:
    type: AWS::AutoScaling::LaunchConfiguration
    properties:
      ImageId: { get_param: image }
      InstanceType: { get_param: flavor }
      KeyName: { get_param: key_name }
      UserData:
        str_replace:
          template: |
            #!/bin/bash -v
            mkdir /root/gaoxiaoxin
            service iptables stop

            # set root password
            printf "$root_passwd" | passwd --stdin root

            # enable remote password login
            sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config

            # get ip address to generate volume name
            IP=`ifconfig  | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}'`
            echo $IP > /tmp/ip

            # get the resource uuid of this server
            server_id=`nova --os-username $os_name --os-password $os_password --os-tenant-name "$os_tenant" --os-auth-url http://$os_auth_url:5000/v2.0 list --ip $IP | grep -o -P '\w{8}-\w{4}-\w{4}-\w{4}-\w{12}' | awk '{ print $1}'`

            echo $server_id > /tmp/server_id

            # create the volume
            nova --os-username $os_name --os-password $os_password --os-tenant-name "$os_tenant" --os-auth-url http://$os_auth_url:5000/v2.0 volume-create --display-name "vol$IP" $volume_size

            # get the resource uuid of this volume
            volume_id=`nova --os-username $os_name --os-password $os_password --os-tenant-name "$os_tenant" --os-auth-url http://$os_auth_url:5000/v2.0 volume-list | grep vol$IP | grep -o -P '\w{8}-\w{4}-\w{4}-\w{4}-\w{12}'`

            echo $volume_id > /tmp/volume_id

      
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章