Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

모니터링과 인시던트 관리

나는 인터넷 서비스의 품질을 확보하기 위한 가장 중요한 활동을 아래와 같이 정의 한다.
  • 문서화 : API, (코드화된)인프라, 설계문서, 기획서.
  • 테스트가 포함된 CICD : 품질관리자가 따로 존재 할 경우 문서를 이용해서 품질을 검사한다. 이러한 업무도 페어 프로그래밍의 유형이다.
  • 모니터링, 관제 시스템 및 장애(인시던트)관리 프로세스 : 수많은 로그와 이벤트들이 발생한다. 노이즈 필터링하고, 처리해야 할 사람에게 업무를 할당, 원인을 분석해서 대책을 마련, 서비스에 반영하는 프로세스와 프로세스를 지원하기 위한 시스템이 구축되야 한다.
모니터링 결과는 결국 알람과 인시던트의 형태로 출력된다. 알람과 인시던트는 업무처리 시스템에 따라서 처리를 해야 한다 대략적인 프로세스는 아래와 같을 것이다.

 인시던트 처리 프로세스

event, alert, incident

이벤트, 경고(alert), 인시던트(incident)에 대해서 정리를 하고 넘어가야 겠다.

  • 이벤트 : 이벤트는 시스템, 환경, 프로세스, 작업의 흐름에서 관찰된 변경이다. Security Group 의 정책 변경이나 새로운 IAM 사용자의 생성, 인스턴스 시작 등이 이에 해당한다.
  • 경고 : 특정한 이벤트가 발생 했음을 알리는 알림이다. 보통 중요하다고 생각하는 이벤트들이다. 개발이나 QA 환경에서의 인스턴스 시작 이벤트는 경고로 전달하지 않을 것이다. 하지만 IAM 사용자의 생성은 보안 담당자에게, VPC 라우팅 테이블의 변경은 네트워크 담당자에게 전달 될 것이다.
  • 인시던트 : 비지니스에 영향을 미치는 중요한 이벤트다. 데이터베이스 접근 실패, 사용자 인증 실패 등이다. 특정 타겟 그룹에 있는 EC2 인스턴스의 unhealth 이벤트는 비지니스에 직접적인 영향을 주지 않기 때문에 경고로 처리하는게 일반적이다.
경고와 인시던트를 처리하는 방법에도 차이가 생긴다. 경고는 즉시 대응 할 필요는 없다. 예를 들어 4개의 인스턴스를 포함하고 있는 타겟 그룹이 있다고 가정해보자. 인스턴스 하나가 죽었다고 새벽같이 엔지니어를 깨워서 실시간 대응을 할 필요는 없다. 출근 후, 원인을 파악해서 대응해도 된다.

반면 ELB로의 HTTP 요청이 일정시간 실패했다면, 즉시 모니터요원이 확인해서 담당자에게 연락을 취해서 문제를 해결 해야 한다. 담당자가 연락을 받지 못할 수도 있으니, 1선,2선 담당자의 연락처를 확보해야 할 것이다.

통시방법에도 차이가 있다.

경고는 Email, Jira, Slack 등으로 보내면 된다. 담당자가 경고를 인지했는지를 즉각적으로 확인하는 절차도 필요 없다. 하지만 인시던트라면 Email, Jira로 보내는 것에 더해서 SMS,전화 등으로 인시던트를 인지하도록 하고 즉각 처리하도록 해야 한다.

처리는 Jira 같은 업무처리 시스템을 이용해서 추적가능하게 해야 할 것이다.

통합된 인시던트 관리 시스템의 필요성

CloudWatch에 알람 설정 걸어 놓고 이벤트가 발생하면, 중요도 확인해서 담당자에게 티켓(jira ticket 같은)할당 해서 처리하도록 하면 되는 것이라고 쉽게 생각 할 수 있겠다. 하지만 결코 만만한 작업이 아니다. 아래 그림을 보자.

 다양한 이벤트 소스들

다양한 이벤트 소스들로 부터 이벤트가 발생한다. AWS의 리소스들, 프론트앤드 애플리케이션, 백앤드 서버 애플리케이션, 여러 개의 서비스들, 여러 조직들(외부 조직이 참여할 수도 있다), 개발자, 보안담당자, 데이터베이스 엔지니어, 품질관리자, CSCR 고객지원팀 ...

이리하여 분산된 이벤트들을 중앙에서 모아서 관리해주는 솔류션들이 만들어진다. PagerDuty, victorops 오늘 소개할 Opsgenie가 대표적인 인시던트 관리 솔류션이다.

