Kubernetes Observability
Obeservability 에서 중요한 3 가지 요인은
- Metrics : CPU, 메모리, 네트워크 등 수치화된 성능 데이터를 수집
- Logs : 애플리케이션·시스템 레벨의 텍스트 기록
- Tracing : 마이크로서비스 간 요청 흐름과 지연 시간을 추적
이 세 가지가 함게 작동할 때 서비스의 상태를 관찰하고 문제 상황의 원인을 빠르게 파악할 수 있다.
1. Metrics
1.1 Metrics Server
Kubernetes Cluster 안에서 리소스 사용량 (CPU, 메모리 등)을 수집하고 제공해주는 경량화된 모니터링 컴포넌트이다.
각 Node에서 실행 중인 kubelet 이 내장하고 cAdvisor를 통해 Node와 Pod의 실시간 리소스 사용 정보를 가져온다.
그리고 이 데이터를 수집해서 Kubernetes에서 접근할 수 있도록 metrics.k8s.io API 형태로 제공한다.
Metrics Service 는
각 Node의 CPU, 메모리 사용량
각 Pod 단위의 CPU, 메모리 사용량
정보를 수집한다.
kubectl top nodes # 각 노드의 리소스 사용량 확인
kubectl top pods # 각 Pod의 리소스 사용량 확인
위와 같은 명령어로 Kubernetes 내부에서 직접 조회할 수 있다. 단 kubectl top은 Metrics Server 가 설치되어있어야한다.
** Metrics Server 는 모니터링에도 활용이 되지만 자동화 기능에도 핵심적인 역할은 한다. Kubernetes 에서 Pod 를 자동으로 조절하는 HPA (Horizontal Pod Autoscaler)는 Metrics Server 가 제공하는 데이터를 기반으로 동작한다.
HPA는 Application의 CPU 나 메모리 사용량을 기준으로 Pod의 수를 자동으로 늘리거나 줄여준다.
# HPA example
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
metrics 부분을 살펴보면 cpu 를 기준으로 averageutilization 평균 사용량이 70%를 기준으로 동작하는 것을 볼 수 있다.
Pod 실행 중 → kubelet이 리소스 사용량 수집
↓
Metrics Server가 데이터 집계
↓
metrics.k8s.io API에 제공
↓
HPA 컨트롤러가 주기적으로 확인
↓
필요 시 Pod 수 자동 조정
1.2 Prometheus
Opensource 모니터링 및 알림 시스템으로 주로 time-series를 수집해서 저장하고 분석한다. 시간에 따라 변화하는 CPU 사용량, 메모리, 요청 수 같은 데이터를 수집하고 이를 기반으로 차트를 만들거나 알람을 설정할 수 있다.
Prometheus 는 metrics endpoint 에 주기적으로 접근해서 데이터를 pull 하는 방식을 사용한다. 대상이 되는 애플리케이션이나 Node는 일반적으로 /metrics 라는 HTTP Endpoint를 가지고 있어야 한다.
PromQL (Prometheus Query Language)
Prometheus는 데이터를 검색 및 분석하기 위해 자체적으로 Query Language 인 PromQL을 사용한다.
rate(http_requests_total[5m]) # 최근 5분간의 HTTP 요청 수 변화율
Prometheus Operator
Prometheus 관련 Resource ( Prometheus, Alertmanager 등)를 Kubernetes Custom Resource 로 관릴하게 해주는 Controller 이다.
Prometheus 는 Query 결과를 기준으로 알림을 발생시킬 수 있다 .해당 알림의 규칙을 정의는 것은 PrometheusRule 이고 아림은 Alertmanager 로 전송되어서 Slack, Email, WebHook 등으로 전달된다.
2. Logs 중앙집중형 로깅 시스템
Kubernetes는 기본적으로 각 Pod의 Log가 Cotainer 내 stdout /stderr 로 출력된다. 이 로그는 Node File System에 일시적으로 저장되며, Pod가 재시작되거나 사리지면 로그도 같이 사라진다. 따라서 OS 환경에서 중앙에서 로그를 수집, 보관 및 분석할 수 있는 구조가 필요하다. 그리고 이걸 중앙집중형 로깅 (Centralized Logging) 이라고 한다.
2.1 Node - Level (DaemonSet Based)
- Fluentd, Fluent Bit
Node 에 DaemonSet으로 배포된 로그 수집 Agent 로 각 Node 의 /var/log/containers 또는 /var/log/pods Directory 에서 Container Log File을 읽어온다. Pod에 직접적으로 접근하기 보다는 Node 단위에서 전체 로그를 수집하는 방식이다.
2.2 Sidecar - Pattern
로그 컨테이너를 별도로 배치하는 방법이다.
애플리케이션 컨테이너 옆에 로그만 수집하는 sidecar container를 같이 배포한다. 애플리케이션이 로그를 작성하면 sidecar가 해당 파일을 실시간으로 읽어서 전송한다.
3, Tracing
하나의 요청이 여러 시스템(마이크로서비스, Pod)를 거쳐서 처리될 때 해당 요청이 어떤 순서로 어디를 거쳤고, 각 단계에서 얼마나 시간이 걸렸는 지를 시작으로 추적하는 기법이다.
마이크로서비스 아키텍쳐에서는 하나의 사용자 요쳥이 수많은 서비스와 Pod, API Gateway, DB 등 여러 단계를 거쳐서 처리된다. 이러한 구조에서 문제상황이 발생했을 때, 해당 문제가 어디서 발생했는 지 빠르게 파악하기 위한 것이 Tracing 의 목적이다.
대표적인 Tool은 Jaeger, Zipkin, OpenTelemetry 가 있다.
3.1 Instrumentation
각 애플리케이션은 Tracing 용 라이브러리 또는 SDK를 삽입한다. 이는 Instrumentation 이라고 부르며
요청 시작 시 Trace ID, Span ID 를 생성하고 요청 흐름에 따라 Span (작업 단위)를 생성한다.
그리고 TraceContext를 HTTP Header 나 gRPC metadata 로 다른 서비스에 전달한다.
Span ID ( 요청 내 특정 작업 단위 식별자 )
3.2 TraceContext 전파
예를 들어 프론트엔드 서비스가 백엔드 서비스를 요청할 때
HTTP Request Header 에
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
이와같은 Trace 정보가 들어간다. 해당 정보는 OpenTelemetry 나 Jaeger SDK 가 자동으로 처리해주고 다음 서비스가 이를 받아 다시 Span 을 만들고 이어붙인다.
3.3 Span 생성 및 Collector 전송
각 서비스에서 생성된 Span 은 Collector 로 전송된다.
Span 에는 시작 / 종료 시간, Tag(Http method, status code etc), 호출 대상 정보(URL, Service Name 등) 이러한 Span 들이 연결되어서 하나의 Trace Tree 를 구성한다.
3.4 UI
Collector에 저장된 Span 정보는 Jaeger UI나 Zipkin UI 같은 도구를 통해
다음과 같은 형태로 시각화된다.
Trace ID: 1234abcd...
frontend → auth-service → user-service → db
frontend 10ms
↳ auth 45ms
↳ user 25ms
↳ db 80ms
4. Alerting & Dashboard
Alerting은 사전에 정의된 임계치나 복합적인 조건이 만족되었을 때 자동으로 알림을 보내게 된다. 이때 대표적으로 사용되는 서비스는 Prometheus Alertmanager과 Grafana Alerts 가 있다.
예를 들어 prmetheus Alertmanager 는
Alertmanager는 Prometheus Server가 생성한 Alert(알림 이벤트)을 수집해 Grouping, Silencing, Routing 등의 처리를 수행한 뒤 최종적으로 Slack, Email, PagerDuty, OpsGenie 등 다양한 알림 수단으로 전송한다.