运维人员的军刀——ROS
阿里云资源编排(Resource Orchestration)是一种简单易用的云计算资源管理和自动化运维服务。
本文以运维ECS为例,介绍如何使用资源编排服务,和现有的运维系统对接。本文使用ROS的Python SDK方式来调用资源编排服务,详细教程请参照阿里云资源编排服务Python SDK使用入门。
注: 示例中的命令行都使用Linux的shell,Windows/DOS用户需要根据情况修改。
运维方式对比
以部署一套完整环境为例。
-
使用ROS之前:
- 首先,您会规划一个网络和资源的拓扑结构出来。
- 然后,还要规划资源的配置信息。比如,开放哪几个端口、ECS是几核几G、磁盘需要什么类型、网络带宽是多大、开设哪些白名单等等。
- 下一步,批量创建资源。您会拿着配置清单去批量的生产ECS, SLB, RDS, VPC等资源,直到所有资源都ready,还需要给资源批量或逐个的打标、核对实际生产和规划是否一致。
- 最后,需要逐一的去记录每个资源的ID、内外网地址、连接串等信息。您可能会把资源信息记录在Excel表格或者其他的配置工具中。
- 上述过程已经很繁琐了,后续的运维工作更是令人抓狂,您会不停在查找机器、查找ip地址、ssh到机器、修改配置、修改表格之间奔波。
-
使用ROS之后:
- ROS支持以模板或者可视化工具的方式来帮助您构建网络和资源的拓扑,方便您后续维护。
- ROS支持以配置的方式描述资源,以开发人员所熟知的结构(JSON)来描述资源。一旦这个模板描述好,ROS 可以一键创建资源,免去了您在各个服务或者api之间切换的成本,和等待资源依赖创建的成本。
- ROS支持回滚策略,保证幂等性。您不用逐个去检查每个资源是否都创建成功,他们之间的依赖是否配置完成,这些工作ROS都会搞定。
- 至于资源创建完成之后的信息记录工作,ROS提供了调用接口,配管工具可以直接对接和二次处理。
- 资源升降配、单元扩容,在ROS中都可以一键搞定、同步更新。
下面介绍一个简单的应用场景:运维工具把所需资源的一组参数信息提交给资源编排服务,资源编排服务去生产对应的资源。当然资源生产完成后,运维工具调用ROS接口获取每个资源的信息。
创建资源(ECS)
1 首先您需要了解ECS实例支持配置哪些属性
- 您可以在ROS控制台, 查看ECS配置列表(Properties),如下图所示:
- 有关于ECS配置属性更详细的讲解请参照通过资源编排创建一个ECS实例
2 其次,您需要准备一个用来创建资源栈的模板
- ROS针对大多数场景提供了公共模板的支持, 您可以复制一份模板。
- 或者您也可以自己编写一个模板,可以参照资源编排模板详解
-
本文采用的模板如下, 它会创建一个按量付费的ECS实例和一个没有配置出入规则的安全组,然后把ECS加入到此安全组。
{ "ROSTemplateFormatVersion" : "2015-09-01", "Description": "创建一个按量付费的ecs实例和一个安全组", "Parameters" : { "ImageId": { "Type" : "String", "Default": "ubuntu1404_64_40G_aliaegis_20160222.vhd", "Description": "镜像文件 ID,表示启动实例时选择的镜像资源" }, "InstanceType": { "Type": "String", "Description": "实例的资源规格", "Default": "ecs.s3.large", "AllowedValues": [ "ecs.s2.medium", "ecs.s2.large", "ecs.s3.medium", "ecs.s3.large" ] }, "SecurityGroupName": { "Type": "String", "Default": "ros", "Description": "安全组名称" } }, "Resources" : { "WebServer": { "Type": "ALIYUN::ECS::Instance", "Properties": { "ImageId" : {"Ref": "ImageId"}, "InstanceType": {"Ref": "InstanceType"}, "SecurityGroupId": { "Fn::GetAtt": [ "SecurityGroup", "SecurityGroupId" ] } } }, "SecurityGroup": { "Type": "ALIYUN::ECS::SecurityGroup", "Properties": { "SecurityGroupName" : {"Ref": "SecurityGroupName"} } } }, "Outputs": { "InstanceId": { "Value" : {"Fn::GetAtt": ["WebServer","InstanceId"]} }, "InnerIp": { "Value": {"Fn::GetAtt": ["WebServer","InnerIp"]} }, "PublicIp": { "Value" : {"Fn::GetAtt": ["WebServer","PublicIp"]} } } }
注意: 把需要获取的属性逐一添加到outputs节点之后,配管工具才能拿到资源的对应信息。
ECS支持的输出属性可以在ROS控制台查看Attributes列表,如下图所示:
3 接下来通过ROS Python SDK,您就可以调用资源编排服务去创建ECS资源了
-
简单的说就是把您的模板以及资源的参数封装成对象,然后发送给资源编排服务。代码片段如下:
req = CreateStacksRequest.CreateStacksRequest() req.set_headers({'x-acs-region-id': region}) create_stack_content = ''' { "Name":"%s", "TimeoutMins":%d, "Template":%s, "Parameters":%s } ''' % (stack_name, timeout_mins, template, json.dumps(stack_params)) req.set_content(create_stack_content)
其中,template即为资源栈模板,region、stack_params等是从运维工具获取的参数信息。
4 请求结果可以通过如下代码进行获取:
status, headers, body = client.get_response(req)
if status == 201:
stack_info = json.loads(body)
print("create stack %s complete", stack_info)
print(stack_info["Id"])
else:
print('Unexpected errors: status=%d, error=%s' % (status, body))
请求成功可以获得stack_id和stack_name,后续可以查询资源栈详情。
获取资源(ECS)属性值
1 发送请求。通过查询资源栈信息接口,可以拿到outputs信息,API接口详情请参考帮助文档。需要stack_name, stack_id和region三个参数,代码片段如下:
status_req = DescribeStackDetailRequest.DescribeStackDetailRequest()
status_req.set_headers({'x-acs-region-id': region})
status_req.set_StackId(stack_id)
status_req.set_StackName(stack_name)
status, headers, body = client.get_response(status_req)
2 异步处理。因为ECS的创建一般需要3-5分钟的时间,所以我们需要一个retry方法去轮训stack的状态,直到stack的状态变为CREATE_COMPLETE
,我们就可以拿到outputs, 代码片段如下:
stack_detail = json.loads(body)
stack_status = stack_detail["Status"]
if stack_status in [ROLLBACK_COMPLETE, CREATE_COMPLETE]:
// do action here..
3 返回结果。 最后配管工具就可以拿到上述资源信息。
一键体验
1 下载本文实例代码(见附件),然后修改代码中的ak信息,以及ecs的配置信息如下:
stack_name = 'test_aliyun_ros_ecs_wqe'
region_id = 'cn-beijing'
ak_id, ak_sec = 'Your access id key', 'Your access secret'
tpl_param = {
"ImageId": "ubuntu1404_64_40G_aliaegis_20160222.vhd",
"InstanceType": "ecs.s3.large",
"SecurityGroupName": "ros_sg"
}
2 运行代码:
python test_ros.py
3 等待几分钟会得到ECS实例信息如下:
[
{u'OutputKey': u'InstanceId', u'Description': u'No description given', u'OutputValue': u'i-25bfg22gs'},
{u'OutputKey': u'PublicIp', u'Description': u'No description given', u'OutputValue': u'101.200.186.33'},
{u'OutputKey': u'InnerIp', u'Description': u'No description given', u'OutputValue': u'10.44.163.73'}
]
如果您的配管工具支持python脚本,把本文的实例代码放到您的系统,调用就可以了。
本文实例代码可在附件中下载 . 您可以加入ROS旺旺群(1496006086), 向我们反馈您的问题。