목차
OpenTelemetry K8s 모니터링, 비용 효율적인 구축 전략
안녕하세요, 13년차의 서버실 주인장입니다. 😎
요즘 Kubernetes(쿠버네티스) 환경에서 애플리케이션을 운영하는 건 거의 기본이 되었죠. 근데 이 복잡한 환경을 제대로 모니터링하는 게 정말 쉽지 않더라고요. 특히 OpenTelemetry K8s 모니터링은 분산 시스템의 가시성(Observability)을 확보하는 데 필수적인데, 이걸 어떻게 구축해야 할지 막막한 분들이 많으실 거예요.
비용 문제도 무시할 수 없죠. 상용 모니터링 솔루션은 비싸고, 직접 구축하려니 삽질이 이만저만이 아니거든요. 😅
오늘은 제가 직접 Kubernetes 모니터링을 OpenTelemetry로 구축하면서 겪었던 삽질과, 어떻게 하면 비용 효율적인 구축 전략을 가져갈 수 있는지 제 경험을 바탕으로 이야기해보려 합니다. 초기엔 저도 뭐가 뭔지 헷갈렸는데, 결국 해내고 나니 뿌듯하더라고요. 함께 가시죠! 💪
OpenTelemetry를 활용한 Kubernetes 모니터링 아키텍처는 위 그림처럼 구성할 수 있습니다. 데이터를 수집하고 백엔드로 보내는 과정이 깔끔하죠.
개념 설명: OpenTelemetry, K8s 모니터링의 핵심
자, 그럼 핵심 개념부터 간단히 짚고 넘어갈까요?
- Observability(옵저버빌리티): 시스템 내부 상태를 외부에서 추론할 수 있는 능력입니다. 주로 Metrics(메트릭), Logs(로그), Traces(트레이스) 세 가지 기둥으로 구성되거든요. 이 세 가지를 제대로 봐야 시스템에서 무슨 일이 일어나는지 파악할 수 있죠.
- OpenTelemetry(오픈텔레메트리): 이 옵저버빌리티 데이터를 수집하고, 처리하고, 내보내는 표준화된 프레임워크입니다. 벤더 종속성을 줄여주는 엄청난 장점이 있어요. 예전에는 각 모니터링 솔루션마다 에이전트를 다르게 심고 그랬었는데, OpenTelemetry 덕분에 한 번만 계측(Instrumentation)하면 다양한 백엔드로 데이터를 보낼 수 있게 된 거죠. 이게 진짜 편하더라고요!
- Kubernetes 모니터링: K8s 클러스터 내의 Pod(파드), Node(노드), Deployment(디플로이먼트) 등의 상태와 성능을 지속적으로 관찰하는 활동입니다. CPU 사용량, 메모리, 네트워크 트래픽부터 애플리케이션 로그, 에러 트레이스까지 다 포함되거든요.
- 비용 분석: 모니터링 솔루션은 데이터 수집량에 따라 비용이 천차만별입니다. 특히 클라우드 환경에서는 데이터 전송량, 저장량, 쿼리량 등에 따라 과금되기 때문에, 불필요한 데이터를 줄이고 효율적으로 관리하는 전략이 정말 중요하더라고요. 놓치면 배보다 배꼽이 더 커질 수 있거든요.
실전 구현: OpenTelemetry Collector와 백엔드 구축
이제 본격적으로 OpenTelemetry Collector를 K8s에 배포하고, 데이터를 수집하는 방법을 알아볼게요. 저는 비용 효율성을 위해 Prometheus(프로메테우스) + Grafana(그라파나) 조합으로 메트릭을, Loki(로키)로 로그를, Jaeger(예거)로 트레이스를 수집하는 방법을 선호합니다. 다 오픈소스라서 초기 비용 부담이 적거든요. 제 홈랩에서도 이 조합으로 잘 쓰고 있습니다. 👍
먼저 OpenTelemetry Collector를 DaemonSet(데몬셋)으로 배포해서 각 노드에서 데이터를 수집하도록 설정합니다. 이게 가장 일반적이고 안정적인 방법이에요.
# opentelemetry-collector-daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: otel-collector
namespace: monitoring
labels:
app: otel-collector
spec:
selector:
matchLabels:
app: otel-collector
template:
metadata:
labels:
app: otel-collector
spec:
serviceAccountName: otel-collector
containers:
- name: otel-collector
image: otel/opentelemetry-collector:0.87.0 # 최신 안정 버전 확인 필요합니다. 공식 도커 허브를 참고하세요!
command: ["--config=/conf/otel-collector-config.yaml"]
volumeMounts:
- name: otel-collector-config-vol
mountPath: /conf
- name: host-proc
mountPath: /proc
readOnly: true
- name: host-sys
mountPath: /sys
readOnly: true
securityContext:
privileged: true # 노드 메트릭 수집을 위해 필요할 수 있습니다. 보안에 유의하세요.
volumes:
- name: otel-collector-config-vol
configMap:
name: otel-collector-config
- name: host-proc
hostPath:
path: /proc
- name: host-sys
hostPath:
path: /sys
다음은 ConfigMap(컨피그맵)으로 OpenTelemetry Collector의 설정을 정의합니다. 여기서 중요한 건 어떤 데이터를 수집해서 어디로 보낼지 정의하는 부분이에요. Receivers, Processors, Exporters가 핵심이죠.
# opentelemetry-collector-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: otel-collector-config
namespace: monitoring
data:
otel-collector-config.yaml: |
receivers:
otlp:
protocols:
grpc:
http:
prometheus:
config:
scrape_configs:
- job_name: 'kubernetes-nodes'
scrape_interval: 15s
kubernetes_sd_configs:
- role: node
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- target_label: __address__
replacement: kubernetes.default.svc:443
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
target_label: __metrics_path__
replacement: /api/v1/nodes/${1}/proxy/metrics
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
target_label: __address__
replacement: $1:$2
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: kubernetes_pod_name
processors:
batch:
send_batch_size: 1000
timeout: 5s
memory_limiter:
limit_mib: 200
spike_limit_mib: 50
resourcedetection:
detectors: [env, system, kubernetes]
timeout: 2s
kubernetes:
pod_association:
- from: cgroup
- from: resource_attribute
key: k8s.pod.uid
attributes:
actions:
- key: host.name
action: delete
- key: host.id
action: delete
- key: os.type
action: delete
exporters:
prometheus:
endpoint: "0.0.0.0:8889" # Prometheus가 이 엔드포인트를 스크래핑하여 메트릭 수집
prometheusremotewrite:
endpoint: "http://prometheus-server.monitoring.svc.cluster.local:9090/api/v1/write" # Prometheus Remote Write API
otlp/logs:
endpoint: "loki.monitoring.svc.cluster.local:3100" # Loki OTLP/HTTP Endpoint
tls:
insecure: true # 개발 환경에서만 사용하세요. 프로덕션에서는 TLS 구성이 필요합니다.
otlp/traces:
endpoint: "jaeger-collector.monitoring.svc.cluster.local:14250" # Jaeger gRPC Endpoint
tls:
insecure: true # 개발 환경에서만 사용하세요. 프로덕션에서는 TLS 구성이 필요합니다.
service:
pipelines:
metrics:
receivers: [otlp, prometheus]
processors: [resourcedetection, attributes, batch, memory_limiter]
exporters: [prometheus, prometheusremotewrite] # prometheus는 메트릭 노출, prometheusremotewrite는 원격 Prometheus로 전송
logs:
receivers: [otlp]
processors: [resourcedetection, attributes, batch, memory_limiter]
exporters: [otlp/logs]
traces:
receivers: [otlp]
processors: [resourcedetection, attributes, batch, memory_limiter]
exporters: [otlp/traces]
여기서 exporters 부분을 보면 Prometheus, Loki, Jaeger로 데이터를 보내도록 설정한 걸 볼 수 있죠. 각 백엔드에 맞게 엔드포인트를 지정해주면 됩니다. 특히 processors 섹션에서 attributes를 사용해서 불필요한 메트릭 속성들을 제거하는 게 비용 효율적인 모니터링에 큰 도움이 되더라고요. 클라우드에서 데이터 전송량이나 저장량 줄이는 데 효과 만점입니다. 💡
OpenTelemetry Collector와 모니터링 백엔드 간의 상세 데이터 흐름 구성도입니다. 이 그림을 보면서 각 컴포넌트가 어떻게 연결되는지 쉽게 이해할 수 있을 거예요.
주의사항/트러블슈팅: 삽질 피하기! ⚠️
제가 이 부분에서 삽질을 좀 많이 했었습니다. 여러분은 이런 실수 안 하시길 바라면서 몇 가지 중요한 주의사항과 해결법을 공유해드릴게요. 멘토의 조언이라고 생각해주세요! 😉
- ⚠️ 권한 문제: OpenTelemetry Collector가 노드 메트릭을 제대로 수집하려면
host-proc,host-sys마운트와privileged: true설정이 필요할 수 있거든요. 보안상 민감한 부분이니 필요한 최소한의 권한만 부여하는 게 중요해요. 처음엔 권한 부족으로 메트릭이 안 들어와서 한참 헤맸습니다. - ⚠️ 설정 파일 오타: YAML 파일은 스페이스 하나에도 민감하죠. 특히 ConfigMap에
data아래에otel-collector-config.yaml: |부분의 들여쓰기를 조심하세요. 오타 하나 때문에 Collector가 시작도 안 되는 경우가 허다하거든요.kubectl logs로 Collector Pod의 로그를 꼭 확인하세요. - ⚠️ 네트워크 문제: 백엔드(Prometheus, Loki, Jaeger)의 서비스 이름과 포트가 정확한지 확인해야 합니다. 특히 K8s 클러스터 내에서
service.namespace.svc.cluster.local형태로 접근하는 게 일반적이에요. 방화벽이나 NetworkPolicy(네트워크 정책) 때문에 통신이 안 되는 경우도 많으니kubectl exec로 Collector Pod에 들어가서curl등으로 연결 테스트를 해보는 게 좋습니다. - 💡 데이터 과부하: OpenTelemetry Collector의
memory_limiter와batch프로세서를 적절히 설정해서 Collector가 과도한 리소스를 사용하거나, 데이터 전송에 병목이 생기는 걸 방지해야 합니다. 저도 한 번 Collector가 메모리 폭주해서 노드가 비정상적으로 동작하는 바람에 새벽에 호출된 적이 있습니다... 😅
검증/결과: 모니터링 대시보드 확인
이제 모든 설정이 끝났으니, 제대로 동작하는지 확인해볼 시간입니다! 🎉 드디어 됐다! 하고 외칠 준비 되셨죠?
- 먼저 Grafana(그라파나)에 접속해서 Prometheus 데이터 소스를 추가하고, Kubernetes 노드/파드 메트릭 대시보드를 임포트해보세요. 저는 보통
Node Exporter Full이나Kubernetes / Kubelet대시보드를 사용합니다. - 로그는 Loki에 쌓인 데이터를 Grafana의 Explore(탐색) 기능으로 확인하거나, Loki 전용 대시보드를 만들어 볼 수 있습니다.
logcli같은 도구로도 확인 가능하고요. - 트레이스는 Jaeger UI에 접속해서 애플리케이션에서 보낸 트레이스가 잘 수집되는지 확인합니다. 서비스 이름과 오퍼레이션 이름으로 검색해보면 되겠죠.
OpenTelemetry로 수집한 Kubernetes 메트릭을 Grafana 대시보드에서 시각화한 모습입니다. 이렇게 한눈에 시스템 상태를 파악할 수 있으면 얼마나 든든한지 몰라요!
마무리: 비용 효율과 미래를 위한 전략
오늘은 OpenTelemetry K8s 모니터링을 비용 효율적으로 구축하는 전략에 대해 제 경험을 공유해드렸습니다.
가장 중요한 포인트는 OpenTelemetry를 통해 특정 벤더에 종속되지 않고, 오픈소스 백엔드(Prometheus, Grafana, Loki, Jaeger)를 활용하여 초기 구축 비용을 최소화하는 것이었습니다. 이 조합은 특히 홈랩이나 소규모 프로젝트에서 빛을 발하더라고요.
특히 OpenTelemetry Collector의 processors를 활용하여 불필요한 데이터를 필터링하고, 샘플링(Sampling) 전략을 적용하는 것이 클라우드 환경에서 비용 분석 및 절감에 큰 영향을 미친다는 점을 꼭 기억해주세요. 제가 이 부분에서 시행착오를 많이 겪었거든요. 데이터 양을 줄이는 게 진짜 중요합니다!
Kubernetes 모니터링은 한 번 구축했다고 끝이 아닙니다. 지속적으로 데이터를 분석하고, 대시보드를 개선하며, 새로운 요구사항에 맞춰 시스템을 확장해나가야 하거든요. OpenTelemetry는 앞으로도 옵저버빌리티 분야에서 핵심적인 역할을 할 것이 분명합니다. 여러분의 환경에 맞춰 최적의 비용 효율적인 구축 전략을 찾아보시길 바랍니다. 다음 기회에 심화 내용을 다뤄볼게요! 😊
OpenTelemetry를 통한 모니터링 구축은 단순히 기술적인 선택을 넘어, 장기적인 관점에서 비용 효율성과 유연성을 확보하는 전략적인 결정이 될 수 있습니다.
'IT > k8s' 카테고리의 다른 글
| [K8s] Pod Security Admission 1년 사용 후기 및 실수담 (0) | 2026.06.10 |
|---|---|
| [Kubernetes] External Secrets Operator 보안 강화 체크리스트 10가지 (0) | 2026.06.08 |
| [k8s] OpenShift 비용 최적화: 실제 청구서와 예상 비용 불일치 분석 (0) | 2026.06.04 |
| [K8s] 쿠버네티스 비용 최적화 5가지 핵심 전략 - 클라우드 비용 폭탄 방지 (0) | 2026.06.04 |
| [Kubernetes] OpenTelemetry K8s 분산 추적: 13년차 삽질 & 활용 사례 (0) | 2026.06.04 |
| [k8s] Calico 네트워크 정책 베스트 프랙티스: 프로덕션 환경 보안 강화 체크리스트 (1) | 2026.06.01 |