텔레메트리 데이터 플레인
Ongrid edge 는 매니저와 두 개의 물리 경로 로 대화합니다:
- 컨트롤 플레인 — geminio 터널 (ADR-001 / ADR-007). edge 라이프사이클, RPC, 하트비트, 알림 이벤트, 메트릭 push (
push_prom_samples) 에 사용됩니다. - 텔레메트리 데이터 플레인 — edge 에서 매니저의 공개 ingest 엔드포인트로의 직접 아웃바운드 HTTPS POST. 로그 (Loki API) 와 트레이스 (OTLP) 에 사용됩니다.
이 페이지는 분리, 인증 모델, 그리고 메트릭의 마이그레이션 트리거를 설명합니다.
이 페이지는 간결한 레퍼런스입니다. 전체 결정 기록은 소스 트리의 ADR-014 입니다.
분리
| 플레인 | 채널 | 담는 것 |
|---|---|---|
| 컨트롤 플레인 | geminio 터널 (기존 ADR-001) | edge 라이프사이클, RPC, 하트비트, 알림 이벤트, 메트릭 push (현재) |
| 텔레메트리 데이터 플레인 | edge → 매니저 공개 HTTPS, 독립 아웃바운드 연결 | 로그 (ADR-012), 트레이스 (ADR-013) |
두 플레인 모두 edge 에서 아웃바운드 — 에이전트가 매니저로 dial 합니다. edge 에 인바운드 포트는 없습니다.
왜 분리하는가?
geminio 터널은 컨트롤 RPC 버스로 설계되었습니다. 하나의 영속 연결 안에서 저지연 RPC 호출을 다중화합니다. 메트릭 push 는 ADR-009 에서 "공짜로 함께 타기" 로 추가된 것입니다 — 메트릭 양이 edge 당 수 KB/s 정도로 작고, 터널에 여유 용량이 있기 때문입니다.
로그와 트레이스는 작지 않습니다.
| 신호 | edge 당 정상 상태 | edge 당 피크 |
|---|---|---|
| 메트릭 | 수 KB/s | ~10 KB/s |
| 로그 | 수십 KB/s | 1–10 MB/s |
| 트레이스 | 샘플레이트에 따라 | 로그와 견줄 만함 |
edge 100개 × 1 MB/s = 매니저에서 지속 100 MB/s ingress. 터널은 그 양을 위해 설계되지 않았습니다. 로그와 트레이스를 거기로 강제하면 두 문제가 생깁니다:
- 매니저 CPU 가 녹는다. 터널 프레임 인코딩/디코딩 + 하류 저장소로의 포워딩이 Go 프로세스 안에서 일어납니다. nginx + 하류 저장소 직접 연결은 수 배 더 저렴합니다.
- HOL blocking. 고처리량 바이트 스트림이 mux 위에서 컨트롤 RPC 와 경쟁합니다. "edge 42 무슨 문제야?" 라고 물을 때 운영자가 초 단위 지터를 체감하게 됩니다.
터널은 컨트롤 플레인. 데이터 플레인은 데이터 플레인. 둘을 섞은 것은 NAT 제약 아래의 편법이었습니다 — 분리는 경계를 명시적으로 만듭니다.
아키텍처
┌──────────────────────────────┐
┌──────────────┐ │ manager │
│ ongrid-edge │ │ │
│ │ │ nginx :443 ──► /api/* ───► ongrid (manager)
│ ┌─────────┐ │ geminio tunnel │ │
│ │ agent │ ├────► :40012 ──────►│ frontier (geminio broker) ──┤
│ └─────────┘ │ (control plane) │ │
│ │ │ nginx :443 ──► /loki/* ───► loki ← data plane
│ ┌─────────┐ │ │ ──► /v1/traces ─► tempo ← data plane
│ │promtail │ ├────► :443 ────────►│ ──► /api/v1/write─► prom (today)
│ └─────────┘ │ (data plane) │ │
│ │ │ edgeauth verifies the token │
│ ┌─────────┐ │ │ via /internal/auth/ │
│ │otelcol │ ├────► :443 ────────►│ dataplane-verify before │
│ └─────────┘ │ (data plane) │ proxying. │
└──────────────┘ └──────────────────────────────┘에이전트는 플러그인당 (promtail, otelcol-contrib) 하나의 TLS 연결을 씁니다. 모두 edge 에서 ONGRID_PUBLIC_URL 로 아웃바운드입니다.
인증
하나의 신뢰 루트, 두 개의 경로.
edge 의 access-key/secret-key 쌍이 geminio 의 세션 자격 증명을 통해 터널을 인증합니다. 같은 자격 증명 쌍이 모든 데이터 플레인 HTTPS POST 에 사용되는 Bearer 토큰으로 교환됩니다. nginx 의 auth_request 디렉티브가 매니저의 /internal/auth/dataplane-verify 로 콜백하여 토큰을 검증합니다 — 200 이면 요청이 Loki 또는 Tempo 로 프록시됩니다. 401/403 이면 edge 가 HTTP 에러를 보고 백오프합니다.
이것이 의미하는 바:
- edge 의
secret_key를 교체하면 두 플레인이 동시에 무효화 됩니다. - 두 번째 secret 저장소도, 플러그인별 자격 증명도, 별도의 ACL 도 없습니다.
- 매니저가 인증을 소유합니다 — Loki 와 Tempo 는 edge 의 ID 를 직접 보지 않습니다.
Bearer 토큰은 단명입니다. 에이전트는 터널을 통해 투명하게 갱신합니다. 터널이 장시간 다운된 edge 는 토큰 만료 시점에 데이터 플레인 POST 가 401 을 받기 시작하고, 이것이 터널 재연결을 강제합니다.
NAT 호환성
매니저의 공개 포트로 가는 아웃바운드 HTTPS 는 아웃바운드 터널과 같은 네트워크 클래스입니다 — 둘 다 edge 에서 단일 목적지 포트 범위 (데이터는 443, 터널은 40012) 로 originate 됩니다. 둘 다 일반적인 기업 egress 방화벽을 통과합니다. 특별한 carve-out 도, 인바운드 규칙도 필요 없습니다.
아웃바운드 연결을 하나만 열 수 있는 NAT 전용 edge 를 위해, geminio 에는 raw-stream 폴백 (zstd 압축 로그 페이로드, bounded 버퍼, 오버플로 시 오래된 것 drop) 이 있습니다. 기본이 아니라 escape hatch 입니다 — 아직 어떤 고객에게도 이것을 배포한 적은 없습니다.
메트릭은 어떻게 되나요?
push_prom_samples 는 오늘까지 여전히 터널 위 에 있습니다.
| 터널에 둔 이유 |
|---|
| edge 당 메트릭 양은 포화에서 한참 아래입니다. |
| 기존 경로가 동작합니다. 마이그레이션 비용이 현재 이익보다 큽니다. |
push_prom_samples 는 매 릴리스에서 활용됩니다 — 손대는 게 위험합니다. |
다음 중 어느 하나 라도 성립하면 메트릭을 데이터 플레인 (Prometheus remote_write 로 https://<manager>/api/v1/write 직행) 으로 옮길 것입니다:
- 단일 매니저의 터널 CPU 지속 > 60%.
- 단일 edge 의 메트릭 push 율 지속 > 100 KB/s (거의 항상 cardinality 폭주를 의미합니다 — 먼저 그것부터 고치세요; 그 후에도 지속되면 마이그레이션).
- 메트릭 스트림 압력 아래에서 컨트롤 RPC P95 지연이 > 500ms 로 악화.
Prometheus remote_write 클라이언트는 이미 node_exporter 안에 있고, edge 의 메트릭 플러그인은 env 로 재타겟될 수 있습니다. 위 트리거는 단지 우선순위를 정해 줄 뿐입니다.
edge 구현
디스크에서 에이전트는 모든 텔레메트리 sender 를 internal/edgeagent/dataplane/ 를 통해 배포합니다. 이 패키지가 다음을 중앙화합니다:
- 터널 세션 자격 증명에서의 토큰 재사용.
- 이중 목적지 라우팅 (컨트롤은 터널, 데이터는 HTTPS).
- jitter 가 있는 재시도 + 지수 백오프 (최대 1 분).
- 로컬 bounded 큐 (in-memory; 에이전트는 디스크로 spool 하지 않음).
모든 플러그인 (promtail, otelcol-contrib, 향후의 것들) 이 이 패키지를 소비합니다 — 플러그인별 재시도 / auth 로직이 없습니다. 그 덕분에 ongrid-edge 는 단일 바이너리 + 네 개의 subprocess 로 남고, 플러그인별 sidecar 도, 플러그인별 systemd 유닛도 없습니다.
무엇을 튜닝하나요
| 변수 | 위치 | 효과 |
|---|---|---|
ONGRID_PUBLIC_URL | 매니저 | edge 에 데이터 플레인 루트로 전달되는 URL. 데이터 플레인 동작을 위해 필수. |
ONGRID_LOG_QUERY_URL | 매니저 | 읽기 경로 — Logs 페이지를 위한 매니저 → Loki. edge push 와 독립. |
ONGRID_TRACE_QUERY_URL | 매니저 | 읽기 경로 — Traces 페이지를 위한 매니저 → Tempo. |
ONGRID_EDGE_PLUGIN_BIN_DIR | edge | 플러그인 바이너리가 있는 디렉터리 (promtail, otelcol-contrib). |
ONGRID_EDGE_PLUGIN_WORK_DIR | edge | 플러그인별 런타임 디렉터리 (config, PID, 큐 spool). |
ONGRID_PUBLIC_URL 은 매니저 측에서 단일로 가장 중요한 프로덕션 설정입니다. 비어 있으면 데이터 플레인이 완전 비활성화 됩니다 — edge 는 터널로 연결되고 에이전트는 부팅되지만, 로그와 트레이스는 결코 출발하지 않습니다.
함께 보기
- Architecture — 전체 시스템 다이어그램.
- Capabilities → Logs — 로그 플레인의 운영자 투어.
- Capabilities → Traces — 트레이스 플레인의 운영자 투어.
- 환경 변수 — 이 모두를 와이어링하는 노브들.