본문 바로가기
서버구축 (WEB,DB)

Superset으로 BI, Grafana로 Observability: 데이터 분석과 모니터링 통합

by 날으는물고기 2025. 8. 18.

Superset으로 BI, Grafana로 Observability: 데이터 분석과 모니터링 통합

728x90

운영 환경 기준(보안·가용성·운영 편의성) Docker Compose로 빠르게 시작하고, Kubernetes/Helm으로 확장하는 패턴을 권장합니다. Grafana와의 연계는 “데이터 소스 공유, SSO 통합, 리버스 프록시로의 경로 통합, 임베드/링킹” 순으로 점진 적용을 추천드립니다.

Superset vs Grafana, 언제/어떻게 같이 쓰나?

  1. Superset: SQL 기반 탐색형 BI/대시보드에 강함. 데이터셋(가상 테이블), 차트 조립, 대시보드 퍼블리시, 리치한 슬라이싱/필터.
  2. Grafana: 시계열/인프라/로그 관측성에 강함. 수많은 데이터소스 플러그인, 알러팅실시간 지표에 강함.
  3. 함께 쓰기 활용사례
    • 동일 데이터(예: DW/레이크/OLAP)를 각 도구에 맞게 시각화
    • Grafana로 운영 모니터링/알림, Superset으로 분석형 리포트/임원 대시보드
    • 단일 로그인(SSO), 단일 도메인 하위 경로(/grafana, /superset)로 UX 일원화

배포 아키텍처 선택

  • 단일 노드 PoC: Docker Compose (Postgres + Superset + Redis + Celery + Nginx)
  • 프로덕션/확장: Kubernetes(Helm) + 외부 Postgres/Redis + Ingress + OIDC + Secret Manager
  • 네트워크: 내부 전용 네트워크, DB는 보안 그룹/NSG로 접근 최소화, mTLS 또는 TLS

Docker Compose로 빠른 설치 (개발~파일럿)

폴더 구성

superset/
 ├─ docker-compose.yml
 ├─ superset_config.py
 └─ requirements-local.txt   # (필요 시: 추가 드라이버/라이브러리)

docker-compose.yml (예시)

version: "3.9"
services:
  superset:
    image: apache/superset:latest
    container_name: superset
    environment:
      - SUPERSET_ENV=production
      - SUPERSET_LOAD_EXAMPLES=no
      - SECRET_KEY=${SECRET_KEY:?set in .env}
      - SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://superset:superset@db:5432/superset
      - CACHE_CONFIG={'CACHE_TYPE':'RedisCache','CACHE_DEFAULT_TIMEOUT':300,'CACHE_KEY_PREFIX':'superset_','REDIS_HOST':'redis','REDIS_PORT':6379}
      - CELERY_BROKER_URL=redis://redis:6379/0
      - CELERY_RESULT_BACKEND=redis://redis:6379/1
      - SUPERSET_WEBSERVER_TIMEOUT=120
    volumes:
      - ./superset_config.py:/app/pythonpath/superset_config.py
    ports:
      - "8088:8088"
    depends_on:
      - db
      - redis

  db:
    image: postgres:15
    environment:
      - POSTGRES_DB=superset
      - POSTGRES_USER=superset
      - POSTGRES_PASSWORD=superset
    volumes:
      - dbdata:/var/lib/postgresql/data

  redis:
    image: redis:7

  # (선택) Nginx로 리버스프록시+TLS 종단
  nginx:
    image: nginx:1.25
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certs:/etc/nginx/certs:ro
    ports:
      - "443:443"
    depends_on:
      - superset
volumes:
  dbdata:

초기화

# 최초 1회 DB 초기화 & 어드민 계정
docker compose up -d
docker compose exec superset superset fab create-admin \
  --username admin --firstname Admin --lastname User \
  --email admin@example.com --password 'StrongP@ss!'
docker compose exec superset superset db upgrade
docker compose exec superset superset init

superset_config.py (핵심 보안/운영 옵션 예시)

import os

SECRET_KEY = os.getenv("SECRET_KEY")
SQLALCHEMY_DATABASE_URI = os.getenv("SQLALCHEMY_DATABASE_URI")
FEATURE_FLAGS = {
    "EMBEDDED_SUPERSET": True,   # 임베드/게스트 토큰 사용 시
    "DASHBOARD_RBAC": True,      # 대시보드 단위 권한
}
# 세션/쿠키 보안
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = "Lax"

# 임베딩용 보안 헤더 (Grafana에서 iframe 임베드 시 허용 대상 한정)
TALISMAN_ENABLED = True
TALISMAN_CONFIG = {
    "content_security_policy": {
        "default-src": ["'self'"],
        "frame-ancestors": ["'self'", "https://grafana.example.com"],
        "frame-src": ["'self'", "https://grafana.example.com"],
    },
    "force_https": True,
}

