函数计算自动化运维实战2 -- 事件触发 eip 自动转移
函數(shù)計算
阿里云函數(shù)計算是一個事件驅(qū)動的全托管計算服務(wù)。通過函數(shù)計算,您無需管理服務(wù)器等基礎(chǔ)設(shè)施,只需編寫代碼并上傳。函數(shù)計算會為您準備好計算資源,以彈性、可靠的方式運行您的代碼,并提供日志查詢,性能監(jiān)控,報警等功能。借助于函數(shù)計算,您可以快速構(gòu)建任何類型的應(yīng)用和服務(wù),無需管理和運維。更棒的是,您只需要為代碼實際運行消耗的資源付費,而代碼未運行則不產(chǎn)生費用。
云監(jiān)控
阿里云云監(jiān)控為云上用戶提供開箱即用的企業(yè)級開放型一站式監(jiān)控解決方案。涵蓋IT設(shè)施基礎(chǔ)監(jiān)控,外網(wǎng)網(wǎng)絡(luò)質(zhì)量撥測監(jiān)控,基于事件、自定義指標(biāo)、日志的業(yè)務(wù)監(jiān)控。為您全方位提供更高效、更全面、更省錢的監(jiān)控服務(wù)。
云監(jiān)控提供了豐富事件,并且事件還在不斷豐富中(云產(chǎn)品系統(tǒng)事件監(jiān)控), 豐富的事件觸發(fā)自定義處理的函數(shù),可以實現(xiàn)更加完美的的自動化運維。
專題傳送門 => 函數(shù)計算進行自動化運維專題
示例場景
假設(shè)兩臺 ECS 機器 A, B, A 機器出現(xiàn)了宕機,這個時候需要把 A 機器上的 eip 遷移到備用機器 B 上,這個利用云監(jiān)控的報警和函數(shù)計算可以實現(xiàn) EIP 的自動遷移, 云監(jiān)控檢測到 A 宕機這個事件,然后觸發(fā)函數(shù)執(zhí)行,函數(shù)實現(xiàn) eip 的自動遷移
操作步驟
- 創(chuàng)建函數(shù)(函數(shù)代碼在文末),函數(shù)創(chuàng)建可參考函數(shù)計算helloworld
注:記得給函數(shù)的service的role設(shè)置操作ecs和eip的權(quán)限
- 登錄云監(jiān)控控制臺, 創(chuàng)建報警規(guī)則, 監(jiān)控的事件為ecs 重啟開始
- mock調(diào)試
- 模擬真實的ecs事件
請參考演練系統(tǒng)事件處理程序? So Easy~
代碼
# -*- 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.credentialssts_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 cltclt = 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 standbyEcselse:# other event to do passdef 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 statuselse: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 Truereturn False def move_eip(from_ecs, to_ecs, eip):unAssociateEip(from_ecs, eip)# wait unAssociateEip ...time.sleep(3)# retry 30s util sucessfor 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))returnelse: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_detailexcept Exception as e:LOGGER.error(e)“阿里巴巴云原生微信公眾號(ID:Alicloudnative)關(guān)注微服務(wù)、Serverless、容器、Service Mesh等技術(shù)領(lǐng)域、聚焦云原生流行技術(shù)趨勢、云原生大規(guī)模的落地實踐,做最懂云原生開發(fā)者的技術(shù)公眾號。”
總結(jié)
以上是生活随笔為你收集整理的函数计算自动化运维实战2 -- 事件触发 eip 自动转移的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 函数计算自动化运维实战1 -- 定时任务
- 下一篇: 函数计算自动化运维实战 3 -- 事件触