Grafana
Grafana는 Lumie 인프라의 중앙 시각화 플랫폼으로, 메트릭, 로그, 트레이스를 통합하여 포괄적인 관찰 가능성 대시보드를 제공합니다.
아키텍처
배포 구성
- 네임스페이스:
grafana - 차트:
grafanav10.4.3 - 이미지:
zot.lumie-infra.com/grafana/grafana:12.3.2 - 복제본: 1개
- 데이터베이스: PostgreSQL (공유 infra-db 클러스터)
데이터 소스 통합
데이터 소스 설정
기본 데이터 소스
Grafana는 다음 데이터 소스들과 자동으로 연결됩니다:
datasources:
# 기본 메트릭 소스 (Thanos)
- name: Thanos
type: prometheus
url: http://thanos-query.thanos.svc.cluster.local:9090
isDefault: true
# 직접 Prometheus 접근
- name: Prometheus
type: prometheus
url: http://prometheus-kube-prometheus-prometheus.prometheus.svc.cluster.local:9090
# 로그 데이터
- name: Loki
type: loki
url: http://loki.loki.svc.cluster.local:3100
# 트레이싱 데이터
- name: Tempo
type: tempo
url: http://tempo.tempo.svc.cluster.local:3100
# 알림 관리
- name: Alertmanager
type: alertmanager
url: http://alertmanager.alertmanager.svc.cluster.local:9093
데이터베이스 설정
PostgreSQL 연결
Grafana는 공유 PostgreSQL 클러스터를 사용하여 대시보드와 사용자 데이터를 저장합니다:
env:
GF_DATABASE_TYPE: postgres
GF_DATABASE_NAME: grafana
GF_DATABASE_SSL_MODE: disable
envValueFrom:
GF_DATABASE_HOST:
secretKeyRef:
name: grafana-db-app
key: host
GF_DATABASE_USER:
secretKeyRef:
name: grafana-db-app
key: username
GF_DATABASE_PASSWORD:
secretKeyRef:
name: grafana-db-app
key: password
인증 설정
관리자 계정은 데이터베이스 인증 정보를 사용합니다:
admin:
existingSecret: grafana-db-app
userKey: username
passwordKey: password
보안 설정
익명 접근
읽기 전용 익명 접근이 활성화되어 있습니다. 로그인 폼과 로그아웃 메뉴는 비활성화됩니다:
grafana.ini:
auth.anonymous:
enabled: true
org_role: Viewer
auth.basic:
enabled: false
auth:
disable_login_form: true
disable_signout_menu: true
임베딩 지원
대시보드 임베딩이 허용됩니다:
security:
allow_embedding: true
접근 방법
외부 인그레스는 비활성화되어 있으며, Teleport를 통해서만 접근 가능합니다:
ingress:
enabled: false
접근 방법
Teleport 접근
# Teleport 앱 로그인
tsh app login grafana
tsh app config grafana
# 브라우저에서 접근
open $(tsh app config grafana --format=uri)
포트 포워딩 (개발용)
# 포 트 포워딩
kubectl port-forward -n grafana svc/grafana 3000:80
# 브라우저에서 http://localhost:3000 접근
대시보드 관리
대시보드 가져오기
대시보드는 Grafana HTTP API를 통해 가져옵니다. 익명 접근이 Viewer로만 허용되므로, 관리 작업은 basic-auth 토글을 활성화하거나 grafana-db-app 시크릿의 admin 자격증명을 사용합니다. JSON 파일의 소스는 인프라 레포의 observability/grafana/dashboards/ 디렉터리입니다:
# Grafana API를 통한 대시보드 임포트
# (포트 포워딩 또는 Teleport 접근 후 실행)
curl -s -X POST \
-H "Content-Type: application/json" \
-u "$GRAFANA_USER:$GRAFANA_PASS" \
"http://localhost:3000/api/dashboards/import" \
-d "{\"dashboard\": $(cat dashboard.json), \"overwrite\": true, \"inputs\": [{\"name\": \"DS_THANOS\", \"type\": \"datasource\", \"pluginId\": \"prometheus\", \"value\": \"Thanos\"}]}"
대시보드 내 데이터소스는 ${datasource} 변수를 사용하여 기본(Thanos)에 바인딩됩니다.
대시보드 내보내기
# 대시보드 JSON 내보내기
curl -H "Authorization: Bearer <api-key>" \
http://grafana.grafana.svc.cluster.local/api/dashboards/uid/<dashboard-uid> \
| jq '.dashboard' > dashboard.json
권장 대시보드
인프라 모니터링
- Kubernetes Cluster Overview: 클러스터 전체 상태
- Node Exporter Full: 노드 상세 메트릭
- Kubernetes Pod Overview: 파드 리소스 사용량
애플리케이션 모니터링
- Application Performance: 요청/응답 메트릭
- Database Performance: 데이터베이스 성능
- Message Queue: RabbitMQ 메트릭
로그 분석
- Loki Dashboard: 로그 검색 및 분석
- Application Logs: 애플리케이션별 로그 뷰
쿼리 예제
메트릭 쿼리 (PromQL)
# CPU 사용률 (상위 10개 파드)
topk(10, rate(container_cpu_usage_seconds_total[5m]))
# 메모리 사용률
container_memory_working_set_bytes / container_spec_memory_limit_bytes * 100
# HTTP 요청 비율
sum(rate(http_requests_total[5m])) by (service)
# 에러율
sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) * 100
로그 쿼리 (LogQL)
# 특정 네임스페이스의 에러 로그
{k8s_namespace_name="my-app"} |= "error" | json
# 로그 레벨별 카운트
sum by (level) (count_over_time({k8s_namespace_name="my-app"} | json | __error__="" [5m]))
# 특정 시간대의 로그
{k8s_namespace_name="my-app"} | json | level="error" | line_format "{{.timestamp}} {{.message}}"
트레이스 쿼리
Tempo 데이터 소스에서 트레이스 ID로 검색하거나 서비스/오퍼레이션별로 필터링할 수 있습니다.
알림 설정
알림 규칙 생성
- Alerting → Alert Rules → New Rule
- 쿼리 조건 설정
- 평가 조건 정의
- 알림 세부사항 입력
- 라벨 및 어노테이션 추가
알림 채널 설정
Alertmanager와 통합되어 있어 별도의 알림 채널 설정이 필요하지 않습니다.
성능 최적화
리소스 설정
resources:
requests:
cpu: 22m # VPA 권장값
memory: 175Mi
limits:
memory: 283Mi # CPU 제한 없음
캐싱 설정
데이터베이스 백엔드를 사용하여 대시보드와 설정이 영구 저장됩니다.
문제 해결
대시보드가 로드되지 않는 경우
# Grafana 로그 확인
kubectl logs -n grafana deployment/grafana
# 데이터 소스 연결 확인
kubectl exec -n grafana deployment/grafana -- \
curl -s http://localhost:3000/api/datasources
데이터가 표시되지 않는 경우
# 데이터 소스 상태 확인
kubectl exec -n grafana deployment/grafana -- \
curl -s http://localhost:3000/api/datasources/proxy/1/api/v1/query?query=up
# Prometheus 연결 테스트
kubectl exec -n grafana deployment/grafana -- \
curl -s http://thanos-query.thanos.svc.cluster.local:9090/api/v1/query?query=up
데이터베이스 연결 문제
# 데이터베이스 시크릿 확인
kubectl get secret -n grafana grafana-db-app -o yaml
# PostgreSQL 연결 테스트
kubectl exec -n grafana deployment/grafana -- \
pg_isready -h infra-db-rw.infra-db.svc.cluster.local -p 5432
보안 고려사항
네트워크 보안
- 외부 인그레스 비활성화
- Teleport를 통한 안전한 접근
- 클러스터 내부 통신만 허용
데이터 보호
- PostgreSQL을 통한 영구 저장
- Vault를 통한 데이터베이스 인증 정보 관리
- 익명 접근은 읽기 전용으로 제한
모니터링 모범 사례
대시보드 설계
- 목적별 대시보드: 하나의 대시보드는 하나의 목적
- 계층적 구조: 개요 → 상세 → 디버깅 순서
- 적절한 시간 범위: 기본 1시간, 필요시 조정 가능
- 변수 활용: 네임스페이스, 서비스별 필터링
쿼리 최적화
- 적절한 시간 범위: 너무 긴 범위는 성능 저하
- 집계 활용:
sum,avg등으로 데이터 축약 - 레이블 필터링: 불필요한 시리즈 제외
- 캐싱 활용: 반복 쿼리는 변수로 저장