前言
heat是对openstack资源的编排工具,编排可以理解为自动化。
在heat中,将一次编排任务称之为stack。创建编排就是创建一个stack。
演示使用 python-heatclient 创建特定需求的虚拟机。
涉及非常多的新知识,这篇文章只能至简的介绍使用。
环境
python2
openstack版本:queens
模板格式:HOT
正文
这里可以拆分为3个部分:
- python-heatclient:主体运行程序
- yaml文件:定义资源的规格,可以编写简单的逻辑。
- 虚拟机执行脚本:虚拟机开机时执行的脚本,这个可以整合在yaml文件中,也可以独立出来。
总体流程:
- 准备好配置文件,参数
- 创建stack
运行一个实例
- 准备yaml文件。
yaml文件直接引用官方给出的例子,不做任何修改。
地址:
https://github.com/openstack/heat-templates/blob/master/hot/servers_in_existing_neutron_net.yaml
贴出其中的内容:
heat_template_version: 2013-05-23
description: >
HOT template to deploy two servers into an existing neutron tenant network and
assign floating IP addresses to each server so they are routable from the
public network.
parameters:
key_name:
type: string
description: Name of keypair to assign to servers
image:
type: string
description: Name of image to use for servers
flavor:
type: string
description: Flavor to use for servers
public_net_id:
type: string
description: >
ID of public network for which floating IP addresses will be allocated
private_net_id:
type: string
description: ID of private network into which servers get deployed
private_subnet_id:
type: string
description: ID of private sub network into which servers get deployed
resources:
server1:
type: OS::Nova::Server
properties:
name: Server1
image: { get_param: image }
flavor: { get_param: flavor }
key_name: { get_param: key_name }
networks:
- port: { get_resource: server1_port }
server1_port:
type: OS::Neutron::Port
properties:
network_id: { get_param: private_net_id }
fixed_ips:
- subnet_id: { get_param: private_subnet_id }
security_groups: [{ get_resource: server_security_group }]
server1_floating_ip:
type: OS::Neutron::FloatingIP
properties:
floating_network_id: { get_param: public_net_id }
port_id: { get_resource: server1_port }
server2:
type: OS::Nova::Server
properties:
name: Server2
image: { get_param: image }
flavor: { get_param: flavor }
key_name: { get_param: key_name }
networks:
- port: { get_resource: server2_port }
server2_port:
type: OS::Neutron::Port
properties:
network_id: { get_param: private_net_id }
fixed_ips:
- subnet_id: { get_param: private_subnet_id }
security_groups: [{ get_resource: server_security_group }]
server2_floating_ip:
type: OS::Neutron::FloatingIP
properties:
floating_network_id: { get_param: public_net_id }
port_id: { get_resource: server2_port }
server_security_group:
type: OS::Neutron::SecurityGroup
properties:
description: Add security group rules for server
name: security-group
rules:
- remote_ip_prefix: 0.0.0.0/0
protocol: tcp
port_range_min: 22
port_range_max: 22
- remote_ip_prefix: 0.0.0.0/0
protocol: icmp
outputs:
server1_private_ip:
description: IP address of server1 in private network
value: { get_attr: [ server1, first_address ] }
server1_public_ip:
description: Floating IP address of server1 in public network
value: { get_attr: [ server1_floating_ip, floating_ip_address ] }
server2_private_ip:
description: IP address of server2 in private network
value: { get_attr: [ server2, first_address ] }
server2_public_ip:
description: Floating IP address of server2 in public network
value: { get_attr: [ server2_floating_ip, floating_ip_address ] }
创建一个template文件,将内容完整的复制进去:
vim servers_in_existing_neutron_net.yaml
- 创建stack
这个template文件大体是创建了一个带浮动ip的虚拟机,并且创建了一个安全组绑定到虚拟机端口上。
创建python 程序:
vim client.py
# coding:utf8
from keystoneauth1 import session
from keystoneauth1.identity import v3
from heatclient import client as heat_client
# 注意替换认证信息
auth = v3.Password(
auth_url="http://192.168.110.10:35357/v3",
username="admin",
password="qwe",
project_id="97eaa64704bd4f549f3abf99a6decdc1",
user_domain_id='default')
sess = session.Session(auth=auth)
hc = heat_client.Client('1', session=sess)
# 注意替换模板路径
template_path = "./servers_in_existing_neutron_net.yaml"
# 注意替换 镜像等信息。这里的 parameters 就是模板中定义的参数
parameters = {
"key_name": "be8ee056ea274d45a1fd97bfd36c2775_lzp",
"image": "cirros",
"flavor": "cc00d88f-9ed5-4012-9840-faf8add2873d",
"public_net_id": "4955888e-1622-4a2b-88d7-2c58e092e7fa",
"private_net_id": "77844f4d-0dd8-4532-bbaa-d17efd5a1895",
"private_subnet_id": "9a7bfada-fd99-4ac4-a4a0-66e872019bc1"
}
template = open(template_path).read()
stack_name = "test1"
with open(template_path, "r") as f:
stack = hc.stacks.create(
stack_name=stack_name,
template=f.read(),
parameters=parameters
)
print(stack)
运行即可。
可以通过命令行查看进度:
openstack stack list
image.png
扩展
outputs
在template中尾部定义了 outputs。用于保留这个stack的某些重要信息。不需要可以不定义。
代码参考:
stack_id = "4d05cb2d-76a0-4ca4-a484-494ddcdcd243"
# 列出output列表
outputs = hc.stacks.output_list(stack_id=stack_id)
print(outputs)
# 显示output中某个键值对
server1_public_ip = hc.stacks.output_show(stack_id=stack_id, output_key="server1_public_ip")
print(server1_public_ip)
参考
模板例子参考:
https://github.com/openstack/heat-templates
模板配置详情参考:
https://docs.openstack.org/heat/rocky/template_guide/hot_spec.html#hot-spec
python-heatclient 参考:
https://github.com/openstack/python-heatclient
heat api 参考:
https://developer.openstack.org/api-ref/orchestration/v1/index.html?expanded=create-stack-detail#stacks
网友评论