OpenMetadata로 구현하는 엔터프라이즈 Data Governance

데이터 플랫폼이 성숙할수록 "이 테이블이 뭐지?", "이 데이터 믿어도 되나?" 같은 질문이 반복됩니다. PAASUP DIP의 카탈로그인 OpenMetadata에서 StarRocks, Kafka, Iceberg 등 실제 서비스를 연동하며 Discovery, Lineage, Quality, RBAC까지 엔터프라이즈 Data Governance의 주요 기능을 검증했습니다

OpenMetadata로 구현하는 엔터프라이즈 Data Governance

목차

  1. 왜 Data Governance인가
  2. OpenMetadata 아키텍처 개요
  3. Data Discovery: 모든 데이터 자산의 단일 진실
  4. Data Lineage: 데이터 흐름의 완전한 추적
  5. Data Quality & Observability: 데이터 신뢰성 확보
  6. Glossary & Classification: 조직 공통 언어 정립
  7. RBAC: 정밀한 접근 제어
  8. 서비스별 연동 심층 검증
  9. 운영 이슈 & 트러블슈팅 모음
  10. 종합 평가 및 권장 아키텍처

1. 왜 Data Governance인가

데이터 플랫폼이 성숙해질수록 아이러니하게도 "이 테이블이 뭘 담고 있지?", "이 컬럼이 어디서 왔지?", "이 데이터를 믿어도 되나?" 같은 질문이 반복됩니다. 데이터 자산이 수백·수천 개로 늘어나면 파이프라인 엔지니어, 분석가, 거버넌스 팀이 같은 데이터를 다른 이름으로 부르고, 품질 이슈가 발생해도 원인 추적에 며칠이 걸리는 상황이 생깁니다.

Data Governance는 이 문제를 구조적으로 해결합니다.

문제 Governance로 해결
"이 테이블 뭐야?" Data Discovery + Glossary
"이 데이터 믿어도 돼?" Data Quality + Observability
"데이터가 어디서 왔어?" Data Lineage
"누가 이걸 볼 수 있어?" RBAC + Classification
"지금 얼마나 잘 관리되고 있어?" Data Insights KPI

OpenMetadata는 이 모든 기능을 하나의 오픈소스 플랫폼으로 제공합니다. 우리는 PaaSup DIP(Data Intelligence Platform) 환경에 OpenMetadata 1.12.1을 직접 설치하고 실제 서비스들을 연동하며 각 거버넌스 기능을 면밀히 검증했습니다. 이 글은 그 과정에서 얻은 기술적 인사이트를 공유합니다.


2. OpenMetadata 아키텍처 개요

2.1 플랫폼 구성

┌─────────────────────────────────────────────────────┐
│                   OpenMetadata UI                    │
│         (Data Discovery · Lineage · Governance)      │
└───────────────────┬─────────────────────────────────┘
                    │ REST API
┌───────────────────▼─────────────────────────────────┐
│            OpenMetadata App Server                   │
│      (Java Spring Boot · Keycloak SSO 연동)           │
└────────┬──────────────────────────────┬─────────────┘
         │                              │
┌────────▼────────┐          ┌──────────▼──────────┐
│   OpenSearch    │          │       Airflow        │
│ (메타데이터 검색) │          │  (Ingestion 스케줄)   │
└─────────────────┘          └──────────┬──────────┘
                                        │ KubernetesExecutor
                              ┌─────────▼──────────┐
                              │  ephemeral worker   │
                              │  pod (실행 후 삭제)   │
                              └────────────────────┘

2.2 PAASUP DIP에서 openmetadata catalog 생성

  • openmetadata가 전사 데이터 거버넌스의 구현체이기 때문에 PAASUP DIP에서
    클러스터 카탈로그로 openmetadata를 생성하여야 합니다. (클러스터 관리자가 생성)

스크린샷 2026-06-04 175124.png

  • 클러스터 카탈로그 조회화면에서 생성된 openmetadata를 확인할 수 있습니다.
    스크린샷 2026-06-04 175206.png

  • 클러스터 관리자가 openmetadata를 생성하면 프로젝트 관리자는 프로젝트의 [카탈로그 생성]화면에서 openmetadata의 카탈로그를 생성하여 팀 단위의 데이터 거버넌스 권한 체계를 관리할 수 있게 됩니다.

