阅读 450

使用awscli监控线上即将"退休"机器

目的:

目前aws所有服务基本上都会定时执行退休计划,而这个退休事件是我们所需要关注的。

即将退休的服务,比如ec2,我们需要对其进行数据备份,重启实例,数据恢复等操作。

注意:

  • 服务的退休计划一般通知可能不是很完善,所以很可能会遗漏,导致数据或者服务丢失
  • 退休事件一般会有截止日志,如果在截止日期之前未做任何备份操作,同样会导致数据丢失

解决方案:

目前需要关注的存在退休事件的服务有:ec2,elb2,rds等。(目前暂时先对ec2进行监控)

通过awscli工具对各个区域ec2进行监控,如果存在变更事件,则微信告警通知,并设置定时任务,保证监控不间断。

(为什么不用sdk,sdk需要access_key等重要信息,目前可能暂时不需要,cli已经满足当前需求。)

涉及到的cli命令:

aws ec2 describe-instances | grep InstanceId | awk '{ print $2 }' | tr -d '\n'  //得到当前region所有ec2的实例id,最终需要创建成python listaws ec2 describe-instance-status --instance-id i-feinsdkfj | grep Events        //判断当前实例是否存在Events事件,这样是想对较快的一种方式了复制代码

整个监控脚本如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-

# @Version : 1.0
# @Time    : 2018/5/30 18:12
# @Author  : **********
# @File    : auto_check_retirement_instance.py
# @Function: 自动检测退休机器(aws)
# @Note    : 定时自动检查退休机器,通知对应负责人执行备份然后重启实例工作

import os,sys,commands,time,requests
import ast

# 执行命令函数
def execCommand(comm):
    try:
        (exitstatus, outtext) = commands.getstatusoutput(comm)
        return outtext
    except Exception as e:
        print(e)

# 得到该区域所有实例的id
def getCurRegionAllInstanceId():
    comm = ''' aws ec2 describe-instances | grep InstanceId | awk '{ print $2 }' | tr -d '\n' '''
    instanceid = execCommand(comm)
    instancelist = ast.literal_eval('[' + instanceid.rstrip(',') + ']')
    return instancelist

# 循环遍历该区域下的所有实例,如果该实例下存在Event事件,那么就需要通知用户执行相应操作
def checkInstanceWithEvent(instancelist):
    withEventInstanceList = []
    for ins in instancelist:
        comm = ''' aws ec2 describe-instance-status --instance-id %s | grep Events ''' % ins
        result = execCommand(comm)
        if result != "":
            withEventInstanceList.append(ins)
    return withEventInstanceList

# 获取存在event机器的事件信息
def getEventMesg(region,withEventInstanceList):
    for ins in withEventInstanceList:
        comm = ''' aws ec2 describe-instance-status --instance-id %s ''' % ins
        result = eval(execCommand(comm))
        desc = result['InstanceStatuses'][0]['Events'][0]['Description']    # 事件描述
        code = result['InstanceStatuses'][0]['Events'][0]['Code']           # 机器状态
        duedate = result['InstanceStatuses'][0]['Events'][0]['NotBefore']   # 截止日志
        curtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 
        eventmesg = {
            "receiver": "**********",
            "subject": "aws计划事件",
            "content": ""
        }
        eventmesg["content"] = u"区域:%s\nID:%s\n事件:%s\n时间:%s\n描述:%s\n截止日期:%s\n\n" % (region, ins, code, curtime, desc,duedate)
        requests.post("http://***********/send_wx", data=eventmesg)

if __name__ == '__main__':
    # region = "us-west-2"
    region = "ap-south-1"
    instancelist = getCurRegionAllInstanceId()
    withEventInstanceList = checkInstanceWithEvent(instancelist)
    if len(withEventInstanceList):
        getEventMesg(region,withEventInstanceList)
    else:
        print("该区域无计划事件机器")
复制代码

使用说明:

  • 由于脚本是在各个region的ops机器运行,所有机器已经授权了iam,所以不需要做另外配置。
  • 唯一需要修改的是主函数中region的值,修改成对应的region即可。
  • 直接定时任务运行即可,python auto_check_retirement_instance.py
  • 其中发送信息调用的接口是公司内部的微信接口,各位可以根据自己的需求进行设计发送。

告警效果图:


最后补充:

  • 后续会逐渐加上aws其他服务的监控
  • 后续会研究如何直接从aws 的事件列表中获取数据,而不是遍历对应的ec2.
  • 脚本都是最基础的命令,没什么技术含量,主要是为了解决目前的一些问题而已。不喜勿喷,谢谢。