Serverless架构在运维层面有着得天独厚的优势,不仅因为其事件触发可以有针对性地获取、响应一些事件,还因为其轻量化、低运维的特性让很多运维开发者甚是喜爱。
在实际生产中,如果可以将线上环境的变动以事件的形式触发函数,由函数进行一系列运维操作,那么Serverless将会在自动化运维的过程中发挥出更重要的作用和更大的价值,也会让传统服务的自动化运维变得更加简单、轻便。例如:当线上主机异常中止时,可以触发函数,通过云厂商提供的API备份数据盘,再对主机进行恢复;当服务器压力过大时,可以通过云监控事件触发函数进行集群扩容。当然,如果云厂商并没有提供常见的云监控触发器等,那么在将线上环境的变动以事件形式触发函数时,也可以考虑通过函数计算的定时触发器进行某些业务指标的轮询,进而实现对传统业务的部分自动化运维。
本节以阿里云函数计算与云监控触发器结合为例。假设一台云服务器ECS因系统错误而重启,在传统的架构下,运维人员或者ECS用户需要紧急响应,人工验证,并创建快照等对服务进行一定的运维操作。本节将会站在Serverless架构的角度,通过云监控中的ECS重启事件触发函数执行,自动找出ECS挂接的云盘,并为云盘自动创建快照;也将会以腾讯云云函数与时间触发器结合为例,满足定时重启云主机的需求。
6.3.1 云盘自动快照
云盘自动快照这个功能是通过Serverless架构实现的自动化运维,整个项目分为两个主要部分:业务逻辑和触发器配置。
业务逻辑部分主要是通过阿里云函数计算调用云盘相关的SDK,实现快照建立功能;触发器配置部分则是通过云监控触发器,为对应的函数计算配置相关的触发条件。
在编写业务逻辑之前,需要清楚云监控触发器所产生的事件格式,即云监控在触发函数时,与函数计算所规约的事件数据结构(函数入口方法的event参数),具体如下。
{ "product": "ECS", "content": { "executeFinishTime": "2018-06-08T01:25:37Z", "executeStartTime": "2018-06-08T01:23:37Z", "ecsInstanceName": "timewarp", "eventId": "e-t4nhcpqcu8fqushpn3mm", "eventType": "InstanceFailure.Reboot", "ecsInstanceId": "i-bp18l0uopocfc98xxxx" }, "resourceId": "acs:ecs:cn-hangzhou:12345678:instance/i-bp18l0uopocfc98xxxx", "level": "CRITICAL", "instanceName": "instanceName", "status": "Executing", "name": "Instance:SystemFailure.Reboot:Executing", "regionId": "cn-hangzhou" }
明确数据结构之后,可以开始编写核心业务逻辑,代码如下。
# -*- coding: utf-8 -*- import logging import json, random, string from aliyunsdkcore import client from aliyunsdkecs.request.v20140526.CreateSnapshotRequest import CreateSnapshot-Request from aliyunsdkecs.request.v20140526.DescribeDisksRequest import DescribeDisksRequest from aliyunsdkcore.auth.credentials import StsTokenCredential LOGGER = logging.getLogger() clt = None def handler(event, context): creds = context.credentials sts_token_credential = StsTokenCredential(creds.access_key_id, creds.access_key_secret, creds.security_token) evt = json.loads(event) content = evt.get("content") ecsInstanceId = content.get("ecsInstanceId") regionId = evt.get("regionId") global clt clt = client.AcsClient(region_id=regionId, credential=sts_token_credential) name = evt.get("name").lower() if name in ['Instance:SystemFailure.Reboot:Executed'.lower(), "Instance:InstanceFailure.Reboot:Executed".lower()]: request = DescribeDisksRequest() request.add_query_param("RegionId", regionId) request.set_InstanceId(ecsInstanceId) response = _send_request(request) disks = response.get('Disks').get('Disk', []) for disk in disks: diskId = disk["DiskId"] create_ecs_snap_by_id(diskId) LOGGER.info("Create ecs snap success, ecs id = %s , disk id = %s ", ecsInstanceId, diskId) def create_ecs_snap_by_id(disk_id): LOGGER.info("Create ecs snap, disk id is %s ", disk_id) request = CreateSnapshotRequest() request.set_DiskId(disk_id) request.set_SnapshotName("reboot_" ''.join(random.choice(string.ascii_lowercase) for _ in range(6))) response = _send_request(request) return response.get("SnapshotId") #发送API请求 def _send_request(request): request.set_accept_format('json') try: response_str = clt.do_action_with_exception(request) LOGGER.info(response_str) response_detail = json.loads(response_str) return response_detail except Exception as e: LOGGER.error(e)
完成业务逻辑的核心代码之后,可以将代码部署到函数计算中。然后在云监控的控制台进行相关的触发设置,此时可以在阿里云云监控平台选择事件监控报警规则,如图6-20所示。
图6-20 云监控报警规则页面
然后创建事件报警,可以选择事件报警规则,如图6-21所示。
图6-21 报警事件规则配置
完成配置之后,将动作设置为函数计算即可。选择刚刚部署的函数,如图6-22所示。
图6-22 报警事件规则函数计算触发配置
这样当ECS重启事件发生之后,云监控就会通过事件触发指定的函数以执行自动化运维的业务逻辑:找出ECS挂接的云盘,并为云盘自动创建快照。
6.3.2 服务器定时重启
并不是所有FaaS平台都像阿里云函数计算一样拥有云监控触发器,可以非常简单、快速、轻松地感知到业务或服务的变化,并以事件触发的形式,触发函数计算,实现自动化运维。如果所使用的FaaS平台本身不具备云监控触发器,应当如何对服务器进行监控和自动化运维呢?
以笔者正在做的一个项目为例,该项目所使用的服务器需要每天凌晨进行初始化(根据已有的镜像重装系统)。在传统的架构下,需要一个额外的服务来实现该功能;而在Serverless架构下,只需要一个函数即可实现完整的业务逻辑,若同时配置时间触发器,还可实现整个需求的开发。代码如下。
# -*- coding: utf8 -*- from tencentcloud.common import credential from tencentcloud.common.profile.client_profile import ClientProfile from tencentcloud.common.profile.http_profile import HttpProfile from tencentcloud.cvm.v20170312 import cvm_client, models ImageId = "" InstanceId = "" secretId = "" secretKey = "" def main_handler(event, context): try: cred = credential.Credential(secretId, secretKey) httpProfile = HttpProfile() httpProfile.endpoint = "cvm.tencentcloudapi.com" clientProfile = ClientProfile() clientProfile.httpProfile = httpProfile client = cvm_client.CvmClient(cred, "ap-shanghai", clientProfile) req = models.ResetInstanceRequest() params = '{"InstanceId":"%s","ImageId":"%s","LoginSettings":{"KeepImageLogin":"TRUE"}}' % (InstanceId, ImageId) req.from_json_string(params) resp = client.ResetInstance(req) print(resp.to_json_string()) except Exception as err: print(err)
完成业务逻辑的核心代码之后,可以将函数部署到线上,部署完成后,还需要配置时间触发器(定时触发器),如图6-23所示。
图6-23 时间触发器配置
配置完成后,就可以满足定时云主机的重装诉求,即每天凌晨,系统会根据指定的镜像重新初始化云主机。
6.3.3 总结
通过Serverless架构,可以将一些触发器和业务逻辑友好、简单地组合起来。无论是日志触发器、云监控触发器还是时间触发器,都可以通过与业务逻辑结合,简单、轻量化地定制自动化运维脚本。相对传统的自动化运维脚本而言,基于Serverless架构的自动化运维脚本会更加简单、轻量、稳定。
标签:Serverless,触发器,函数,运维,request,import,id,赋能 From: https://www.cnblogs.com/muzinan110/p/17067631.html