스크린샷 2026-06-04 180743.png

2.3 Kubernetes Pod 구조 (namespace: openmetadata)

스크린샷 2026-06-04 170626.png

Pod 역할
openmetadata-* 앱 서버 (REST API, Keycloak OIDC 연동)
openmetadata-dependencies-api-server-* Airflow API Server — ingestion 트리거, CA cert 파일 참조 위치
openmetadata-dependencies-dag-processor-* DAG 파일 파싱 → MySQL 동기화 (30초 간격)
openmetadata-dependencies-scheduler-* 스케줄러 → KubernetesExecutor로 ephemeral worker pod 생성
openmetadata-dependencies-triggerer-0 Deferrable Operator 비동기 처리
opensearch-0 메타데이터 인덱싱 및 검색 엔진
mysql-0 Airflow 메타데이터 DB (DAG 이력, Task 상태)

Airflow Executor 실행 흐름:

[OpenMetadata UI]
      ↓ ingestion 트리거
[Airflow API Server] → [Scheduler] → [KubernetesExecutor]
                                             ↓
                                  ephemeral worker pod 생성
                                  (실행 완료 후 자동 삭제)

[dag-processor] ← DAG .py 파일 파싱 → [MySQL]
                                           ↑
                                    [Scheduler]가 읽어 실행

ephemeral worker pod 방식은 각 ingestion 작업이 독립된 환경에서 실행되고 완료 후 자동 삭제되어 자원 낭비가 없다는 장점이 있습니다.

2.4 등록된 서비스 현황

서비스 타입 Ingestion 방식
StarRocks Database UI (Airflow 스케줄)
PostgreSQL Database UI (Airflow 스케줄)
Lakekeeper (Iceberg) Database CLI (Python SDK) — UI 폼 한계로 우회
Kafka (Strimzi) Messaging UI (Airflow 스케줄)
MinIO CSV Database (Datalake) UI (Airflow 스케줄)
Superset Dashboard UI (Airflow 스케줄)

스크린샷 2026-06-04 170851.png


3. Data Discovery: 모든 데이터 자산의 단일 진실

Data Discovery는 OpenMetadata의 핵심입니다. 분산된 데이터 소스에 흩어진 테이블, 토픽, 대시보드, ML 모델을 하나의 검색 인터페이스에서 탐색할 수 있습니다.

3.1 검색 기능

  • 키워드 검색: 테이블명, 컬럼명, 설명, 태그 등 전문(full-text) 검색
  • 필터: 서비스·타입·오너·태그·도메인 등 다차원 필터링
  • 고급 검색: 복합 조건 쿼리 지원

스크린샷 2026-06-04 182057.png

3.2 자산 메타데이터 관리

각 데이터 자산의 상세 페이지에서 아래 정보를 중앙 관리합니다.

메타데이터 설명
스키마 컬럼명·타입·설명·태그·Glossary term 연결
Owner 담당자/팀 지정 (Data Insights KPI와 연동)
Domain 비즈니스 도메인 분류 (예: Finance, Marketing)
Tags Classification 기반 분류 태그
Tier 데이터 중요도 등급 (Tier1~5)
Sample Data 실제 데이터 미리보기 (최대 50행)
통계(Profile) 행 수, Null 비율, 고유값 수 등 통계 지표

스크린샷 2026-06-04 182445.png

3.3 Sample Data 수집 — 서비스별 방식 비교

Sample Data는 데이터 소비자가 테이블의 실제 내용을 파악하는 데 결정적으로 도움을 줍니다. 그러나 모든 서비스가 동일한 방식으로 동작하지는 않았습니다.

서비스 Agent 지원 수집 방법
StarRocks Profiler Agent (orm-profiler)
PostgreSQL Profiler Agent (orm-profiler)
Lakekeeper (Iceberg) PyIceberg 직접 읽기 → API 푸시
MinIO CSV boto3 직접 읽기 → API 푸시

스크린샷 2026-06-04 182542.png

Lakekeeper(Iceberg) 이슈: orm-profiler는 SQLAlchemy dialect를 내부적으로 사용합니다. 그런데 Iceberg의 RestCatalog에는 SQLAlchemy 인터페이스가 없어 AttributeError: 'RestCatalog' has no attribute 'dialect' 오류가 발생합니다. PyIceberg로 직접 데이터를 읽어 SDK의 ingest_table_sample_data() API로 푸시하는 방식으로 우회했습니다.

