← 목록으로AWS

EC2 StatusCheckFailed 기반 장애 감지 및 자동 복구 알람 시스템

EC2 인스턴스의 StatusCheckFailed 지표를 활용한 장애 자동 감지, Auto Recovery 실행, 다중 채널(전화/SMS/이메일) 알람 아키텍처 구축

AWSMonitoringCloudWatchAutomation
2024-10-02

개요

운영 중인 EC2 인스턴스에서 예기치 못한 재기동이 발생했고, AWS Support를 통해 원인이 StatusCheckFailed_System (물리적 호스트 하드웨어 이슈)임을 확인했습니다.

이 경험을 계기로 EC2 StatusCheckFailed 지표 기반의 장애 감지 + Auto Recovery + 다중 알람 시스템을 구축했습니다.


EC2 StatusCheckFailed 지표 이해

EC2의 StatusCheckFailed는 두 가지 하위 지표로 나뉩니다.

EC2_StatusCheckFailed
    ├── StatusCheckFailed_Instance (인스턴스 내부 문제)
    │     ├── 손상된 파일 시스템
    │     ├── 잘못 구성된 네트워킹 또는 시작 구성
    │     ├── 고갈된 메모리
    │     ├── 운영체제 부팅 실패
    │     └── 올바른 볼륨 마운트 실패
    │
    └── StatusCheckFailed_System (AWS 인프라 문제)
          ├── 네트워크 연결 끊김
          ├── 시스템 전원 손실
          ├── 물리적 호스트의 소프트웨어 문제
          └── 물리적 호스트의 하드웨어 문제

Instance 체크는 OS 영역에서 발생하는 이슈, System 체크는 AWS 인프라 레벨에서 발생하는 이슈입니다.

여러 상황에 따른 지표 trigger 테스트 완료 (인터페이스 다운, 볼륨 마운트 실패, 메모리 고갈 등) → 예기치 못한 EC2 인스턴스 내외적 문제에 따른 빠른 대응 가능


실제 장애 사례

AWS Support 확인 결과:

[장애 타임라인]
05:43 UTC — 인스턴스가 위치한 물리적 호스트에서 하드웨어 이슈 발생
           → StatusCheckFailed_System[1] 확인
           → 인스턴스가 정상적으로 응답하지 못하는 동안
             CloudWatch 데이터 포인트 누락 발생

05:49 UTC — Auto Recovery 실행
           → AWS_EC2_SIMPLIFIED_AUTO_RECOVERY_SUCCESS 수행
           → 정상 운영 중인 새 호스트 하드웨어로 이동
           → 정상적으로 상태 확인 완료

PHD(Personal Health Dashboard) 콘솔에서 Auto Recovery 이력을 확인할 수 있습니다.


알람 아키텍처

EC2 인스턴스 (다수 운영 서버)
    │
    ├── CW Agent (메트릭 수집)
    │
    ↓
CloudWatch 경보 (StatusCheckFailed_System)
    │
    ├── Auto Recovery 실행
    │
    ↓
SNS Topic (Seoul Region)
    │
    ├── 4. HTTP 구독 → Alarm App (경보 메시지 전달)
    │       │
    │       ├── 5.1 메시지 파싱 후 Call Service 호출
    │       │       └── Amazon Connect → 운영 팀 순차 전화 알림
    │       │
    │       ├── 6.1 Email Service 호출
    │       │       └── AWS SES → 팀 이메일 전송
    │       │
    │       └── 7.1 SMS Service 호출
    │               └── AWS SNS (Tokyo Region) → 운영 팀 문자 알림
    │
    └── (직접 구독: 이메일)

크로스 리전 구성

  • CloudWatch 경보 + SNS Topic: Seoul Region
  • SMS 발송용 SNS: Tokyo Region (SMS 지원 리전)

CloudWatch 경보 설정

각 EC2 인스턴스마다 StatusCheckFailed 경보를 설정합니다.

import boto3
 
cloudwatch = boto3.client('cloudwatch')
 
def create_status_check_alarm(instance_name, instance_id, sns_topic_arn):
    cloudwatch.put_metric_alarm(
        AlarmName=f'{instance_name}-StatusCheckFailed',
        MetricName='StatusCheckFailed',
        Namespace='AWS/EC2',
        Dimensions=[
            {'Name': 'InstanceId', 'Value': instance_id},
        ],
        Statistic='Maximum',
        Period=60,
        EvaluationPeriods=1,
        Threshold=1,
        ComparisonOperator='GreaterThanOrEqualToThreshold',
        AlarmActions=[
            sns_topic_arn,
            f'arn:aws:automate:{region}:ec2:recover',  # Auto Recovery
        ],
        TreatMissingData='breaching',
    )

TreatMissingData='breaching'으로 설정하여 데이터 포인트 누락 시에도 경보가 발생하도록 합니다. 실제 장애 시 CloudWatch 데이터 포인트가 누락될 수 있기 때문입니다.


Auto Recovery

