|
|||
| $ whoami --team ❯ kt cloud Data플랫폼팀 유지연 님 |
![[구축사례] kt cloud PLATFORM Observability Alert 플랫폼 구축하기](https://blog.kakaocdn.net/dna/2TMuI/dJMcagUcmt0/AAAAAAAAAAAAAAAAAAAAALcgnp6JZrkI7mDO8eGObrRdbCcEHjvDhPUyFDPDtgtr/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1788188399&allow_ip=&allow_referer=&signature=uZwFckDo269%2Fk898K0oLQErX3R8%3D)
1. 왜 Observability Alert 플랫폼을 직접 만들었나 — 문제의 출발점
클라우드 플랫폼을 운영하다 보면 자연스럽게 모니터링과 알림 체계가 고도화됩니다. 가상 서버, 네트워크, 컨테이너 플랫폼 각각을 감시하는 도구들이 늘어나면서, 어느 순간 "알림을 받는 것"보다 "어떤 알림을 어떤 팀에 어떻게 보낼 것인가"가 더 어려운 문제가 됩니다.
저희도 같은 지점에서 막혔습니다. KCP의 Observability 인프라는 Grafana, Loki, Tempo, Mimir로 구성된 LGTM 오픈소스 스택으로 잘 구축되어 있었습니다. 데이터 수집과 시각화는 이 스택이 충분히 처리해 주었지만, Alert 영역에서는 세 가지 문제가 반복됐습니다.
첫째, 조직(Org) 단위 Alert 격리가 어려웠습니다. Grafana는 데이터 조회를 조직 단위로 분리하지만, Alert 처리는 수집 테넌트(X-Scope-OrgID) 기준으로 동작합니다. 하나의 플랫폼을 여러 팀이 공유하는 환경에서 팀별로 완전히 독립된 Alert 정책을 운영하기가 구조적으로 어려웠습니다.
둘째, Alert 규모가 커질수록 확장성에 제약이 생겼습니다. Grafana Managed Alert는 설정과 사용이 직관적이지만, Alert 설정·평가·전송이 하나의 컴포넌트에 집중된 구조입니다. 엔터프라이즈 규모의 Alert 환경에서는 병목이 발생할 가능성이 있어, 컴포넌트를 분리하는 방향을 검토하게 됐습니다.
셋째, 표준화된 Alert API 계층이 없었습니다. Grafana에 종속된 구조에서 벗어나, 향후 자체 포털이나 외부 서비스에서도 동일한 인터페이스로 Alert를 생성·조회·관리할 수 있어야 했습니다.
세 문제의 공통점은 단순히 "알림 기능"이 부족한 게 아니라, Alert를 운영 정책으로 다룰 수 있는 계층이 없다는 것이었습니다. 저희는 외부 SaaS 도입 대신, LGTM 스택 위에 자체 Alert 관리 서비스를 구축하는 방향을 선택했습니다.
2. 전체 아키텍처
이번 구축의 목표는 통합관제 시스템 자체를 새로 만드는 것이 아니었습니다.
이미 운영 중인 통합관제 체계 앞단에서 Observability 데이터를 기반으로 Alert 이벤트를 생성하고, 이를 관제 시스템이 이해할 수 있는 표준 이벤트 형태로 전달하는 것이 핵심이었습니다.
전체 흐름은 다음과 같습니다
![[구축사례] kt cloud PLATFORM Observability Alert 플랫폼 구축하기](https://blog.kakaocdn.net/dna/wzvCi/dJMcagUcmt2/AAAAAAAAAAAAAAAAAAAAAA1XjPbXrhBi4VCJkIEic4l6qGHQIyHmZBenxYwDk7aL/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1788188399&allow_ip=&allow_referer=&signature=ubLJXCTzHO%2Fdw7YpCnmYFKPg63E%3D)
이 구조에서 Alert 관리 플랫폼은 Grafana, Mimir, Loki, 통합관제 시스템 사이의 중간 계층으로 동작합니다.
사용자는 Grafana를 통해 Alert를 관리하지만, 내부적으로는 API 계층에서 조직 정보, namespace, label, 이벤트 저장 구조를 일관되게 처리합니다.
3. 주요 설계 결정
Observability Alert 플랫폼을 구축하면서 가장 중요하게 본 지점은 단순히 Alert Rule을 생성하고 발송하는 기능이 아니었습니다.
실제 운영 환경에서는 여러 조직이 하나의 플랫폼을 함께 사용하고, Alert 이벤트가 통합관제 시스템까지 안정적으로 전달되어야 하며, 이후 장애 분석을 위해 이력도 남아야 합니다.
이를 위해 Alert 관리 계층에서는 다음 네 가지 설계 결정을 내렸습니다.
![[구축사례] kt cloud PLATFORM Observability Alert 플랫폼 구축하기](https://blog.kakaocdn.net/dna/L2AEm/dJMcahexjwa/AAAAAAAAAAAAAAAAAAAAAMGz56kKb0VwoIiPdtzU3M5sdgEyslrQ7HhGv0osnXUr/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1788188399&allow_ip=&allow_referer=&signature=6YGf9D%2FK%2FbYUJEu9YTf4kdB2o0A%3D)
결정 1. 조직별 Alert 격리는 Namespace Prefix 방식으로 구현
KCP 환경에서는 여러 조직이 하나의 Observability Platform을 함께 사용합니다.
하지만 Alert Rule, Notification Policy, Silence와 같은 운영 설정은 조직별로 독립적으로 관리되어야 합니다.
이를 위해 두 가지 방식을 검토했습니다.
첫 번째는 클러스터 또는 백엔드 인스턴스를 조직별로 분리하는 방식입니다.
격리 수준은 높지만 조직이 늘어날수록 Mimir, Loki, Alertmanager 등의 컴포넌트를 각각 운영해야 하므로 인프라 비용과 운영 복잡도가 커집니다.
두 번째는 API 계층에서 namespace prefix를 주입하는 방식입니다.
Mimir와 Loki가 단일 인스턴스에서도 여러 tenant와 namespace를 처리할 수 있다는 점을 활용해, Alert 관리 API가 Rule 저장 시 namespace 앞에 조직 식별자를 추가하는 방식입니다.
예를 들어 특정 조직에서 cpu-alert라는 namespace를 생성하면, 백엔드에는 실제로 다음과 같이 저장됩니다.
cpu-alert → teamA_cpu-alert
저희는 두 번째 방식을 선택했습니다.
별도 인프라를 추가하지 않고도 조직 단위 격리를 구현할 수 있고, 사용자는 복잡한 backend tenant 구조를 직접 알 필요 없이 Grafana Organization 기준으로 Alert를 관리할 수 있기 때문입니다.
즉, Alert 관리 API 계층이 UI의 조직 구조와 백엔드의 namespace 구조 사이를 연결하는 역할을 하도록 설계했습니다.
결정 2. 통합관제 연계를 위해 Label 체계를 표준화
Alert를 통합관제 시스템으로 전달할 때 중요한 것은 Alert 조건 자체보다 이벤트를 식별할 수 있는 메타데이터였습니다.
예를 들어 CPU 사용률이 임계치를 초과했다는 Alert가 발생해도, 그 정보만으로는 관제 시스템이 이벤트를 정확히 처리하기 어렵습니다. 실제 운영에서는 다음 정보가 함께 필요합니다.
- 어떤 서비스 또는 인프라 대상에서 발생했는가
- 어느 지역 또는 영역에 속하는가
- 이벤트 유형은 Infra, Platform, Service 중 무엇인가
- 심각도는 어느 수준인가
- 관제 대상 식별자는 무엇인가
- 현재 상태가 발생인지, 해제인지
이를 위해 Alert Rule 생성 단계에서 필요한 label 체계를 정의했습니다.
관제 시스템으로 연계되는 Alert의 경우 필수 label이 누락되면 Rule 생성을 제한하도록 했습니다. 잘못된 label을 가진 Alert가 생성되면 이후 관제 시스템에서 대상을 찾지 못하거나 잘못된 이벤트로 분류될 수 있기 때문입니다.
이 과정에서 얻은 인사이트는 Alert 메시지보다 Label 설계가 운영 품질에 더 큰 영향을 준다는 점이었습니다.
메시지 문구가 잘 작성되어 있어도 label이 부정확하면 관제 시스템은 해당 이벤트를 올바른 대상으로 연결할 수 없습니다. 반대로 label 체계가 표준화되어 있으면 이벤트 분류, 담당 조직 식별, 후속 자동화까지 훨씬 수월해집니다.
결정 3. Alert 이벤트 저장 시 Loki 카디널리티를 낮게 유지
Alert 이벤트는 발생 순간에만 필요한 정보가 아닙니다.
장애가 언제 발생했고, 언제 해제되었으며, 어떤 대상에서 반복적으로 발생했는지 확인하려면 이력이 필요합니다.
이를 위해 Alert 이벤트를 Loki에 구조화된 로그 형태로 저장했습니다.
다만 모든 필드를 Loki label로 저장하지는 않았습니다.
Loki는 Stream Label을 기준으로 로그 스트림을 인덱싱합니다.
label 개수가 많아지거나 label 값의 종류가 지나치게 많아지면 카디널리티가 증가하고, 저장소 부하와 조회 비용이 커질 수 있습니다.
그래서 저장 필드를 두 가지로 나누었습니다.
| 구분 | 저장 필드 예시 | 용도 |
| Stream Label | status, event_level, type, region |
빠른 필터링에 사용하는 저카디널리티 필드 |
| JSON Log Line | event_id, alertname, target_ip, target_name, fingerprint, dashboard_url |
상세 조회와 분석에 사용하는 고카디널리티 필드 |
status, event_level, type, region처럼 값의 종류가 제한적이고 조회 조건으로 자주 사용하는 정보는 Stream Label로 저장했습니다.
반면 event_id, target_ip, fingerprint처럼 이벤트마다 값이 달라질 수 있는 필드는 JSON 로그 라인에 저장했습니다.
이 구조를 통해 통합관제 시스템은 저장된 이벤트를 조회 API를 통해 가져가도록 구성했습니다. Loki의 카디널리티를 낮게 유지하면서도, Alert History 조회와 장애 재발 분석에 필요한 상세 데이터는 함께 보존할 수 있었습니다.
결정 4. Rule 조회는 PostgreSQL First 전략으로 처리
Alert Rule 목록을 조회할 때마다 Mimir나 Loki에 직접 요청하면 백엔드 상태에 따라 응답 속도와 안정성이 영향을 받을 수 있습니다.
예를 들어 Mimir나 Loki가 일시적으로 불안정한 상황에서도 운영자는 현재 등록된 Rule 목록을 확인해야 합니다. 또한 Rule 수가 많아질수록 매번 백엔드 API를 직접 조회하는 방식은 응답 속도 측면에서도 부담이 될 수 있습니다.
이를 보완하기 위해 Alert 관리 계층에서는 PostgreSQL First 조회 전략을 적용했습니다.
Rule 생성, 수정, 삭제 시에는 PostgreSQL과 Mimir 또는 Loki에 모두 반영합니다.
그리고 Rule 목록을 조회할 때는 PostgreSQL을 우선 조회 소스로 사용합니다.
이 방식의 장점은 두 가지입니다.
첫째, 가용성입니다.
Mimir나 Loki가 일시적으로 불안정하더라도 PostgreSQL에 저장된 Rule 정보를 기준으로 목록 조회를 계속 제공할 수 있습니다.
둘째, 조회 성능입니다.
PostgreSQL의 인덱스를 활용하면 조직, namespace, Rule 이름, 상태 등 다양한 조건으로 Rule을 빠르게 조회할 수 있습니다.
물론 이 구조에서는 PostgreSQL과 Mimir/Loki 간 정합성 관리가 중요합니다.
Rule 생성, 수정, 삭제 과정에서 한쪽만 성공하고 다른 한쪽은 실패하는 상황이 발생할 수 있기 때문입니다. 따라서 요청 처리 순서와 실패 시 보상 처리도 함께 고려해야 했습니다.
결과적으로 PostgreSQL은 단순 캐시가 아니라, Alert 관리 계층에서 Rule 조회와 운영 정책 데이터를 안정적으로 제공하기 위한 기준 저장소 역할을 하도록 설계했습니다.
4. 운영하면서 배운 것들
Alert 시스템은 알림 발송 도구가 아니라 운영 정책 시스템이다
개발 초기에는 Alert Rule 등록과 Notification 발송 자체가 목표였습니다. 그런데 실제 운영 환경에 적용해보니, 발송 자체보다 다음 질문들이 훨씬 더 중요했습니다.
- 어떤 팀에 어떤 Alert를 보낼 것인가?
- 이 이벤트의 성격은 무엇이고 누가 관리하는가?
- 실제로 정상 발송되었는가?
- 배포·점검 시간에는 어떻게 Alert를 억제할 것인가?
이 질문들에 답하는 과정에서 Silence 기능(배포·점검 시 일시 중지), 조직별 Notification Policy, 통합관제 연동 매핑 체계 등이 설계에 추가됐습니다.
Label 설계가 Alert 품질을 결정한다
통합관제 연동 과정에서 가장 어려웠던 부분은 기술 구현이 아니라 Label 체계 표준화였습니다. Alert 메시지 내용보다, type, region, zone, target_name 같은 Label을 어떻게 정의하고 표준화하느냐가 실제 운영 품질에 훨씬 더 큰 영향을 줬습니다.
레이블 체계 없이 Alert만 보내면 통합관제 측에서 "이게 어느 서비스의 어떤 이벤트인지"를 파악하기 어렵습니다. Alert 메시지 설계보다 레이블 설계가 먼저라는 것을 경험했습니다.
오픈소스로 SaaS 수준 운영 체계 구현 가능성 확인했다
LGTM 오픈소스 스택과 자체 개발 서비스의 조합으로, 외부 SaaS 없이도 Org 격리, Alert 정책 관리, 다채널 Notification(Slack·Email), 통합관제 시스템 연동이 가능한 수준의 Alert 체계를 구성할 수 있었습니다.
다만 단순 기능 구현보다 운영 정책·확장성·표준화·조직 구조를 함께 고려해야 안정적인 플랫폼 운영이 가능하다는 점을 확인했습니다.
5. 마무리

이번 설계에서 가장 중요한 점은 Alert 플랫폼을 단순한 Rule 등록 도구로 보지 않았다는 것입니다.
운영 환경에서 Alert는 조직별 권한, 관제 대상 식별, 이벤트 이력, 조회 성능, 백엔드 안정성과 모두 연결됩니다.
따라서 Alert 관리 계층은 단순히 알림을 보내는 역할이 아니라, Observability 데이터와 통합관제 체계 사이에서 운영 이벤트를 표준화하고 관리하는 역할을 해야 했습니다.
결과적으로 KCP Observability Platform에서 발생한 Alert를 단순 알림이 아니라, 조직별로 관리되고 통합관제 시스템과 연결 가능한 운영 이벤트로 확장할 수 있었습니다.
앞으로는 Alert 발생·해제 이력과 Notification 전송 이력을 더 고도화해 장애 분석, 운영 리포트, 반복 장애 패턴 분석까지 활용할 수 있는 구조로 발전시켜 나갈 계획입니다.
?› 자주 묻는 질문 FAQ
'Tech Story > Cloud Architecture' 카테고리의 다른 글
| [구축사례] 흩어진 운영 데이터를 하나로, kt cloud 운영 데이터 통합 플랫폼 Deck 구축기 (0) | 2026.08.06 |
|---|---|
| [기술사례] OVN ACL Flow Sampling 기반 VPC Flow Log 서비스 개발 (0) | 2026.07.31 |
| [구축사례] IPFIX와 Goflow2로 구현한 kt cloud Network 미터링 내재화 (0) | 2026.07.24 |
| [구축사례] kt cloud PLATFORM OpenStack 검증용 Zuul.CI Gating System 구축 (0) | 2026.07.16 |
| [기술사례] Ceph 기반 스토리지 내재화로 상용 스토리지 대체하기 (0) | 2026.07.13 |