# Lakekeeper Sample Data 수집 핵심 흐름
lk_token = fetch_lakekeeper_token()   # Keycloak에서 scope=lakekeeper 토큰 발급
catalog = load_catalog("minio-iceberg", **config)
table = catalog.load_table(f"namespace.table_name")
df = table.scan(limit=50).to_pandas()
metadata.ingest_table_sample_data(table=om_table, sample_data=TableData(...))

MinIO CSV 이슈: Datalake Profiler Agent는 테이블 FQN에 .csv가 포함된 경우 처리 대상으로 인식하지 못하는 버그가 있었습니다 (에러 없이 Processed records: 0으로 종료). boto3로 CSV를 직접 읽고 다중 인코딩 재시도 패턴을 적용해 해결했습니다.

# 인코딩 자동 감지 패턴 (StreamingBody는 한 번만 읽을 수 있음)
raw = s3_client.get_object(Bucket=bucket, Key=key)["Body"].read()
for enc in ["utf-8", "utf-8-sig", "cp949", "euc-kr", "latin-1"]:
    try:
        df = pd.read_csv(io.BytesIO(raw), nrows=50, encoding=enc, on_bad_lines="skip")
        break
    except Exception:
        continue

4. Data Lineage: 데이터 흐름의 완전한 추적

Lineage는 "이 대시보드의 숫자가 어떤 테이블에서 왔는가?", "이 컬럼을 변경하면 어디에 영향이 가는가?"에 답합니다.

4.1 Lineage 계층

  • 테이블 레벨: 테이블 간 upstream/downstream 시각화
  • 컬럼 레벨: 특정 컬럼의 데이터 흐름 추적 (Column-level lineage)

4.2 지원 엔티티

Table · Topic(Kafka) · Dashboard · ML Model · Container · Pipeline

4.3 Lineage 등록 방법

자동 수집: Airflow/dbt 파이프라인 연동 시 실행 이력 기반 자동 생성
수동 등록: UI의 Lineage 탭 → Edit → 소스/목적지 엔티티 검색하여 엣지 연결
스크린샷 2026-06-04 182708.png

OpenLineage API: Flink/Spark 파이프라인에서 직접 push

# OpenLineage endpoint
POST http://openmetadata.openmetadata.svc.cluster.local:8585/api/v1/lineage/openlineage/api/v1/lineage
도구 라이브러리
Spark openlineage-spark
Flink openlineage-flink

주의: 수동 등록 시 양쪽 엔티티가 OpenMetadata에 먼저 등록되어 있어야 연결 가능합니다.

4.4 Superset Dashboard Lineage

Superset connector는 대시보드 ingestion 시 Chart → Data Model(쿼리) → 원본 Table까지 자동으로 lineage를 구성합니다. 이를 통해 "이 차트가 어느 테이블을 바라보고 있는지" UI에서 즉시 확인할 수 있습니다.

검증 결과: Dashboard 11개, Chart 58개, Data Model 34개 — 총 85개 엔티티 성공적으로 등록(100% 성공률).

스크린샷 2026-06-04 183151.png


5. Data Quality & Observability: 데이터 신뢰성 확보

5.1 Profiler — 통계 수집

Profiler는 테이블의 통계 정보를 주기적으로 수집합니다.

수집 항목 예시
행 수 1,234,567
Null 비율 2.3%
고유값 수 (Distinct) 456
최소값/최대값 0 / 9,999
평균/표준편차 512.3 / 201.7

5.2 Quality Tests — 규칙 기반 검증

개별 컬럼이나 테이블에 품질 규칙을 설정하고, 규칙 위반 시 알림을 받을 수 있습니다.

테이블: subway_passengers
컬럼: boarding_count
규칙: columnValuesToBeBetween(minValue=0, maxValue=100000)

5.3 Incident Manager

품질 테스트 실패 시 인시던트(Incident)가 자동 생성됩니다. 담당자 할당, 상태 추적(Open → Acknowledged → Resolved), 관련 자산 연결 등 ITSM 워크플로와 유사한 방식으로 품질 이슈를 관리합니다.