StatusCheckFailed_System 발생 시 EC2 Auto Recovery가 자동 실행됩니다.

  • 인스턴스를 정상 운영 중인 새 물리적 호스트로 이동
  • 인스턴스 ID, Private IP, Elastic IP, 메타데이터 유지
  • EBS 볼륨 그대로 연결
AlarmAction: arn:aws:automate:{region}:ec2:recover

Auto Recovery는 EBS-backed 인스턴스에서만 동작하며, Instance Store 볼륨을 사용하는 경우 지원되지 않습니다.


다중 알람 채널

Alarm App (HTTP 구독)

SNS Topic에 HTTP 프로토콜로 구독하여 경보 메시지를 수신하고, 내부에서 전화/SMS/이메일 서비스를 호출합니다.

# Alarm App - SNS 메시지 수신 후 알람 발송
from fastapi import FastAPI, Request
import json
 
app = FastAPI()
 
@app.post("/alert")
async def handle_alarm(request: Request):
    body = await request.json()
    message = json.loads(body.get('Message', '{}'))
 
    alarm_name = message.get('AlarmName', '')
    description = message.get('AlarmDescription', '')
 
    # 설정 파일에서 알람 방법 및 수신자 로드
    config = load_config('monitor-config.yaml')
 
    if 'call' in config['notificationMethod']:
        await make_calls(config['callPhoneNumbers'], description)
 
    if 'sms' in config['notificationMethod']:
        await send_sms(config['smsPhoneNumbers'], description)
 
    if 'email' in config['notificationMethod']:
        await send_email(config['receiver'], description)

전화 (Amazon Connect)

async def make_calls(phone_numbers: list, message: str):
    # 담당자 순차 전화 발신
    connect = boto3.client('connect')
    for phone in phone_numbers:
        connect.start_outbound_voice_contact(
            DestinationPhoneNumber=phone,
            ContactFlowId='[contact-flow-id]',
            InstanceId='[connect-instance-id]',
            SourcePhoneNumber='[caller-number]',
            Attributes={'message': message}
        )

SMS (SNS - Tokyo Region)

async def send_sms(phone_numbers: list, message: str):
    sns = boto3.client('sns', region_name='ap-northeast-1')  # Tokyo
    for phone in phone_numbers:
        sns.publish(PhoneNumber=phone, Message=message)

Email (SES)

async def send_email(recipients: list, body: str):
    ses = boto3.client('ses')
    ses.send_email(
        Source='[sender-email]',
        Destination={'ToAddresses': recipients},
        Message={
            'Subject': {'Data': '[긴급] EC2 StatusCheckFailed 경보'},
            'Body': {'Text': {'Data': body}}
        }
    )

설정 파일 기반 유지보수

YAML 설정 파일로 모든 알람 설정을 관리합니다. 코드 변경 없이 운영 중 수정 가능합니다.

# monitor-config.yaml
receiver: '[team-email]'
cc: '[team-email]'
notificationMethod: ['call', 'sms', 'email']
 
callPhoneNumbers:
  - '+8210[phone-1]'
  - '+8210[phone-2]'
  - '+8210[phone-3]'
 
smsPhoneNumbers:
  - '+8210[phone-1]'
  - '+8210[phone-2]'
  - '+8210[phone-3]'
 
servers:
  - server1:
      name: '[SERVICE-A]-PRD-01'
      alarmName: '[SERVICE-A]-PRD-01-StatusCheckFailed'
      description: '서버가 다운되었거나 인스턴스 내부 문제가 발생하였습니다.'
  - server2:
      name: '[SERVICE-A]-PRD-DB-01'
      alarmName: '[SERVICE-A]-PRD-DB-01-StatusCheckFailed'
      description: 'DB 서버가 다운되었거나 인스턴스 내부 문제가 발생하였습니다.'
  # ... 추가 서버

설정 파일에서 관리하는 항목

  1. 알람 수단 다중 선택 (call, sms, email)
  2. EC2 Failure 추적할 인스턴스 경보 이름
  3. EC2 Failure 추적할 인스턴스 이름
  4. 알람 시 발송 메시지 및 전화 음성
  5. 전화 수신 번호
  6. 문자 수신 번호
  7. 알람 이메일 수신 이메일

모니터링 대상

운영 환경의 전체 EC2 인스턴스를 대상으로 경보를 설정합니다.

  • 애플리케이션 서버 (PRD AP)
  • DB 서버 (PRD DB, Replica)
  • 연동 서비스 서버 (HUB, API 등)
  • Docker 기반 Agent 서버

정리

  • EC2 StatusCheckFailed 지표로 인스턴스 내부/외부 장애 모두 감지
  • Auto Recovery로 System 레벨 장애 시 자동 복구
  • SNS → Alarm App → 전화/SMS/이메일 다중 알람 채널 구성
  • 크로스 리전(Seoul → Tokyo) SMS 발송 구성
  • YAML 설정 파일 기반으로 대상/수신자/알람 수단 유동적 관리
  • 실제 하드웨어 장애 사례에서 Auto Recovery 정상 동작 확인