阿里云函数计算是一个事件驱动的全托管计算服务。经过函数计算,您无需管理服务器等基础设施,只需编写代码并上传。函数计算会为您准备好计算资源,以弹性、可靠的方式运行您的代码,并提供日志查询,性能监控,报警等功能。借助于函数计算,您能够快速构建任何类型的应用和服务,无需管理和运维。更棒的是,您只须要为代码实际运行消耗的资源付费,而代码未运行则不产生费用。html
阿里云云监控为云上用户提供开箱即用的企业级开放型一站式监控解决方案。涵盖IT设施基础监控,外网网络质量拨测监控,基于事件、自定义指标、日志的业务监控。为您全方位提供更高效、更全面、更省钱的监控服务。
云监控提供了丰富事件,而且事件还在不断丰富中(云产品系统事件监控), 丰富的事件触发自定义处理的函数,能够实现更加完美的的自动化运维。json
假设两台 ECS 机器 A, B, A 机器出现了宕机,这个时候须要把A机器上的 eip 迁移到备用机器 B 上,这个利用云监控的报警和函数计算能够实现 EIP 的自动迁移, 云监控检测到 A 宕机这个事件,而后触发函数执行,函数实现eip的自动迁移api
建立函数(函数代码在文末),函数建立可参考函数计算helloworld服务器
注:记得给函数的service的role设置操做ecs和eip的权限
微信
登陆云监控控制台, 建立报警规则, 监控的事件为ecs 重启开始网络
# -*- coding: utf-8 -*- import logging import json, random, string, time from aliyunsdkcore import client from aliyunsdkvpc.request.v20160428.AssociateEipAddressRequest import AssociateEipAddressRequest from aliyunsdkvpc.request.v20160428.UnassociateEipAddressRequest import UnassociateEipAddressRequest from aliyunsdkvpc.request.v20160428.DescribeEipAddressesRequest import DescribeEipAddressesRequest 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) ''' { "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:123456789:instance/i-bp18l0uopocfc98xxxx", "level": "CRITICAL", "instanceName": "instanceName", "status": "Executing", "name": "Instance:SystemFailure.Reboot:Executing", "regionId": "cn-hangzhou" } ''' 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"); eipId = "eip-bp1nexxxc7zjfnex6i0"; standbyEcsId = "i-bp19yycxx7yroukxpv" name = name.lower() if name in ['Disk:Stalled:Executing'.lower(), 'Instance:SystemFailure.Reboot:Executing'.lower(), "Instance:InstanceFailure.Reboot:Executing".lower()]: print("move eip to standbyEcs"); move_eip(ecsInstanceId, standbyEcsId, eipId) # move eip to standbyEcs else: # other event to do pass def getEipStatus(eip): request = DescribeEipAddressesRequest() request.set_AllocationId(eip) request.add_query_param("RegionId", "cn-hangzhou") response = _send_request(request) if isinstance(response, dict) and "RequestId" in response: EipAddresses = response.get('EipAddresses', {}) EipAddress = EipAddresses['EipAddress'][0] status = EipAddress['Status'] return status else: LOGGER.error("getEipAddressDesc {} fail".format(eip)) def unAssociateEip(ecs_id, eip): request = UnassociateEipAddressRequest() request.set_AllocationId(eip) request.set_InstanceType('EcsInstance') request.set_InstanceId(ecs_id) response = _send_request(request) if isinstance(response, dict) and "RequestId" in response: LOGGER.info("UnassociateEipAddress {} from {} succ".format(ecs_id, eip)) else: LOGGER.error("UnassociateEipAddress {} from {} fail".format(ecs_id, eip)) def associateEip(ecs_id, eip): associte_request = AssociateEipAddressRequest() associte_request.set_AllocationId(eip) associte_request.set_InstanceType('EcsInstance') associte_request.set_InstanceId(ecs_id) associte_response = _send_request(associte_request) if isinstance(associte_response, dict) and "RequestId" in associte_response: LOGGER.info("AssociateEipAddress {} to {} succ".format(eip, ecs_id)) return True return False def move_eip(from_ecs, to_ecs, eip): unAssociateEip(from_ecs, eip) # wait unAssociateEip ... time.sleep(3) # retry 30s util sucess for i in xrange(10): eip_status = getEipStatus(eip).lower() if eip_status == 'available': if associateEip(to_ecs, eip): LOGGER.info("AssociateEipAddress {} to {} succ".format(eip, to_ecs)) return else: LOGGER.info("eip status = {}".format(eip_status)) time.sleep(3) LOGGER.info("AssociateEipAddress {} to {} fail".format(eip, to_ecs)) # send open api request 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)
“阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,作最懂云原生开发者的技术公众号。”less