5.4 Data Contracts

스키마·품질·SLA 기준을 생산자/소비자 간 "계약"으로 명문화하는 기능입니다. 계약 위반 시 자동으로 감지하고 이해관계자에게 알림을 발송합니다.


6. Glossary & Classification: 조직 공통 언어 정립

6.1 Glossary (단어사전)

데이터 거버넌스에서 가장 기초적이지만 가장 중요한 작업 중 하나가 비즈니스 용어를 표준화하는 것입니다. OpenMetadata의 Glossary는 계층형 용어 체계를 구성하고 실제 데이터 자산(테이블·컬럼)에 연결합니다.

이번에 구성한 단어사전 (starrocks단어집) 구조:

최상위 카테고리 하위 용어 (일부)
subway_data (지하철 데이터) station_id · station_name · boarding_count · alighting_count · card_type
data_engineering (데이터 엔지니어링) ingestion · profiler · sample_data · pipeline · lineage
monitoring (모니터링) latency · error_rate · throughput · api_request

21개 term (최상위 3개 + 하위 18개)

CSV Import를 통한 대량 등록:

먼저 아래와 같이 CSV형태의 단어사전을 준비합니다.
스크린샷 2026-06-04 183714.png

Govern → Glossary → ⋮ → Import → CSV 업로드 경로로 가능합니다. 단, parent 필드에 반드시 FQN 형식을 사용해야 합니다.

단순 term 이름을 입력하면 하위 term 전체가 조용히 누락됩니다. 기존 형식이 불확실하다면 ⋮ → Export로 현재 CSV를 먼저 내려받아 형식을 확인하는 것을 권장합니다.

6.2 Classification & Tags

Classification은 조직의 데이터 분류 체계를 정의합니다. 예: PII, DataAccess, Confidential 등의 분류를 만들고, 각 분류 아래 구체적인 태그를 정의합니다.

태그는 단순한 레이블이 아니라 RBAC 정책의 조건으로 활용됩니다 (7장 참조).


7. RBAC: 정밀한 접근 제어

7.1 Policy/Role 계층 구조

Rule (Policy 내부에 종속, 단독 재사용 불가)
  ↓
Policy (여러 Role에 공유 가능)  ← 공유 단위
  ↓
Role → User / Team

7.2 기본 역할

역할 접근 범위 주요 용도
Admin 전체 플랫폼 전체 관리
DataConsumer 전체 (조회만) 데이터 탐색/활용
DataSteward 자기 팀 소유 자산만 팀 데이터 메타데이터 관리

DataSteward가 테이블을 보려면 해당 테이블의 Owner가 자신의 팀(Group 타입)으로 지정되어 있어야 합니다.

7.3 Policy 조건식

Policy 조건식은 아래 함수만 지원합니다. 서비스명을 직접 조건으로 지정할 수 없다는 점이 중요한 제약입니다.

조건 함수 설명
matchAnyTag('tagFQN') 리소스에 특정 태그가 있는 경우
isOwner() 현재 사용자가 리소스 소유자인 경우
noOwner() 리소스에 소유자가 없는 경우
inAnyTeam('teamName') 현재 사용자가 특정 팀에 속한 경우

7.4 실전: 특정 서비스 접근 차단 구현

목표: testor 유저의 starrocks-demo01 전체 접근 차단

서비스명 직접 지정이 불가하므로 "태그 기반 DENY 정책" 패턴으로 구현합니다.

Step 1 — Classification 및 태그 생성

Govern → Classifications → Add Classification
  Name: DataAccess
  ↓
DataAccess → + Add Tag
  Name: StarRocks-Restricted

Step 2 — StarRocks 테이블에 태그 적용

각 테이블 상세 페이지 → Tags 편집 → DataAccess.StarRocks-Restricted 추가
(테이블 수가 많으면 API bulk-tagging 스크립트 활용)

Step 3 — DENY Policy 생성

Settings → Access Control → Policies → Add Policy
  Name:       deny-starrocks-access
  Effect:     Deny
  Operations: ViewAll
  Resources:  All
  Condition:  matchAnyTag('DataAccess.StarRocks-Restricted')

Step 4 — Role 생성 및 사용자 할당

