最近公司要求用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
# wait volume to be avaliable
sleep 20;
# attach the volume to this server
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-attach $server_id $volume_id /dev/vdb
while [ ! -e "/dev/vdb" ];
do
sleep 1;
done
fdisk -l;
# mount
mkfs -t ext4 /dev/vdb
if [ $install_glusterfs = "0" ] ; then
mkdir -p /usr/local/GOS
mount /dev/vdb /usr/local/GOS
else
mkdir -p /root/volumes
mount /dev/vdb /root/volumes
fi
params:
$root_passwd: {get_param: server_password}
$os_name: {get_param: os_user}
$os_password: {get_param: os_password}
$os_tenant: {get_param: os_tenant}
$os_auth_url: {get_param: os_auth_url}
$volume_size: {get_param: volume_size}
$install_glusterfs: {get_param: install_glusterfs}
worker_group:
type: OS::Heat::InstanceGroup
properties:
LaunchConfigurationName: {Ref: host_pm}
Size: {get_param: pm_num}
AvailabilityZones: []
最后说下调试:
heat模板的调试只能通过日志来看:模板的验证的日志为heat-api.log, 模板运行过程中的日志为heat-engine.log。
heat模板本身是个很不错的思路,用模板来简化部署。但目前heat还很不成熟,手册和release出来的程序对应不上,还不是openstack的官方组件。。。
转载请注明转自高孝鑫的博客
在这次使用中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
flavor
public_net_id
private_net_name
每个openstack平台的虚拟机都会分配一个内部ip如10.0.0.x,该ip无法被openstack平台以外的机器访问,这时
就需要为该虚拟机绑定一个浮动ip,该ip与外网机器可以互通,如172.16.90.x
parameters:
接下来就是最重要的部分,heat模板所以启动的资源,以resources开头:
如下的host_um1和host_um2为2个nova 虚拟机的模板,每个虚拟机都通过port绑定的浮动ip,可以与外网互通访问。每个虚拟机的模板中都指明了这个虚拟所使用的镜像(参数image)和虚拟机资源分片策略(参数flavor)。另外每个虚拟机都可以通过user_data来指定一段shell脚本,该脚本会在虚拟机启动并对外提供服务执行执行完成。脚本可以通过使用str_replace来使用heat模板中其他资源作为参数。
resources:
如下的资源模板与上面的不同,使用的是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组件还不支持,手册上说没有实现。。。
最后说下调试:
heat模板的调试只能通过日志来看:模板的验证的日志为heat-api.log, 模板运行过程中的日志为heat-engine.log。
heat模板本身是个很不错的思路,用模板来简化部署。但目前heat还很不成熟,手册和release出来的程序对应不上,还不是openstack的官方组件。。。
转载请注明转自高孝鑫的博客