首页 / 资讯中心 / 文章详情

OpenStack 编排管理:Heat 把一台虚拟机写进模板里

OpenStack 编排管理:Heat 把一台虚拟机写进模板里 ★ FEATURED ARTICLE
OpenStack 编排管理Heat 把一台虚拟机写进模板里Heat 是 OpenStack 里的模板服务把虚拟机、网络、卷这些资源写成一份声明式模板一次描述、反复发放改一行参数就能重发一整套环境。这篇从组件分工讲到模板的四个必写段落再走 Web 与 CLI 两套部署实验最后讲嵌套模板怎么拆。一、Heat 是什么Heat 是一种通过 OpenStack 原生 REST API、使用声明性模板格式编排复合云应用的服务与其他 OpenStack 核心项目紧密集成。三个关键性质模板是文本文件描述云应用的基础架构用户可读写支持用版本控制工具如 git管理模板指定资源之间的关系Heat 能调用 OpenStack API 以正确的顺序创建所需的基础设施——先有网络再起虚拟机、先有密钥再注入实例顺序它来保证位置在 Nova、Neutron 等服务之上用户不需要直接接触其他服务把资源需求写在 Heat 模板里Heat 自动调相关服务的接口配置资源。它充当了 OpenStack 对外接口的角色。模板里的资源集合很广虚拟机、网络、存储、告警、浮动 IP、安全组、伸缩组、嵌套 stack 等——通过定义模板可以多次创建需要的资源。二、三个组件两个接单一个干活组件职责heat-api提供 REST API是其他组件与 Heat 交互的入口接收请求并传送给 heat-engineheat-api-cfn提供兼容AWS CloudFormation的 API接收请求并转发给 heat-engineheat-engineHeat 的核心实现任务调度、资源生命周期管理。注意它自身并不提供资源创建功能只负责编排资源然后交由其他组件各服务的 API去处理请求路径用户在 Horizon 或 CLI 提交「模板 参数」→ 转成 REST 调用 → heat-api 或 heat-api-cfn 验证模板正确性 →消息队列→ heat-engine 处理。验收命令heat 装在控制节点ps-e|grepheat# 三类进程heat-api / heat-api-cfn / heat-enginesystemctl status openstack-heat-*三、HOT 模板四段式结构3.1 模板语言YAMLHeat 模板默认编写语言是 YAMLYAML Ain’t Markup Language三条语法规则使用缩进一个或多个空格排版——缩进就是层级序列列表项用短划线-表示MAP 中的 key-value 对用冒号:表示——每个冒号后都要有空格即使冒号后没有内容实验中最容易栽的坑。3.2 四段式结构段作用关键点heat_template_version版本日期如2018-08-31、2015-10-15决定可用语法parameters参数区type/label/description/defaultconstraints做校验长度 min/max、allowed_pattern 正则、range 范围、custom_constraint 引用校验hidden: true隐藏敏感回显如密码resources资源区核心type: OS::Nova::Server等资源类型 properties属性内置函数取值outputs输出区stack 创建完成后回显信息get_attr取资源属性如实例 IP、私钥三个内置函数高频出现get_param取 parameters 里用户传入的参数get_resource引用本模板内定义的另一个资源比如 port 引用 subnetget_attr取某资源创建后的属性outputs 里用。3.3 常用资源类型OS::Nova::Server 虚拟机实例 OS::Nova::KeyPair 密钥对 OS::Neutron::Net 网络 OS::Neutron::Subnet 子网 OS::Neutron::Router 路由器 OS::Neutron::RouterInterface 路由器接口 OS::Neutron::FloatingIP 浮动 IP OS::Neutron::FloatingIPAssociation 浮动 IP 绑定 OS::Neutron::SecurityGroup 安全组 OS::Cinder::Volume 块存储卷查询环境支持的全部资源类型openstack orchestration resource type list。3.4 Heat StackStack堆栈 按模板创建出来的一整套资源实例。模板是「图纸」stack 是「按图纸盖好的楼」。常用命令命令说明openstack stack create -t 模板文件 [--parameter kv ...] 栈名用模板创建堆栈openstack stack event list 栈名查看创建过程事件流openstack stack list/stack show 栈名堆栈列表 / 详情状态CREATE_COMPLETE表示完成openstack stack output show --all 栈名查看 outputs 输出实例名、IP 等openstack stack delete 栈名删除堆栈交互确认加--yes跳过确认四、Web 实验一份模板全家桶先备好两样被模板引用的资源并记录它们的 ID创建外网或确认已有 External记录 public_net ID创建镜像记录 image ID。把下面模板存为heat.txt——凡是【 】括起来的占位符都要换成自己的值注释里保留了实验环境的原值供对照heat_template_version:2018-08-31# 模板版本决定这份模板能用哪些语法和函数description:Simple template to deploy a stack with one virtual machine instances# ---------- 参数区创建堆栈时传入没传就用 default 兜底 ----------parameters:image_name_1:# 参数1镜像 ID实例1要用type:stringlabel:Image IDdescription:Specify an image name for instance1default:【替换成你的镜像ID】# 实验环境值732c9cee-2652-4a4e-8c09-19745d6e15b5public_net:# 参数2外网 ID路由器网关和浮动 IP 都挂它type:stringlabel:Network IDdescription:Network to be used for the compute instancedefault:【替换成你的外网ID】# 实验环境值a6e27f03-e762-4c46-a997-a7a6848d5849# ---------- 资源区10 个资源Heat 按引用关系自动排创建顺序 ----------resources:mykey:# ① 密钥对save_private_keytrue 让 Heat 生成私钥type:OS::Nova::KeyPairproperties:save_private_key:truename:mykeyweb_secgroup:# ② 安全组只放行 SSH(22) 和 ping(ICMP)type:OS::Neutron::SecurityGroupproperties:rules:-protocol:tcp# 规则1TCP 22 端口源 0.0.0.0/0 任意来源remote_ip_prefix:0.0.0.0/0port_range_min:22port_range_max:22-protocol:icmp# 规则2ICMP 放行 pingprivate_net:# ③ 私有网络虚拟机真正住的网络type:OS::Neutron::Netproperties:name:private_netprivate_subnet:# ④ 子网network_id 用 get_resource 引用③type:OS::Neutron::Subnetproperties:network_id:{get_resource:private_net}cidr:192.168.99.0/24# 私网网段ip_version:4vrouter:# ⑤ 路由器外网网关指向参数里的外网type:OS::Neutron::Routerproperties:external_gateway_info:network:{get_param:public_net}vrouter_interface:# ⑥ 路由器接口把⑤和④接通私网才有出口type:OS::Neutron::RouterInterfaceproperties:router_id:{get_resource:vrouter}subnet_id:{get_resource:private_subnet}instance_port:# ⑦ 实例端口提前占好 IP、挂好安全组type:OS::Neutron::Portproperties:network:{get_resource:private_net}security_groups:-default# 默认安全组-{get_resource:web_secgroup}# 再挂②实例才通 SSH/ICMPfixed_ips:-subnet_id:{get_resource:private_subnet}# 从④的网段分 IPfloating_ip:# ⑧ 浮动 IP从外网池里申请一个type:OS::Neutron::FloatingIPproperties:floating_network_id:{get_param:public_net}association:# ⑨ 绑定关系把⑧绑到⑦端口上type:OS::Neutron::FloatingIPAssociationproperties:floatingip_id:{get_resource:floating_ip}port_id:{get_resource:instance_port}instance1:# ⑩ 虚拟机四样要素全部引用/参数拼装type:OS::Nova::Serverproperties:image:{get_param:image_name_1}# 镜像来自参数区key_name:{get_resource:mykey}# 密钥用①flavor:【替换成你的flavor名】# 实验环境值Flavor_webnetworks:-port:{get_resource:instance_port}# 用⑦的端口自带 IP 和安全组# ---------- 输出区stack 创建完成后回显信息 ----------outputs:private_key:description:Private keyvalue:{get_attr:[mykey,private_key]}# 取①生成的私钥登录实例要用这份模板一次描述了10 个资源——密钥对 安全组放行 22/ICMP 私网 子网 路由器 路由器接口 实例端口 浮动 IP 绑定关系 虚拟机对照网络管理实验这就是把「建网络、连路由、绑浮动 IP、配安全组、发实例」全流程写成一份文件。逐段拆解参数区两个 IDimage_name_1实例用的镜像 ID。写成参数而不是写死在资源里是为了换环境时只改default一行或创建时用--parameter覆盖模板本身不用动public_net外网 ID被⑤路由器网关和⑧浮动 IP 两处get_param引用——所有跟外网沾边的东西全挂它。资源区10 个资源四条线网络主线③④⑤⑥先有私有网络再有子网network_id用get_resource引用③路由器外网网关指向public_net最后路由器接口把子网挂上路由器——私网从这里通向外界。这四步就是实操篇「建网络、连路由」的原样复刻实例接入⑦⑩端口提前占好网段内的 IP、挂上 default ②两组安全组虚拟机的networks写的是这个 port 而不是网络名——因为固定 IP 和安全组都配在端口上实例挂端口就把这些配置一起继承外网可达⑧⑨从外网池申请一个浮动 IP再由绑定关系把它绑到实例端口上外网才能 SSH 进来安全与密钥①②安全组只放行 TCP 22 和 ICMP别的全拒密钥对因save_private_key: true由 Heat 生成私钥——私钥不落盘在服务端只在 outputs 里回显给你。输出区创建完成后取回①的私钥——用openstack stack output show --all 栈名拿到私钥内容才能登录实例。没有这一段私钥就只存在 Heat 那里拿不出来了。三个内置函数的出场位置对应着看get_param出现在⑤⑧⑩从参数区取外网和镜像get_resource出现在④⑥⑦⑨⑩模板内资源互相引用get_attr只在输出区出现取创建完成后的属性。那 Heat 怎么知道「先建网络、最后建虚拟机」模板里从头到尾没写一行顺序但每个引用get_resource/get_param本身就是依赖声明虚拟机引用了端口端口引用了网络和子网……Heat 把这些引用关系梳理成依赖图按拓扑顺序自动创建——这正是开篇说的「模板指定资源之间的关系Heat 能以正确的顺序创建」。创建堆栈「项目 编排 堆栈」→「创建堆栈」→ 选择模板文件 heat.txt → 提交。创建完成后实例、网络、浮动 IP 全部就位。五、CLI 实验从单机到嵌套sourcekeystonerc_admin# 清场删掉现有实例避免资源不足openstack server list openstack server delete INSTANCE_NAME/ID# 备好四样资源openstack image list / flavor list / keypair list / network list5.1 最简单模板demo-template.yamlheat_template_version:2015-10-15# 版本决定可用语法parameters:NetID:# 唯一参数实例要接入的网络 IDtype:stringdescription:Network ID to use for the instance.resources:server:# 只有一个资源一台虚拟机type:OS::Nova::Serverproperties:image:Img_cli# 【替换成你的镜像名】flavor:Flavor_cli# 【替换成你的flavor名】key_name:KeyPair_cli# 【替换成你的密钥对名】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]}# 回显实例 IP创建并验收exportNET_ID【替换成shared网络的ID】 openstack stack create-tdemo-template.yaml--parameterNetID$NET_IDStack_demo openstack stack event list Stack_demo# 看创建过程openstack stack list# CREATE_COMPLETE 即完成openstack stack output show--allStack_demo# 输出实例名和 IPopenstack server list# 实例已就位5.2 带约束的模板hello_world.yaml在 demo 基础上加了三样东西constraints 校验image/flavor/key_name 用custom_constraintglance.image、nova.flavor、nova.keypair自动校验存在性admin_pass 要求长度 6~8、纯字母数字、大写开头db_port 限定 40000~60000hidden: trueadmin_pass 是密码创建时不回显user_data str_replace实例首次启动时执行脚本db_port占位符被get_param的值替换——这是 Heat 做软件配置编排的入口。# 【 】里换成自己环境的资源名其余照抄openstack stack create-thello_world.yaml\--parameterimage【你的镜像名】--parameterflavor【你的flavor名】\--parameterkey_name【你的密钥对名】--parameterNetID【你的网络名】\--parameteradmin_pass【6~8位大写开头字母数字】 Stack_helloworld_cli# 同一份模板换一套参数再发一套——这就是「一次编写、多次发放」openstack stack create-thello_world.yaml\--parameterimage【你的镜像名】--parameterflavor【你的flavor名】\--parameterkey_name【你的密钥对名】--parameterNetID【你的网络名】\--parameteradmin_pass【6~8位大写开头字母数字】 Stack_helloworld_web对比两份模板的区别demo 的参数只有一个 NetID、资源写死hello_world 参数化程度高、带校验和初始化脚本——模板越通用参数化越彻底。5.3 嵌套模板主模板引用子模板子模板my_nova.yaml只定义一台实例key_name 和 NetID 暴露为参数heat_template_version:2015-04-30parameters:key_name:# 密钥名暴露为参数由主模板传入type:stringNetID:# 网络 ID 同样暴露为参数type:stringresources:server:# 子模板只干一件事按传入参数起一台实例type:OS::Nova::Serverproperties:image:Img_cliflavor:Flavor_clikey_name:{get_param:key_name}networks:-network:{get_param:NetID}主模板main.yamlresources.type 直接写子模板文件名属性照常传参heat_template_version:2015-04-30resources:my_server:# type 直接写子模板文件名当成一种「资源类型」用type:my_nova.yamlproperties:# 属性名对应子模板 parameters 里的参数名key_name:【替换成你的密钥对名】# 实验环境值KeyPair_cliNetID:【替换成你的网络ID或名】# 实验环境值Network_cli_01openstack stack create-tmain.yaml Stack_nest openstack stack event list Stack_nest嵌套的意义把大架构拆成可复用的积木——主模板管编排子模板管单件。5.4 删除堆栈连坐机制openstack stack delete Stack_demo# 交互式提示确认输入 y 或回车openstack stack delete--yesStack_nest# 静默式不询问直接删openstack stack list# 空了openstack server list# 也空了结论由堆栈创建的虚拟机实例会随着堆栈的删除而删除——stack 是资源的「全家桶」。实际工作中建议用交互确认式删除避免误删--yes适合脚本自动化。六、Heat 的编排能力全景概念加分项场景说明基础设施编排计算/网络/存储按模板与依赖关系一键创建本篇实验软件配置与部署user_data cloud-init 在实例首启时装软件、改配置自动伸缩配合伸缩组与告警Ceilometer/Aodh 提供数据按负载自动加减实例负载均衡编排模板里直接创建 LB 成员与监听与配置管理工具集成Ansible/Puppet 等作为部署后环节接进模板七、命令速查总表命令关键选项/参数说明openstack stack create-t 模板--parameter kv可多次--parameter k$VAR创建堆栈openstack stack event list栈名查看创建/删除过程事件openstack stack list/show—列表看状态/ 详情openstack stack output show--all查看模板 outputsopenstack stack delete加--yes跳过确认删除堆栈连坐删资源openstack orchestration resource type list—查询支持的资源类型ps -e | grep heat—验收三个 heat 进程附关键英文全称缩写全称含义HOTHeat Orchestration TemplateHeat 原生模板格式YAMLYAML Ain’t Markup Language递归缩写模板语言Stack—堆栈按模板创建的资源集合CFNCloudFormationAWS 的编排服务heat-api-cfn 兼容其 APIget_param / get_resource / get_attr—取参数 / 引用模板内资源 / 取资源属性 参考资料官方文档Heat 官方文档组件架构、栈生命周期、CLIhttps://docs.openstack.org/heat/latest/Heat Template GuideHOT 模板结构parameters / resources / outputs 与内置函数https://docs.openstack.org/heat/latest/template_guide/index.html
阅读完成 · 觉得有帮助?
咨询建站