Role: starrocks-blocked (Policy: deny-starrocks-access)
  → testor 유저에게 Role 할당

동작 원리:

Organization Policy  →  ViewAll 허용 (모든 사용자)
testor의 추가 역할   →  Deny ViewAll (DataAccess.StarRocks-Restricted 태그 보유 자산)
                                ↑ DENY는 ALLOW보다 항상 우선 적용

운영 시 주의사항:

  • 태그는 해당 엔티티에만 적용되며 계층 자동 전파 없음
  • 서비스 전체 차단이 목적이면 모든 하위 테이블에 태그 개별 적용 필요
  • 추후 테이블 추가 시 신규 테이블에도 태그 적용 필요 (bulk-tagging 자동화 권장)

admin으로 로그인한 화면에서 quickstart db목록(예시)
KONG_ACCESS_LOG, subway_info, subway_info_copy, subway_passengers_copy, subway_passengers_time_copy 테이블들의 tag로 StarRocks-Restricted로 설정되어 있습니다.

스크린샷 2026-06-04 184147.png

testor로 로그인한 화면에서 quickstart db목록(예시)
testor유저는 StarRocks-Restricted로 tag된 테이블을 조회할 수 없습니다.

스크린샷 2026-06-04 184620.png


8. 서비스별 연동 심층 검증

8.1 Lakekeeper (Iceberg) 연동

[OpenMetadata] → [Keycloak] → [Lakekeeper (Iceberg REST Catalog)] → [MinIO]

이번 검증에서 가장 많은 이슈가 발생한 연동입니다.

이슈 1: UI 연결 폼에 필수 파라미터 입력란 없음

OpenMetadata 1.12.1의 Iceberg 연결 폼에 아래 두 파라미터 입력란이 없습니다.

필수 파라미터 역할
scope=lakekeeper Keycloak 토큰에 Lakekeeper 권한 부여
warehouse=minio-iceberg 접근할 warehouse 지정

Python SDK CLI로 ingestion을 직접 실행하여 우회

이슈 2: Fernet 암호화된 bot 토큰

Fernet Secrets Manager 활성화 시 API가 평문 JWT 대신 fernet:gAAAAAB... 형태로 반환합니다.

# Fernet 키 확인
kubectl exec -n openmetadata <pod> -- env | grep FERNET_KEY
from cryptography.fernet import Fernet
plain_jwt = Fernet(fernet_key).decrypt(encrypted).decode()

최종 ingestion YAML (핵심 부분):

source:
  type: iceberg
  serviceName: Lakekeeper-demo01
  serviceConnection:
    config:
      type: Iceberg
      catalog:
        name: minio-iceberg
        connection:
          uri: http://lakekeeper.lakekeeper.svc.cluster.local:8181/catalog
          token: "<scope=lakekeeper 토큰>"
          fileSystem:
            type:
              awsAccessKeyId: adminuser
              awsRegion: us-east-1
              endPointURL: http://minio.minio.svc.cluster.local:9000
        warehouseLocation: minio-iceberg

자동화 전략:

CLI ingestion은 Airflow DAG를 생성하지 않아 스키마 변경 시 수동 재실행이 필요합니다. 두 가지 자동화 방안이 있습니다.

방법 설명 난이도
cron run_lakekeeper_ingestion.py 정기 실행 쉬움
Airflow 이미지 커스텀 worker 이미지에 openmetadata-ingestion[iceberg] 설치 후 UI 에이전트 등록 어려움(정석)

8.2 Kafka (Strimzi) 연동

[OpenMetadata] → [Airflow API Server] → [Kafka Cluster (SASL_SSL · SCRAM-SHA-512)]

이슈 1: CA Certificate PEM 형식 파괴

UI의 "파일 내용 입력" 옵션 사용 시 줄바꿈(\n)이 공백( )으로 변환되어 저장됩니다 → librdkafka PEM 파싱 실패.

"파일 경로 지정" 옵션으로 해결

# Strimzi broker pod에서 CA cert 추출 → Airflow API server pod에 복사
kubectl exec -n kafka-cluster kafka-cluster-broker-0 \
  -- cat /opt/kafka/cluster-ca-certs/ca.crt > /tmp/kafka-cluster-ca.crt

이슈 2: security.protocol 미설정