인시던트 시스템은 아래의 기능들을 가지고 있어야 한다.
  1. 다중 경고 채널 : 이메일은 기본이다. 신속한 대응이 필요한 이벤트를 위해서 모바일 푸시, SMS, 음성호출, Jira, Slack(메신저)등 다양한 경고 채널을 제공해야 한다.
  2. 다양한 이벤트 소스 지원 : AWS CloudWatch, AWS SNS, Sentry, DataDoG 등 다양한 이벤트 소스와 통합 할 수 있어야 한다.
  3. 이벤트 라이프사이클 관리 : Open, 인지, 할당, Close 등 이벤트를 관리하고 추적하기 위한 시스템을 가지고 있어야 한다.
  4. 이벤트 정책 설계 : 쓸데 없는 경고는 잡음일 뿐이다. 이벤트 종류, 중요도, 시간에 따라서 알람을 받을 수 있어야 한다.
  5. 이벤트 스케쥴 설정 : 평일, 주말, 근무시간, 근무외시간, 휴가, 근무교대와 같은 스케쥴링 시나리오를 설정할 수 있어야 한다.
아래와 같이 Opsgenie를 이용해서 인시던트 관리 시스템을 구성했다.

 인시던트 관리 시스템

모든 이벤트를 Opsgenie로 통합해서 관리한다. Opsgenie는 이벤트 정책에 따라서, 각 담당자 혹은 담당자 그룹에게 메신저, 이메일, 전화 등으로 알람을 보낸다. 알람은 또한 업무처리 시스템(내장된 Jira 비슷한 시스템)으로 전송되며, 담당자는 해당 내용을 읽어서 처리한다. 처리 결과는 레포트로 출력된다.

인시던트 관리 시스템 구축

위의 개념을 검증하기 위해서 아래와 같은 테스트 시스템을 구성하기로 했다.

  1. AWS에서 발생하는 이벤트 : 모든 이벤트는 Cloudwatch로 보낸다. ELB, EC2 등 AWS 인프라에서 발생하는 이벤트는 물론이고 애플리케이션에서 발생하는 이벤트도 CloudWatch 보낸다. 애플리케이션은 ECS라면 표준출력으로, EC2 라면 Cloudwatch Agent를 이용해서 전송 할 수 있다.
  2. 애플리케이션에서 발생하는 이벤트 : 크래시 로그만 따로 Sentry로 보낸다.
  3. Slack : 이벤트는 Slack로 받아볼 것이다.
클라우드에서 개발, 로그 수집/분석, 보안, 모니터링 시스템 구축에 대한 내 원칙은 "복잡도의 위임"이다.

Slack 설정

채팅 솔류션으로 Slack를 선택했다. Opsgenie에서 발생하는 이벤트를 받아보는 채널이되시겠다. 슬랙 클라이언트 설치와 사용에 대한 내용은 다루지 않는다.

나는 joinc-opsgenie라는 이름의 workspace 를 만들고, #opsgenie 채널을 만들었다.

이 것으로 Slack은 준비완료

AWS SNS 및 CloudWatch 설정

AWS 인프라에서 발생하는 이벤트를 Opsgenie로 보내는 시스템을 구성하는게 이 문서의 목표다. 이 목표를 위해서 아래의 시스템을 구성하기로 했다.

 Opsgenie 테스트를 위한 AWS SNS 설정

  1. EC2 인스턴스의 CPU Utilization이 30%를 초과하면 알람을 발생하도록 한다.
  2. 이 알람은 SNS로 전달되고
  3. 이후 Opsgenie에 통합된다.
SNS Topic을 만들자.

SNS 대시보드로 이동해서 Create topic를 선택한다.

Name 설정하고 Create 버튼 누르면 된다. 지금 상황에서는 Name 설정만으로 충분하다. 다른 옵션들은 여기에서는 다루지 않겠다.

Topic을 만들었으니, 이 Topic을 Opsgenie에서 구독(subscription) 하도록 설정하면 된다. Opsgenie SNS endpoint가 있어야 진행이 가능하므로 여기에서 중단하고 Opsgenie를 설정하자.

Opsgenie 설정

Opsgenie사이트에 방문해서 계정을 하나 만들자. 모든 기능을 제공하는 FREE 요금제를 사용하기로 했다. 15일 동안 사용 할 수 있다. 기능 테스트하기에는 충분한 시간이다.

ESSENTIALS의 경우 9 달러인데, 유저 10명이 사용한다고 했을 때 110 달러/월 수준이다. 이런 시스템을 직접 구축하고 운영/유지보수에 들어가는 시간과 노력을 생각하면, 매우 매우 엄청나게 저렴한 비용이다.

계정을 하고 로그인 하면 Quick Start guid가 반겨준다. 익숙해지면 메뉴 뒤져가면서 설정 할 수 있겠으나, 처음엔 Quick Start guid를 따라가면 편하게 설정을 마칠 수 있다.

Configure your profile을 보면 "Active your account"이 보일 것이다. 이 부분이 Done상태여야 한다. Opsgenie 계정을 만들면 이메일 주소로 어카운트 확인 메일이 전송되는데, 반드시 확인해줘야 한다. 그렇지 않으면 권한문제로 기능이 작동하지 않는다.

