Kubernetes and Cloud Native Associate (KCNA) #6 Cloud Native Observability (8%): 텔레메트리, Prometheus, 비용 관리
수십 개의 Pod 가 여러 노드에 흩어져 서로를 호출하는 분산 시스템에서는, 한 요청이 느려졌을 때 어디서 무슨 일이 일어났는지가 한눈에 보이지 않습니다. 단일 서버라면 로그 파일 하나만 들여다보면 됐지만, 컨테이너가 죽고 다시 뜨고 스케일이 오르내리는 클라우드 네이티브 환경에서는 시스템의 상태를 외부에서 관측 가능한 신호로 바꿔 두지 않으면 장애의 원인을 추적할 수 없습니다. 이 능력을 다루는 도메인이 Cloud Native Observability입니다.
KCNA에서 이 도메인의 비중은 **8%**로 작지만, 출제 패턴이 정형적이라 점수를 확보하기 쉬운 구간입니다. 이번 글에서는 텔레메트리의 세 기둥, Prometheus를 중심으로 한 메트릭 수집, OpenTelemetry와 분산 추적, 신뢰성 지표(SLI,SLO,SLA), 그리고 비용 관리(FinOps)를 정리하겠습니다.
옵저버빌리티와 모니터링의 차이 #
시험에서 두 용어를 구분하는 문항이 나오므로 먼저 정리하겠습니다. **모니터링(monitoring)**은 미리 정해 둔 지표와 임계값을 지켜보는 활동입니다. “CPU 사용률이 80%를 넘으면 알림"처럼, 무엇을 볼지 이미 알고 있는 상황을 다룹니다. 반면 **옵저버빌리티(observability)**는 시스템이 내보내는 신호만으로 미리 예상하지 못한 질문에도 답할 수 있는 성질을 뜻합니다. “왜 특정 사용자의 결제만 3초 걸리는가” 같은, 사전에 대시보드로 만들어 두지 않은 질문을 사후에 파고들 수 있어야 옵저버빌리티가 있다고 말합니다.
정리하면 모니터링은 알려진 문제를 감시하는 행위이고, 옵저버빌리티는 알려지지 않은 문제까지 탐구할 수 있게 만드는 시스템의 특성입니다. 옵저버빌리티가 잘 갖춰진 시스템 위에서 모니터링이 작동한다고 이해하면 됩니다.
텔레메트리의 세 기둥 #
옵저버빌리티는 시스템이 내보내는 텔레메트리(telemetry) 데이터 위에 세워집니다. 이 데이터는 전통적으로 세 종류로 나뉘며, 각각 답하는 질문이 다릅니다. 시험에서 가장 자주 나오는 분류이므로 표로 정리하겠습니다.
| 기둥 | 형태 | 답하는 질문 | 대표 도구 |
|---|---|---|---|
| Metrics(메트릭) | 시간에 따른 수치 시계열 | 얼마나 많은가, 얼마나 빠른가 | Prometheus |
| Logs(로그) | 개별 이벤트의 기록 | 그때 정확히 무슨 일이 있었는가 | Fluentd, Loki |
| Traces(트레이스) | 한 요청이 거친 서비스 경로 | 이 요청이 어디서 느려졌는가 | Jaeger, OpenTelemetry |
메트릭은 “초당 요청 수”, “에러율”, “메모리 사용량"처럼 일정 간격으로 측정한 수치를 시간순으로 쌓은 시계열입니다. 저장 비용이 가볍고 집계가 빠르지만, 개별 사건의 세부 내용은 담지 못합니다. 로그는 애플리케이션이 특정 시점에 남긴 텍스트 이벤트로, 어떤 요청이 어떤 메시지로 실패했는지 같은 구체적 맥락을 담습니다. 대신 양이 많아 저장과 검색 비용이 큽니다. 트레이스는 하나의 요청이 여러 서비스를 거쳐 가는 전체 경로를 이어 붙인 것으로, 마이크로서비스 사이에서 어느 구간이 병목인지 짚어 줍니다.
세 기둥은 경쟁 관계가 아니라 보완 관계입니다. 메트릭으로 “에러율이 올랐다"는 사실을 감지하고, 트레이스로 “어느 서비스 구간에서 막혔는지” 좁힌 다음, 로그로 “정확히 어떤 메시지로 실패했는지” 확인하는 흐름이 전형적입니다.
Prometheus: 메트릭 수집의 표준 #
Prometheus는 메트릭 영역의 사실상 표준이며, CNCF의 졸업(Graduated) 단계 프로젝트입니다. 쿠버네티스 다음으로 CNCF에 두 번째로 졸업한 프로젝트라는 점도 종종 출제됩니다.
pull 기반 수집 #
Prometheus의 가장 큰 특징은 pull 기반 수집 모델입니다. 애플리케이션이 메트릭을 어딘가로 밀어 보내는(push) 것이 아니라, Prometheus 서버가 정해진 주기마다 대상의 /metrics 엔드포인트를 직접 긁어 옵니다. 이 행위를 **scrape(스크레이프)**라고 부릅니다. 어느 대상을 긁을지는 설정과 서비스 디스커버리로 정하며, 쿠버네티스에서는 Pod 와 Service 를 자동으로 발견해 대상 목록을 갱신합니다.
push가 아니라 pull이라는 점은 시험의 단골 함정입니다. (단기 작업처럼 살아 있는 시간이 짧아 scrape하기 어려운 경우를 위해 Pushgateway라는 보조 컴포넌트가 따로 있긴 하지만, 기본 모델은 어디까지나 pull입니다.)
exporter와 시계열 DB #
애플리케이션이 Prometheus 형식의 메트릭을 직접 노출하지 않을 때는 **exporter(익스포터)**를 둡니다. exporter는 데이터베이스,메시지 큐,노드의 하드웨어 상태 같은 외부 시스템의 상태를 읽어 Prometheus가 긁을 수 있는 형식으로 변환해 주는 어댑터입니다. 노드의 CPU,메모리,디스크를 노출하는 Node Exporter가 대표적입니다.
긁어 온 메트릭은 Prometheus 내장 **시계열 데이터베이스(TSDB)**에 저장됩니다. 각 시계열은 메트릭 이름과 라벨(label) 조합으로 식별되며, 이 라벨이 뒤에서 질의의 차원을 만듭니다.
PromQL과 메트릭 타입 #
저장된 데이터는 **PromQL(Prometheus Query Language)**로 질의합니다. 예를 들어 아래 한 줄은 최근 5분 동안 초당 HTTP 요청 수를 계산합니다.
rate(http_requests_total[5m])메트릭은 보통 다음 세 가지 타입으로 나뉩니다.
| 타입 | 의미 | 예시 |
|---|---|---|
| Counter(카운터) | 증가만 하는 누적값 | 총 요청 수, 총 에러 수 |
| Gauge(게이지) | 오르내리는 순간값 | 현재 메모리 사용량, 큐 길이 |
| Histogram(히스토그램) | 값의 분포를 버킷으로 집계 | 요청 지연의 분포(p95 등) |
카운터는 누적이라 재시작 전까지 줄어들지 않으므로, 위 예시처럼 rate()로 증가 속도를 구해 의미 있는 값으로 바꿉니다. 게이지는 현재 상태를 그대로 읽으면 됩니다. 히스토그램은 지연 시간처럼 분포가 중요한 값을 버킷에 나눠 담아, p95,p99 같은 백분위 지표를 뽑을 때 씁니다.
Alertmanager와 Grafana #
Prometheus는 수집과 질의를 맡고, 그 주변에 두 도구가 붙습니다. Alertmanager는 Prometheus가 평가한 알림 규칙(alerting rule)을 받아 중복 제거,묶기,라우팅을 거쳐 이메일,Slack,PagerDuty 같은 채널로 보냅니다. 알림 규칙을 판단하는 주체는 Prometheus이고, 발송과 라우팅을 맡는 주체가 Alertmanager라는 역할 구분이 출제 포인트입니다.
Grafana는 메트릭을 그래프와 대시보드로 보여 주는 시각화 도구입니다. Prometheus를 데이터 소스로 가장 많이 쓰지만 Grafana 자체는 Prometheus에 종속되지 않으며, 여러 데이터 소스를 한 대시보드에 모읍니다. 즉 Prometheus가 저장과 질의, Grafana가 시각화를 맡는 분업으로 이해하면 됩니다.
분산 추적과 OpenTelemetry #
마이크로서비스 환경에서는 한 요청이 게이트웨이,인증,주문,결제 등 여러 서비스를 거칩니다. 이 전체 경로를 추적하는 것이 **분산 추적(distributed tracing)**입니다.
- Trace(트레이스): 하나의 요청이 시스템을 통과한 전체 여정입니다.
- Span(스팬): 그 여정 안에서 하나의 서비스 또는 작업 단위가 차지한 구간입니다. 시작,종료 시각을 가지며, 여러 스팬이 부모-자식으로 이어져 하나의 트레이스를 이룹니다.
각 스팬의 소요 시간을 이어 보면 어느 서비스 구간이 전체 지연의 원인인지 곧바로 드러납니다.
OpenTelemetry #
**OpenTelemetry(OTel)**는 텔레메트리 데이터를 생성하고 수집하는 방식의 표준이며, CNCF 프로젝트입니다. 메트릭,로그,트레이스 세 신호를 하나의 SDK와 프로토콜(OTLP)로 다루도록 통일해, 애플리케이션 계측(instrumentation)을 특정 백엔드에 묶이지 않게 만드는 것이 목표입니다. 즉 OpenTelemetry로 계측해 두면 추적 데이터를 Jaeger로 보내든 다른 백엔드로 보내든 코드를 바꿀 필요가 없습니다.
여기서 계측은 OpenTelemetry, 저장과 조회는 백엔드라는 분업이 핵심입니다. Jaeger는 그 백엔드 가운데 대표적인 분산 추적 시스템으로, 수집한 트레이스를 저장하고 요청 경로를 시각화해 보여 주는 CNCF 프로젝트입니다.
로깅 수집 #
컨테이너 환경의 로깅은 한 가지 원칙에서 출발합니다. 컨테이너 안의 애플리케이션은 로그 파일을 직접 관리하지 않고 표준 출력(stdout)과 표준 에러(stderr)로 내보내며, 그 출력을 플랫폼이 수집합니다. 컨테이너는 언제든 죽고 다시 뜨므로, 로그를 컨테이너 안에 두면 사라지기 때문입니다.
이 출력을 모아 중앙 저장소로 보내는 도구가 **로그 수집기(log collector)**입니다. Fluentd와 더 가벼운 Fluent Bit이 CNCF 프로젝트로 널리 쓰이며, 각 노드에서 컨테이너 로그를 읽어 가공한 뒤 저장 백엔드로 전달합니다. 저장과 조회 쪽에서는 Grafana 진영의 Loki가 메트릭처럼 라벨 기반으로 로그를 다뤄 가볍게 운영된다는 점으로 자주 언급됩니다.
신뢰성 지표: SLI, SLO, SLA #
서비스가 “충분히 잘 동작하는가"를 숫자로 다루는 어휘가 SLI,SLO,SLA입니다. 세 약어를 정확히 구분하는 문항이 거의 매번 나오므로 반드시 분리해 두어야 합니다.
| 약어 | 정식 명칭 | 의미 | 예시 |
|---|---|---|---|
| SLI | Service Level Indicator | 실제로 측정한 값 | 지난 30일 가용성 99.95% |
| SLO | Service Level Objective | 내부적으로 정한 목표 | 가용성 99.9% 이상 유지 |
| SLA | Service Level Agreement | 고객과 맺은 계약(위반 시 보상) | 99.5% 미만이면 요금 환불 |
순서로 외우면 헷갈리지 않습니다. **측정값(SLI)**이 가장 안쪽에 있고, 그 측정값에 대해 조직이 스스로 세운 **목표(SLO)**가 그 위에 있으며, 고객과 법적으로 약속한 **계약(SLA)**이 가장 바깥에 있습니다. 보통 SLA보다 SLO를 더 엄격하게 잡아, 계약을 위반하기 전에 내부 목표에서 먼저 경보가 울리도록 설계합니다.
Error budget #
SLO를 100%가 아니라 99.9%로 잡으면, 나머지 0.1%만큼은 실패가 허용되는 여유가 생깁니다. 이 여유를 **error budget(에러 예산)**이라고 부릅니다. 에러 예산이 남아 있으면 새 기능을 공격적으로 배포할 여유가 있다는 뜻이고, 다 소진했으면 안정화에 집중해야 한다는 신호입니다. 안정성과 배포 속도 사이의 균형을 수치로 다루는 장치입니다.
Golden signals #
무엇을 측정해야 할지 막막할 때 기준이 되는 네 가지 핵심 지표가 **golden signals(골든 시그널)**입니다.
| 신호 | 의미 |
|---|---|
| Latency(지연) | 요청을 처리하는 데 걸리는 시간 |
| Traffic(트래픽) | 시스템이 받는 요청량 |
| Errors(에러) | 실패한 요청의 비율 |
| Saturation(포화) | 자원이 한계에 얼마나 가까운지 |
네 가지를 머리글자 순서 그대로 묶어 외워 두면, golden signals를 묻는 문항에서 빠지거나 다른 항목이 섞인 보기를 골라낼 수 있습니다.
비용 관리: FinOps #
클라우드 네이티브 환경에서는 자원을 쉽게 늘릴 수 있는 만큼 비용도 쉽게 새어 나갑니다. 그래서 옵저버빌리티의 한 갈래로 비용 가시성을 다루며, 이를 운영 문화로 묶은 것이 **FinOps(Financial Operations)**입니다. 엔지니어,재무,운영이 함께 클라우드 지출을 가시화하고, 측정한 뒤 최적화하는 반복 활동을 뜻합니다.
requests와 limits가 비용을 가른다 #
쿠버네티스에서 비용에 가장 직접적으로 작용하는 설정이 컨테이너의 resource requests와 limits입니다. requests는 스케줄러가 자리를 잡을 때 예약하는 양이라, requests를 실제 사용량보다 크게 잡으면 그만큼 노드 용량이 비어 있는 채로 예약되어 **오버프로비저닝(over-provisioning)**으로 이어집니다. 노드는 비싸게 돌아가는데 실제 사용률은 낮은 상태가 됩니다. 반대로 너무 낮게 잡으면 한도 초과로 컨테이너가 종료(OOMKilled)되거나 스로틀링이 걸립니다. 실제 사용량에 맞춰 requests와 limits를 조정하는 **rightsizing(적정화)**이 비용 관리의 출발점입니다.
OpenCost와 KubeCost #
쿠버네티스 자체는 “이 네임스페이스가 이번 달에 얼마를 썼는가"를 알려 주지 않습니다. 이 부분을 보완하는 도구가 비용 가시화 솔루션입니다. OpenCost는 쿠버네티스 비용 측정의 오픈소스 표준(CNCF 샌드박스 프로젝트)으로, Pod,네임스페이스,라벨 단위로 비용을 배분해 보여 줍니다. KubeCost는 OpenCost를 토대로 한 제품으로, 같은 비용 데이터에 최적화 추천과 대시보드를 더해 줍니다. 두 도구 모두 자원 사용량을 비용으로 환산해 누가 얼마를 쓰는지 드러내는 역할이라고 이해하면 됩니다.
시험 포인트 정리 #
이 도메인에서 자주 나오는 출제 포인트를 모으면 다음과 같습니다.
- 세 기둥의 구분. 메트릭(수치 시계열),로그(이벤트 기록),트레이스(요청의 분산 경로)가 각각 무엇을 답하는지. 셋의 역할이 뒤섞인 보기를 골라내야 합니다.
- Prometheus는 pull 모델. 대상의
/metrics를 직접 scrape합니다. push라고 적힌 보기는 함정입니다. - SLI,SLO,SLA의 구분. 측정값(SLI),목표(SLO),계약(SLA)의 순서와 정의를 헷갈리지 않아야 합니다.
- golden signals 네 가지. latency,traffic,errors,saturation입니다.
- 역할 매칭. Prometheus(수집,질의),Grafana(시각화),Alertmanager(알림 라우팅),OpenTelemetry(계측 표준),Jaeger(분산 추적 백엔드),Fluentd/Fluent Bit(로그 수집)를 한 줄씩 구분해 두어야 합니다.
- FinOps와 requests/limits. requests를 과대 설정하면 오버프로비저닝으로 비용이 샙니다.
정리 #
이번 글에서 잡은 것:
- 옵저버빌리티는 시스템의 성질, 모니터링은 알려진 지표를 지켜보는 활동. 둘은 보완 관계
- 텔레메트리 세 기둥. 메트릭(수치 시계열),로그(이벤트),트레이스(분산 경로)
- Prometheus. CNCF 졸업 프로젝트, pull 기반 scrape, exporter, 시계열 DB, PromQL, counter/gauge/histogram. 주변에 Alertmanager(알림)와 Grafana(시각화)
- OpenTelemetry. 계측의 표준, trace/span 개념. 백엔드로 Jaeger
- 로깅. 컨테이너는 stdout/stderr로 출력, Fluentd/Fluent Bit이 수집, Loki가 저장
- 신뢰성 지표. SLI(측정),SLO(목표),SLA(계약), error budget, golden signals(latency/traffic/errors/saturation)
- FinOps. requests/limits가 비용을 가르고, OpenCost/KubeCost가 비용을 가시화
옵저버빌리티의 실무 구현을 더 깊이 보고 싶다면 K8s 고급 #5 옵저버빌리티에서 Prometheus,Grafana,Loki,OpenTelemetry를 실제로 묶어 운영하는 흐름을 다룹니다.
다음: Cloud Native Application Delivery #
관측까지 갖췄다면 마지막 도메인은 애플리케이션을 클러스터로 배달하는 흐름입니다.
#7 Cloud Native Application Delivery (8%): GitOps, CI/CD에서는 GitOps의 원칙(Git을 단일 소스로 삼는 선언형 배포), ArgoCD와 Flux, CI/CD 파이프라인의 구분, 그리고 시험에 자주 나오는 배포 개념을 정리하겠습니다.