# OIDC 예시 (Keycloak/Entra/Okta 등)
from flask_appbuilder.security.manager import AUTH_OAUTH
AUTH_TYPE = AUTH_OAUTH
OAUTH_PROVIDERS = [{
    "name": "keycloak",
    "token_key": "access_token",
    "icon": "fa-address-card",
    "remote_app": {
        "api_base_url": "https://sso.example.com/realms/BI/protocol/openid-connect/",
        "client_kwargs": {"scope": "openid email profile"},
        "access_token_url": "https://sso.example.com/realms/BI/protocol/openid-connect/token",
        "authorize_url": "https://sso.example.com/realms/BI/protocol/openid-connect/auth",
        "client_id": "superset",
        "client_secret": os.getenv("OIDC_CLIENT_SECRET"),
    },
}]
AUTH_ROLES_SYNC_AT_LOGIN = True
AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = "Gamma"  # 최소 권한부터 시작

운영 팁: 알림/리포트 메일, 스케줄 차트 생성은 Celery + Redis 필요.
Docker Compose에 Celery worker/beat 컨테이너를 추가하세요.

Kubernetes/Helm 배포 (권장, 프로덕션)

Helm 차트(예시 가이드)

  • 외부 Postgres/Redis 사용
  • Ingress로 /superset 서브패스 운영
  • Secret은 KMS/Secret Manager에 저장
300x250

Values 핵심 예시

configOverrides:
  enableCORS: true
  enableEmbedded: true

env:
  - name: SECRET_KEY
    valueFrom:
      secretKeyRef: { name: superset-secrets, key: SECRET_KEY }
  - name: SQLALCHEMY_DATABASE_URI
    valueFrom:
      secretKeyRef: { name: superset-secrets, key: DB_URI }

ingress:
  enabled: true
  hosts:
    - host: bi.example.com
      paths:
        - path: /superset
          pathType: Prefix

서브패스 운영 팁

  • Superset는 서브패스 지원. SUPERSET_WEBSERVER_BASE_URL 또는 프록시+헤더 정합 필요
  • Ingress에서 X-Forwarded-* 헤더, 보안 헤더(CSP/XFO) 설정

데이터 소스 연결 (Superset & Grafana 공통)

  1. 공통 원칙: 동일한 원본 DB/엔진(예: Postgres, MySQL, ClickHouse, Trino/Presto, BigQuery, Elastic 등)을 각 도구에서 각자 연결
  2. Superset: SQLAlchemy 드라이버 설치 → Database 등록 → Dataset 생성 → 차트/대시보드
    • 예) ClickHouse연결 URI 예: clickhouse+http://user:pass@clickhouse:8123/dbname
    • pip install clickhouse-connect
  3. Grafana: 데이터소스 플러그인 추가 → 쿼리/패널 → 대시보드 → 알러트

보안: 읽기 전용 계정/스키마를 분리하고, 네트워크 ACL로 BI 레이어 → DB 최소 접근 허용.

Grafana 연계 전략 (4단계 로드맵)

1. 데이터 소스 공유(기본)

  • Superset과 Grafana가 같은 DW/DBC/OLAP을 읽도록 연결
  • 장점: 간단/안전, 도구 분리 유지
  • 체크포인트: 쿼리 비용/부하 관리, 읽기 전용 사용자, 리소스 쿼터

2. SSO/OIDC 통합(권장)

  • 같은 IdP(Keycloak/Okta/Azure AD/Entra 등)로 Superset과 Grafana 동시 연동
  • 이점: 단일 계정/그룹으로 RBAC 일원화
  • Grafana OIDC 예시 (grafana.ini)
    [server]
    domain = grafana.example.com
    root_url = https://grafana.example.com/
    
    [auth]
    disable_login_form = true
    oauth_auto_login = true
    
    [auth.generic_oauth]
    enabled = true
    name = Keycloak
    client_id = grafana
    client_secret = $__file{/etc/grafana/oidc_client_secret}
    scopes = openid profile email
    auth_url = https://sso.example.com/realms/BI/protocol/openid-connect/auth
    token_url = https://sso.example.com/realms/BI/protocol/openid-connect/token
    api_url = https://sso.example.com/realms/BI/protocol/openid-connect/userinfo
    login_attribute_path = preferred_username

3. 경로 통합(리버스 프록시)

  • 단일 도메인 bi.example.com 아래 /grafana, /superset로 서비스
  • NGINX 예시 (요지)
    server {
      listen 443 ssl http2;
      server_name bi.example.com;
      # TLS 설정 ...
    
      # 보안 헤더 (CSP/XFO/CORS는 임베드 정책에 맞춰 최소 허용)
      add_header X-Frame-Options "SAMEORIGIN" always;
      add_header Content-Security-Policy "frame-ancestors 'self' https://bi.example.com" always;
    
      location /grafana/ {
        proxy_pass http://grafana:3000/;
        proxy_set_header X-Forwarded-Prefix /grafana;
        proxy_set_header Host $host;
      }
      location /superset/ {
        proxy_pass http://superset:8088/;
        proxy_set_header X-Forwarded-Prefix /superset;
        proxy_set_header Host $host;
      }
    }