Consumer Config에 명시하지 않으면 기본값 PLAINTEXT로 동작하여 SSL 포트(9094)에서 연결 실패. security.protocol=SASL_SSL 반드시 명시해야 합니다.

이슈 3: /tmp 디렉터리는 pod 재시작 시 소멸

K8s Secret으로 CA cert를 영구 마운트합니다.

kubectl create secret generic kafka-cluster-ca \
  --from-file=ca.crt=/tmp/kafka-cluster-ca.crt -n openmetadata

kubectl patch deployment openmetadata-dependencies-api-server \
  -n openmetadata --type=json \
  -p='[
    {"op":"add","path":"/spec/template/spec/volumes/-",
     "value":{"name":"kafka-ca","secret":{"secretName":"kafka-cluster-ca"}}},
    {"op":"add","path":"/spec/template/spec/containers/0/volumeMounts/-",
     "value":{"name":"kafka-ca","mountPath":"/etc/kafka-ssl","readOnly":true}}
  ]'
# UI CA cert 경로: /etc/kafka-ssl/ca.crt

8.3 MinIO CSV 연동

MinIO의 flat CSV 구조 (datasource/FILE.csv)는 Storage connector가 요구하는 폴더 구조와 맞지 않아 Datalake connector로 우회했습니다.

항목 Storage Service Datalake (채택)
등록 엔티티 타입 Container Table
flat CSV 지원 불가 가능
openmetadata.json 필요 필요 불필요
Lineage 연결 대상 Container Table

결과: CSV 45개 파일 자동 탐색 및 Table 엔티티 등록 성공.

8.4 Superset Dashboard 연동

Superset connector는 Superset의 내부 메타데이터 DB(dashboard, chart 정보)를 읽어 OpenMetadata에 등록합니다.

이슈: 잘못된 Connection 타입 설정

Superset의 백엔드 DB(dashboard·ab_user 테이블)가 PostgreSQL임에도 불구하고 MySQLConnection으로 설정하여 초기 실패. PostgresConnection으로 변경 후 해결.

이슈: MySQL OOMKill → 연쇄 재시작

ingestion 중 Filtered: 10 / Processed: 0 + namespace 전체 pod 연쇄 재시작이 발생했습니다. Filtered: N이 항상 필터 설정 문제를 의미하지는 않습니다. MySQL OOM으로 인한 쓰기 실패 시에도 동일하게 표시됩니다.

# OOMKill 확인
kubectl describe pod -n openmetadata mysql-0 | grep -A5 "Last State"
# → Reason: OOMKilled / Exit Code: 137

# 해결: memory limit 증가
kubectl patch statefulset mysql -n openmetadata \
  --type=json \
  -p='[
    {"op":"replace","path":"/spec/template/spec/containers/0/resources/limits/memory","value":"1536Mi"},
    {"op":"replace","path":"/spec/template/spec/containers/0/resources/requests/memory","value":"768Mi"}
  ]'

9. 운영 이슈 & 트러블슈팅 모음

9.1 dag-processor 연속 재시작 (RESTARTS: 113)

원인: MySQLdb(C extension)는 기본적으로 SO_KEEPALIVE를 활성화하지 않습니다. GKE 환경에서 10분 idle 후 네트워크 레이어가 TCP 연결을 종료하는데, 만료된 연결이 pool에 잔류하다가 COMMIT 시점에 사용되면서 Error 2013 (Lost connection)이 반복 발생합니다.

pool_pre_ping, pool_recycle 등 SQLAlchemy 옵션은 모두 효과 없었습니다.

해결: PyMySQL(순수 Python) 드라이버로 교체

kubectl set env deployment/openmetadata-dependencies-dag-processor \
  AIRFLOW__DATABASE__SQL_ALCHEMY_CONN="mysql+pymysql://airflow_user:<password>@mysql:3306/airflow_db" \
  AIRFLOW__CORE__SQL_ALCHEMY_CONN="mysql+pymysql://airflow_user:<password>@mysql:3306/airflow_db" \
  -n openmetadata

9.2 UI vs CLI Ingestion — 선택 기준

항목 UI Ingestion CLI Ingestion
대상 운영자·데이터 관리자 개발자·DevOps
실행 방식 Airflow Agent 스케줄 직접 실행 or CI/CD
에이전트 등록 자동 (Airflow DAG 생성) 없음 (수동 재실행)
모니터링 UI에서 실행 이력 확인 스크립트·파이프라인으로 제어