Opsgenie는 모든 작업이 팀단위로 이루어진다. 팀단위로 이벤트 소스의 통합(Integrations), 정책 에스컬레이션 설정, 스케쥴을 관리가 수행된다. Team 메뉴에서 팀을 만들자 나는 joinc 라는 이름의 팀을 만들었다.

Slack integration

Team(앞서 만든 Joinc) > Integrations로 이동, Slack를 찾아서 Add 버튼을 클릭한다. Add to Slack 버튼을 클릭하면 Slack 연동화면으로 넘어간다.

이벤트를 전송할 채널 #opsgenie를 선택하고 Install 버튼을 클릭한다.

슬랙에 "added an integration to this channel: OpsGenie"메시지가 뜨면 연동성공이다.

 Opsgenie Slack integration

이제 Opsgenie 에서 발생한 이벤트는 Slack 으로 전달될 것이다.

AWS SNS integration
AWS SNS와 Opsgenie를 연동할 차례다.

Integrations로 이동해서 Add integration을 클릭한다. Amazon SNS를 찾아서 Add 버튼을 클릭한다.

  • Add an HTTPS subscription to your topic : SNS는 https/https 방식의 subscription 수단을 제공한다. 이벤트가 게시되면 등록한 URI를 호출해서 이벤트가 왔음을 알려주는 방식이다. 이 URL을 복사해서 SNS subscription을 설정하면된다. SNS subscription 설정은 이 페이지의 설정이 다 끝난 다음에 수행해야 한다.
  • Name : 적당히 설정하자.
  • API Key : endpoint URI를 호출하기 위해서 필요한 key다. endpoint url
  • Enabled : Enabled 상태여야 이벤트를 받아볼 수 있다.
나머지 기능은 여기에서는 설명하지 않겠다. save Integration 버튼을 눌러서 지금 정보를 저장한다.

이제 AWS web console로 이동해서 subscription을 설정한다.

create subscription을 클릭하면 subscription 설정 페이지로 넘어간다.

  • Topic ARN : Subscription 할 Topic.
  • Protocol : HTTPS
  • Endpoint : Opsgenie의 endpoint url을 붙여넣는다.
Creat subscription을 클릭하면 AWS SNS와 opsgenie와의 통합이 마무리 된다.

Opsgenie 알림창에 Subscription confirmed 알림이 뜨면, 성공이다.

EC2 Cloudwatch 알람 발생

이제 EC2 Cloudwatch 알람을 발생해보자. EC2를 만들고 Monitoring 화면으로 이동한다.

Create Alarm으로 알람을 만든다.

  • Send a notification to : 알람을 게시할 SNS 토픽.
  • CPU 평균 사용율이 50%를 넘으면 알람을 게시하도록 설정했다.
EC2 인스턴스에 접근, dd 명령을 이용해서 CPU 사용율을 증가시켰다.
# dd if=/dev/zero of=/dev/null
설정대로라면 대략 5분 이내에 알람이 발생해야 할 것이다. 알람이 도착했다.

  • 슬랙
  • Opsgenie

나는 Email과 SMS도 등록한 상태다. 4개의 미디어를 통해서 메시지가 전달됐다. SMS는 국제발신으로 수신했다. 실제 환경이라면 SMS나 Slack으로 이벤트를 확인하고, Opsgenie를 통해서 이벤트 처리를 시작했을 거다. Opsgenie에서의 이벤트처리는 Jira의 그것과 유사하다.

Sentry와의 통합

Sentry 로그도 Opsgine와 통합하기로 했다. Opsgenie intergration에서 Sentry를 선택하자.

Opsgenie API key와 Opsgenie Alert URL을 복사해서 Sentry의 opsgenie integration 에 붙여넣기만 하면 된다. 이 문서는 Sentry 사용 문서는 아니니, Sentry측 설정은 넘어가도록 하겠다.

아래과 같은 간단한 코드를 만들어서 Opsgenie와 잘 통합됐는지 테스트했다.
package main

import (
    "errors"
    "fmt"
    "github.com/getsentry/sentry-go"
    "time"
)

func main() {
    err := sentry.Init(sentry.ClientOptions{
        Dsn: "https://77123307xxxxxxxxxxxxxxx@sentry.io/xxxxxxxx",
    })

    if err != nil {
        fmt.Printf("Sentry initialization failed: %v\n", err)
    }

    sentry.CaptureException(errors.New("system error : http/client connection error"))
    sentry.Flush(time.Second * 5)
    time.Sleep(time.Second * 5)
}
프로그램을 실행 후, opsgenie, Sentry, slack에 이슈가 전달되는 걸 확인했다.

정리

  • 클라우드 시스템 관리/운영에서 가장 중요한 요소는 복잡도를 덜어내는 것이다. 자원관리의 복잡성을 위임하자.
  • ITSM(IT 서비스 관리)에서 이벤트관리의 중요성은 백번 강조해도 모자람이 없다.
  • 로그를 통합하는 것은 따로 고민해서 정리해야 겠다.