4. 임베드/상호 링크(선택: 정책 준수 필요)

  • iframe 임베드
    • Grafana → [server] allow_embedding = true 설정 필요
    • Superset → Talisman/CSP에서 frame-ancestors에 Grafana 도메인 허용
  • 게스트 토큰(Embedded Superset): 앱에서 JWT 발급 → 제한된 뷰만 임베드
  • 보안 주의: 클릭재킹 방지, 공개/익명 접근 금지, IP 허용·TLS·SSO로 통제

보안 가이드 & 점검 포인트

  1. 접근통제
    • OIDC/SAML 등 SSO 필수, MFA 권장
    • 최소 권한 롤(Gamma 등)부터 할당, 팀/조직 단위 RBAC 운영
  2. 네트워크
    • 관리 포트(8088/3000)는 내부망 한정, 외부는 WAF/Reverse Proxy로 종단
    • DB 접근은 BI 서비스 IP만 허용, 보안 그룹/네트워크폴리시 적용
  3. 비밀관리
    • SECRET_KEY, DB 비밀번호, OIDC 시크릿은 Secret Manager/KMS로 관리
    • 이미지/코드에 하드코딩 금지
  4. 콘텐츠 보안
    • CSP(frame-ancestors, frame-src) 명시, 필요한 도메인만 허용
    • X-Frame-Options, Referrer-Policy, HSTS 적용
  5. 감사/로그
    • Superset FAB 로그, Grafana 액세스/감사 로그 → 중앙 수집(Elastic, Loki 등)
    • 관리자 작업(권한 변경, 데이터소스 추가) 주기적 리뷰
  6. 알림/자동화
    • Grafana Alerting로 인프라/서비스 지표, Superset Alerts & Reports로 데이터 품질/지연 탐지
  7. 업데이트/취약점
    • 컨테이너 CVE 스캔, 월간 업데이트 윈도우
    • 플러그인(드라이버/데이터소스) 신뢰 검증 & 버전 고정
  8. 쿼리 거버넌스
    • 대용량 테이블: 뷰/머티리얼라이즈드 뷰 제공
    • 리소스 쿼터/최대 실행시간/동시성 제한 적용

운영 체크리스트 (요약)

  1. SSO(OIDC) 연결 및 최소권한 롤 기본값 설정
  2. DB 읽기전용 계정·네트워크 ACL 적용
  3. Reverse Proxy(TLS/HSTS/CSP/XFO) 배치
  4. 로그/감사 중앙수집 및 경보
  5. Superset Celery/Redis 구성(리포트/스케줄)
  6. Grafana Alerting 구성(지표/로그/트레이스)
  7. 임베드 필요 시 CSP & allow_embedding 최소허용
  8. 월간 보안 업데이트 & 플러그인 검토

자주 쓰는 명령/옵션 (실무 메모)

  • Superset 관리자 변경
    docker compose exec superset superset fab list-users
    docker compose exec superset superset fab edit-user --username alice --role Admin
  • 드라이버 설치(컨테이너 내)
    pip install "psycopg2-binary==2.9.*" "mysqlclient==2.2.*" clickhouse-connect trino
  • 대시보드/차트 내보내기/가져오기
    superset export-dashboards -f /tmp/dash.zip
    superset import-dashboards -p /tmp/dash.zip
  • Grafana 프로비저닝(데이터소스)
    # /etc/grafana/provisioning/datasources/ds.yaml
    apiVersion: 1
    datasources:
      - name: PostgresDW
        type: postgres
        url: db.internal:5432
        database: dw
        user: ro_user
        secureJsonData:
          password: ${DS_PG_PASS}

단일 도메인에서 Grafana+Superset 함께 운영

  • 도메인: https://bi.example.com
  • 경로: /grafana, /superset
  • SSO: 공통 OIDC(그룹→롤 매핑)
  • 보안: CSP로 서로 임베드 허용 도메인만 지정, allow_embedding 최소화
  • 링킹: 운영 지표(Grafana 대시보드) → 상세 분석(Superset 대시보드)로 하이퍼링크 연결

권장 배치

  1. 데이터 소스 공유로 간단히 시작 →
  2. SSO/OIDC 통합으로 권한 일원화 →
  3. Reverse Proxy 경로 통합으로 UX 정리 →
  4. 임베드/게스트토큰은 필요 페이지만 제한적으로

현재 인프라(컨테이너/K8s), IdP 종류(Keycloak·Entra·Okta 등), 데이터 소스(DB/클라우드/OLAP) 조건에 맞춰 Values/INI/Config를 맞춤형으로 세팅해 보시기 바랍니다.

728x90
그리드형(광고전용)

댓글