CLI가 필요한 경우:

  • UI 폼에 파라미터 입력란이 없을 때 (이번 사례: Lakekeeper scope, warehouse)
  • 재설치 후 bot JWT 갱신이 UI 토큰 발급 페이지에서 오류 날 때

9.3 운영 체크리스트

항목 확인 방법
dag-processor DB driver AIRFLOW__DATABASE__SQL_ALCHEMY_CONNpymysql 포함 여부
Kafka CA cert 영구화 /etc/kafka-ssl/ca.crt 경로 확인 (Secret 마운트)
bot JWT 유효성 DAG JSON jwtToken 필드 vs 현재 토큰 일치 여부
Lakekeeper ingestion 자동화 cron 또는 Airflow 이미지 커스텀 여부
Glossary CSV parent 필드 {글로사리명}.{term명} FQN 형식 사용 여부
RBAC 신규 테이블 태그 자동 전파 없음 → 추가 테이블에 수동 태깅 또는 bulk script

10. 종합 평가 및 권장 아키텍처

10.1 OpenMetadata 거버넌스 기능 성숙도 평가

기능 평가 비고
Data Discovery ⭐⭐⭐⭐⭐ 다양한 소스 통합, 검색 품질 우수
Data Lineage ⭐⭐⭐⭐ 자동·수동·OpenLineage API 모두 지원
Data Quality ⭐⭐⭐⭐ Profiler + Tests + Incident Manager 삼위일체
Glossary ⭐⭐⭐⭐ CSV import 편리, FQN 규칙 주의 필요
Classification/Tags ⭐⭐⭐⭐⭐ RBAC 연계까지 완성도 높음
RBAC ⭐⭐⭐ 태그 기반 우회 필요, 서비스 직접 지정 미지원
Iceberg 연동 ⭐⭐ UI 폼 한계, Profiler 비호환 — CLI 우회 필수
Kafka 연동 ⭐⭐⭐ CA cert 처리 주의, 설정 완료 후 안정적
Superset 연동 ⭐⭐⭐⭐ Dashboard Lineage 자동 구성 강점

10.2 권장 운영 패턴

┌──────────────────────────────────────────────────────────┐
│  데이터 거버넌스 성숙도 로드맵                              │
│                                                          │
│  1단계 (기반)  →  2단계 (품질)  →  3단계 (자동화)          │
│                                                          │
│  • 서비스 등록       • Profiler 설정      • Lineage 자동화  │
│  • Owner 지정       • Quality Tests      • RBAC 정책화    │
│  • Glossary 구축    • Incident 운영       • KPI 모니터링   │
│  • Tag 체계 설계    • Sample Data 확보    • 알림 자동화     │
└──────────────────────────────────────────────────────────┘

10.3 결론

OpenMetadata는 오픈소스 Data Governance 플랫폼으로서 엔터프라이즈 수준의 기능을 폭넓게 제공합니다. 특히 다양한 데이터 소스를 하나의 인터페이스로 통합하는 Discovery, 컬럼 레벨까지 추적 가능한 Lineage, 비즈니스 용어를 표준화하는 Glossary는 완성도가 높습니다.

다만 Iceberg(RestCatalog) 연동의 UI 한계, RBAC의 서비스 직접 지정 미지원, GKE 환경에서의 MySQL TCP 연결 문제 등 실제 운영 환경에서만 마주칠 수 있는 이슈들이 존재합니다. 이 글이 유사한 환경에서 OpenMetadata를 도입하려는 팀에게 시행착오를 줄이는 레퍼런스가 되길 바랍니다.


참고 링크

서비스 링크
OpenMetadata 공식 문서 https://docs.open-metadata.org
OpenMetadata GitHub https://github.com/open-metadata/OpenMetadata
Apache Airflow https://airflow.apache.org/docs
OpenLineage https://openlineage.io
Keycloak https://www.keycloak.org/documentation

이 글은 PAASUP DIP 환경에서 OpenMetadata 1.12.1을 직접 운영하며 검증한 내용을 바탕으로 작성되었습니다.

Subscribe to PAASUP IDEAS

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe