OpenStack系列(二十) 自动化云应用概述
1 | 作者:李晓辉 |
自动化概述
你知道现在搞应用自动化部署那事儿有多复杂吗?以前部署个应用到单台服务器上,那简直小菜一碟,随便用点啥方法都能搞定。你可以自己搭个镜像,或者在运行时初始化和定制实例,甚至用软件配置管理工具来搞定单台服务器上的应用。但现在的应用可不一样了,都是集群式的,各种资源相互依赖,还分布在混合云数据中心里。今天咱们就来聊聊Heat Orchestration Service 和Ansible这俩玩意儿。
云规模的自动化得用那种功能强大又灵活的工具,得能认出所有 OpenStack 资源类型,包括那些定义资源之间关系和依赖关系的。搞云应用自动化一般分两步:
第一步是 Provisioning(配置),就是搭建和配置应用需要的底层基础设施。
第二步是 Deployment(部署),就是在配置好的基础设施上安装和配置应用。
Heat Orchestration Service
说到配置,特别是那种复杂得不行、资源层级套了好几层的应用,Heat Orchestration Service 可是首选。这玩意儿是 OpenStack 的核心组件,跟身份服务和其他服务都集成得特别好。虽然它能搞定软件部署,但要是遇到超复杂的部署,就有点吃力了。不过 Heat 的好处还是挺多的:
它能搞定各种 OpenStack 资源类型,像实例、浮动 IP、网络、子网、卷、卷挂载、告警之类的,啥都有。
还有资源组,能让你随便创建多少个配置好的资源,哪怕这些资源是复杂的嵌套堆栈也没问题。
管理自动扩展组,能根据设定的指标自动扩展实例和相关资源。
能并行部署资源,只要能并行的就自动并行。
能搞定资源依赖关系,保证资源按正确的顺序创建。
还能对正在运行的堆栈进行增强和配置调整。
删除堆栈的时候,一个命令就能搞定,而且会按照依赖顺序删除资源。
Ansible
Ansible Playbooks 和编排模板有点像,用的是简单明了的 YAML 语法。Ansible 通常用来配置已经定义在清单文件中的基础设施。Ansible 的功能特别强大,有大量的核心模块和各种硬件、操作系统的集合。
Ansible 定义了一系列要执行的任务,这些任务可以组合成剧本(playbooks)和角色(roles)。剧本就是按照顺序在清单中的一个或多个主机上运行一系列任务。角色是一组任务,设计成模块化、可复用的,比如部署一个多节点的 Galera 集群,或者一个 LAMP 堆栈。Ansible 的好处也有不少:
能在几台主机或者几百台主机上部署相同的配置。
能搞定已经配置好的基础设施。
通过角色支持可复用性,能在不同主机上重复使用相同的软件配置。
通过 OpenStack Ansible 模块,还能搞定 OpenStack 资源的配置。
Ansible 剧本可以配置并行资源创建,不过得考虑清单中主机的性能限制。资源依赖顺序是通过任务顺序明确处理的。删除资源通常是通过创建新任务和参数来反向排序。
Red Hat 建议把编排和 Ansible 结合起来用,这样才能搞定复杂应用的扩展。要是要部署的开发实例超过几个,就用编排,因为它本来就是为了搭建和拆除完整的生产环境而设计的,包括支持资源和网络,一直到第二层。用 Ansible 来配置实例上的应用和软件配置。因为这两种方法都用文本文件,所以可以用 Git 这样的版本控制系统来管理配置版本,跟踪基础设施和软件的变化。
Orchestration Service 架构
编排服务项目一开始是为了兼容 CloudFormation(CFN)模板格式设计的,现在还支持。不过现在原生的 Heat Orchestration Template(HOT)格式更常用了。HOT 模板可以用仪表盘里的模板生成器或者文本编辑器来创建文件。配置好的堆栈可以从命令行或者仪表盘来部署或者删除。
你知道编排服务是怎么工作的吗?简单来说,就是把堆栈模板和环境文件里的输入参数一起传给编排引擎。然后,编排引擎解析这些模板和文件,开始部署堆栈。通过查看编排引擎生成的事件,就能追踪堆栈部署的状态了。这里有几个重要的编排服务参数:
num_engine_workers:这是在主机上运行的 heat-engine 进程数量。默认值要么是运行 heat-engine 服务的主机上的 CPU 数量,要么是 4,取两者中的较大值。
stack_action_timeout:这是等待堆栈创建或更新完成的默认超时时间,单位是秒。默认值是 3600 秒,也就是 1 个小时。
编排的最佳实践
编排模板可以重复使用,用来创建相同堆栈的多个副本。为了让模板更通用,可以采用模块化设计,把堆栈模板文件做成可以嵌套的形式,这样就能在其他模板里导入它们。当创建堆栈时,可以用环境文件传入特定于堆栈的参数,比如资源名称和地址。这些最佳实践能帮你更好地规划和组织堆栈部署:
用多层嵌套堆栈:这样管理起来更方便。要是用一个大而全的模板,随着堆栈规模扩大,管理起来会很麻烦,而且一旦出问题,排查起来也更复杂。
- 示例:假设你有一个复杂的多层应用,可以通过嵌套堆栈将每个层级(如数据库层、应用层、前端层)分别定义为一个子堆栈,然后在主堆栈中引用这些子堆栈。
别用硬编码的资源名称和 ID:这样会导致堆栈很难复用。用参数来定义名称,然后在环境文件里设置这些参数。
- 示例:在模板中定义一个参数
resource_name
,在环境文件中为它赋值,这样可以在不同堆栈实例中使用不同的名称而无需修改模板。
- 示例:在模板中定义一个参数
先做干运行(dry run):在真正部署之前,先运行一次,看看有没有资源冲突或者语法错误。虽然干运行不能保证堆栈一定能创建成功,但至少能提前发现一些问题。
- 命令示例:
openstack stack create --dry-run --template my_template.yaml --environment my_env.yaml
- 命令示例:
检查资源配额:确保你估算的 CPU、内存和磁盘空间等资源用量没有超过项目的配额限制。
- 提示:可以通过
openstack limits show
命令查看当前项目的配额限制。
- 提示:可以通过
用约束定义输入参数:这样可以提前检查输入的格式和值是否有效,避免在创建堆栈时才发现问题。
- 示例:在模板中为参数添加约束,如
constraints: { allowed_values: [small, medium, large] }
。
- 示例:在模板中为参数添加约束,如
用命令验证模板:用
openstack orchestration template validate
命令来验证模板,看看资源值和结构有没有问题。验证可以发现缺失的依赖或者循环依赖。- 命令示例:
openstack orchestration template validate --template my_template.yaml
- 命令示例:
编排的用户权限
编排服务用堆栈所有者的角色权限来创建堆栈和资源。但是,为了实现最小权限原则,运行在已部署实例中的任务是由权限受限的用户来执行的。这些用户只能在特定的堆栈里运行任务。为了实现这种安全机制,编排服务会创建一个 heat_stack
域和一个 heat_stack_domain_admin
用户,这个用户有域级别的管理员权限。
1 | (overcloud) [stack@director ~]$ openstack role assignment list --domain heat_stack --names -c Role -c User -c Domain |
说到堆栈创建,如果里面有需要使用有限权限用户的资源,那可就有点复杂了。heat_stack_domain_admin
用户会创建一个新的堆栈域项目和一个有限权限的堆栈域用户,这个用户在 heat_stack
域里有 heat_stack_user
角色。这个有限权限的堆栈域用户和堆栈所有者的项目或用户没有任何关系。它会被分配一个访问令牌,这个令牌只能访问特定的堆栈资源和元数据。
有限权限用户在实例里能干啥?
提供元数据给实例里的代理:编排服务会把元数据提供给实例里运行的代理,这些代理会去拉取并应用配置。
发送信号给编排引擎:比如当
cloud-init
应用软件配置成功或者失败的时候,就会发送一个信号。从实例里向编排引擎报告状态或性能指标:比如某个应用会从实例里向编排引擎报告自己的状态或者性能指标,这样就能触发自动扩展操作。
编排服务的故障排查
大多数问题都是在堆栈部署的时候冒出来的。常见的错误有:
YAML 语法错误:如果你修改了现有的模板,很容易不小心引入 YAML 语法错误。可以用工具,比如
python -m json.tool
,来帮忙找这些错误。还可以用openstack stack create --dry-run
命令选项来验证 YAML 语法。模板结构验证:用
openstack orchestration template validate
来验证模板的资源结构。验证可以发现缺失的依赖或者循环依赖。
要是你在启动堆栈的时候发现实例变成了 ERROR
状态,那可能是因为实例被调度到的节点资源不够。要是 /var/log/nova/scheduler.log
文件里有类似 “No valid host was found” 的错误,那就说明没有计算节点有足够的资源来启动实例。这时候,就需要检查计算节点上运行的实例所消耗的资源了。