Pull과 Push 메트릭 수집 모델을 개발·운영 편의성, 확장성, 장애 처리, Kubernetes 배포, Prometheus와 OpenTelemetry의 통합 관점에서 비교합니다.
메트릭을 수집하는 방식에는 크게 두 가지 방향이 있습니다.
Pull: 수집기가 대상에 연결하여 메트릭을 가져온다.
Push: 대상 또는 에이전트가 수집기로 메트릭을 보낸다.
/metrics를 Prometheus가 스크레이프하는 방식은 대표적인 Pull 모델입니다. 애플리케이션이나 익스포터가 엔드포인트를 노출하고, Prometheus가 주기적으로 연결합니다. OpenTelemetry SDK가 OTLP를 통해 Collector로 메트릭을 내보내는 방식은 대표적인 Push 모델입니다. Pull은 대상이 데이터를 수동적으로 노출한다는 뜻일 뿐이며, 수집 자체는 여전히 Prometheus가 시작하는 능동적인 작업입니다.
처음에는 Push가 더 현대적으로 들릴 수 있습니다. 새 서비스는 자동으로 데이터를 보낼 수 있고, 중앙 Collector 풀은 수평 확장되는 것처럼 보입니다. 하지만 Kubernetes에서는 하나의 ServiceMonitor로 Pod를 발견하는 Prometheus 구성이 훨씬 단순할 수 있습니다.
어느 모델이 더 새로운지만으로 선택하면 가장 중요한 운영상 차이를 놓치게 됩니다.
이 글에서는 두 모델을 다음 관점에서 비교합니다.
요약하면 Pull과 Push의 가장 큰 차이는 화살표 방향이 아닙니다.
누가 수집 실패를 감지하는가?
누가 재시도하고 버퍼링하는가?
누가 소스가 사라졌다고 판단하는가?
그 답이 운영 책임이 어디에 놓이는지를 결정합니다.

메트릭을 가져오고 푸시하는 방식은 서로 다른 운영 책임을 하나의 시스템에 엮어 넣습니다.
Prometheus를 OTLP와 직접 비교하면 서로 다른 계층의 개념이 섞입니다. 메트릭 시스템은 최소 세 계층으로 분리하면 이해하기 쉽습니다.
계측: 애플리케이션이 무엇을 측정하는가
수집: 누가 연결을 열고 데이터를 이동시키는가
저장: 어느 백엔드가 시계열을 저장하고 조회하는가
Prometheus 클라이언트 라이브러리를 사용한다고 해서 모든 것을 로컬 Prometheus 서버에만 저장해야 하는 것은 아닙니다. Prometheus는 대상을 스크레이프한 뒤 Remote Write로 샘플을 장기 저장소에 보낼 수 있습니다.
OpenTelemetry SDK도 벤더 백엔드로 직접 보낼 필요는 없습니다. SDK는 OTLP를 Collector로 내보낼 수 있고, Collector는 메트릭을 변환하여 Prometheus Remote Write나 다른 백엔드 프로토콜로 보낼 수 있습니다.
Prometheus는 이제 OTLP/HTTP 메트릭 수신기를 제공합니다. 반대 방향으로 OpenTelemetry Collector에는 기존 /metrics 엔드포인트를 스크레이프하는 Prometheus 수신기가 있습니다. 저장 제품과 수집 방향은 별개의 선택입니다.
따라서 더 정확한 질문은 다음과 같습니다.
이 수집 경계에서 Pull과 Push 중 어느 쪽이 더 적합한가?
| 차원 | Pull: Prometheus 스크레이프 | Push: OTLP 내보내기 |
|---|---|---|
| 연결 시작 주체 | 수집기가 대상에 연결 | SDK 또는 Agent가 수신기에 연결 |
| 초기 설정 | /metrics 엔드포인트와 스크레이프 구성 | SDK 또는 Agent와 OTLP 엔드포인트 구성 |
| 중앙 제어 | 수집기가 간격, 타임아웃, 대상, 샘플 제한을 관리 | Collector가 배치, 필터링, 라우팅, 재시도 정책을 관리 |
| 발견과 식별 | 발견된 대상과 레이블 사용 | 안정적인 수신기와 리소스 속성 사용 |
| 장애 감지 | 스크레이프 상태와 up 시계열 생성 | 별도의 익스포터 상태 및 데이터 누락 모니터링 필요 |
| 백엔드 장애 | 일반적으로 대상에 영향을 주지 않음 | 큐, 재시도, 드롭, 백프레셔 정책 필요 |
| 짧은 수명의 작업 | 스크레이프 전에 끝날 수 있음 | 종료 전에 플러시할 수 있으나 전송은 여전히 설계 필요 |
| 네트워크 | 수집기가 모든 대상에 도달해야 함 | 일반적으로 워크로드에서 나가는 연결만 필요 |
| 여러 신호 | 메트릭에 집중 | 하나의 경로로 메트릭, 트레이스, 로그를 전달 가능 |
| 수평 확장 | 대상 샤딩과 수집기 복제본 | 작성자 식별 제약을 고려한 수신기와 게이트웨이 확장 |
| 원본 검사 | 엔드포인트를 직접 열어 보기 쉬움 | 파이프라인 단계 전반의 검사 필요 |
어느 쪽도 항상 우세하지는 않습니다. 애플리케이션 개발자에게 쉬운 일이 플랫폼 팀이 운영하기에도 쉬운 일과는 다를 수 있습니다.
Pull은 요청과 메트릭 응답을 반대 방향으로 보내는 반면, Push는 생산자에서 수신기로 메트릭 배치를 보냅니다. 이 차이는 발견, 전송, 장애 처리가 놓이는 위치를 바꿉니다.
Pull 구성에서 애플리케이션의 책임은 비교적 작습니다.
요청을 받으면 현재 메트릭 값을 노출한다.
Prometheus는 수집 시점, 재시도 빈도, 스크레이프 실패 시점을 결정합니다. 애플리케이션은 최종 저장 백엔드의 주소나 자격 증명을 알 필요가 없습니다. 다만 스크레이프에는 신속히 응답해야 합니다. 메트릭을 렌더링하는 동안 수행하는 비싼 계산이나 외부 호출은 스크레이프 엔드포인트를 부하 원인으로 만들 수 있습니다.
대표적인 아키텍처는 다음과 같습니다.
애플리케이션 / 익스포터
↑ 스크레이프
Prometheus
↓ 선택적 원격 쓰기
장기 저장소
매 스크레이프마다 Prometheus는 job 및 instance 레이블을 붙이고 up, scrape_duration_seconds, scrape_samples_scraped 같은 시계열을 만듭니다. up 값이 0이라고 해서 전체 비즈니스 기능이 중단되었다는 뜻은 아닙니다. Prometheus가 해당 엔드포인트를 성공적으로 스크레이프하지 못했다는 의미입니다. 이처럼 더 좁은 의미라도 별도 계측을 추가하지 않고 수집 경로의 도달 가능성을 확인할 수 있습니다.
원본도 쉽게 검사할 수 있습니다.
curl -s http://application:8080/metrics
대시보드가 비어 있을 때 운영자는 엔드포인트, 서비스 디스커버리, 리레이블링, 저장 단계로 문제 범위를 좁힐 수 있습니다.
수집 간격을 15초에서 30초로 바꾸거나 레이블을 제거해야 한다면 애플리케이션을 재배포하지 않고 Prometheus 구성을 변경할 수 있습니다. 수집기는 예상 밖의 샘플 수나 응답 크기도 제한할 수 있습니다.
서비스 수가 늘어날수록 이는 편리해집니다. 모든 애플리케이션이 서로 다른 백엔드 자격 증명, 큐 정책, 재시도 구성을 각각 가질 필요가 없습니다.
다만 Prometheus는 여전히 대상에 도달할 수 있어야 합니다. 중앙 스크레이핑은 격리된 네트워크, NAT 뒤의 대상, 고객 환경에 설치된 에이전트, 매우 짧은 수명의 작업에서는 불편할 수 있습니다.
Prometheus 중단도 대상이 나중에 수집할 과거 샘플을 보관하게 만들지는 않습니다. 누락된 스크레이프 시점의 게이지 값과 짧은 상태 전환은 보통 복구할 수 없습니다. 프로세스가 계속 살아 있고 누적 카운터가 재설정되지 않았다면, 다음 스크레이프에서 총 증가량이 여전히 나타나 비율 계산에 부분적으로 보일 수 있습니다. 수집기 장애가 애플리케이션 자체에는 영향을 주지 않지만, 샘플 해상도와 일시적 상태는 사라집니다.
Push 구성에서는 애플리케이션 SDK 또는 인접한 Agent가 주기적으로 메트릭 배치를 만들고 OTLP 수신기로 보냅니다.
가장 단순한 토폴로지는 다음과 같습니다.
애플리케이션 SDK
↓ OTLP
관측성 백엔드
이는 개발에는 유용하지만, 서비스를 최종 백엔드 엔드포인트 및 인증 메커니즘과 결합시킵니다. 프로덕션 환경에서는 보통 경로에 Collector를 둡니다.
애플리케이션 SDK
↓ OTLP
로컬 Agent / 사이드카 Collector
↓ OTLP
게이트웨이 Collector
↓
하나 이상의 백엔드
애플리케이션은 텔레메트리를 인접한 Collector에 빠르게 넘깁니다. 이후 Collector가 배치, 재시도, 필터링, 리소스 보강, 백엔드 라우팅을 처리합니다.
애플리케이션은 환경 변수로 OTLP/HTTP 엔드포인트를 구성할 수 있습니다.
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-agent:4318
export OTEL_SERVICE_NAME=checkout-api
export OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production
Collector는 OTLP를 수신하여 다른 Collector나 백엔드로 전달할 수 있습니다.
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
memory_limiter:
check_interval: 1s
limit_percentage: 75
spike_limit_percentage: 15
batch: {}
exporters:
otlphttp/backend:
endpoint: https://telemetry.example.com
service:
pipelines:
metrics:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlphttp/backend]
프로덕션 구성에서는 TLS, 인증 헤더, 큐 용량, 재시도 동작도 정의해야 합니다. 이 예시는 파이프라인 형태만 보여 주며 인터넷에 직접 노출하기 위한 안전한 구성은 아닙니다.
Push 수집기는 모든 Pod 주소를 발견할 필요가 없습니다. 새 Pod도 동일한 Collector 서비스로 보낼 수 있습니다. 외부 백엔드가 바뀌면 모든 애플리케이션을 수정하지 않고 Collector 구성을 변경할 수 있습니다.
트레이스와 로그도 OpenTelemetry를 사용한다면 하나의 SDK 전략과 Collector 파이프라인을 공유할 수 있습니다. 이는 애플리케이션 계측을 표준화하는 데 중요한 장점입니다.
발견이 사라지는 것은 아닙니다. 그 일부가 송신자가 전달하는 식별 정보가 됩니다. service.name, service.instance.id, 또는 Kubernetes 리소스 속성이 잘못되면 별도 Pod의 시계열이 합쳐지거나 재시작한 인스턴스가 같은 작성자로 보일 수 있습니다. 안정적인 수신기 주소만으로는 충분하지 않습니다.
그 대가로 전송 장애 시의 책임이 생깁니다.
재시도는 얼마나 오래 계속해야 하는가?
메모리 큐가 가득 차면 무엇을 버리는가?
영속 큐가 필요한가?
종료 시 최종 플러시를 얼마나 기다려야 하는가?
Collector 장애가 애플리케이션 리소스 사용량을 늘릴 수 있는가?
무한히 안전한 큐는 없습니다. 백엔드를 충분히 오래 사용할 수 없다면 시스템은 결국 데이터를 버리거나, 디스크를 계속 소비하거나, 송신자를 느리게 해야 합니다. OTLP 익스포터는 일시적 장애를 재시도할 수 있지만 실제 버퍼링 기간은 SDK와 Collector 구성에 따라 다릅니다. Push는 일부 장애 기간을 흡수할 수 있지만 무손실 전송을 자동으로 보장하지는 않습니다.
Pull은 하나의 수집기가 많은 대상에 연결을 여는 팬아웃 토폴로지입니다.
하나의 Prometheus
→ 수백 또는 수천 개의 대상
→ 대상별 주기적 스크레이프
대상이 늘어나면 서비스 디스커버리, 동시 연결, 스크레이프 응답 크기, 활성 시계열이 함께 증가합니다. 하나의 Prometheus 인스턴스가 용량에 도달하면 대상을 샤드로 나눌 수 있습니다. 동일한 대상을 독립적으로 스크레이프하는 Prometheus 인스턴스 두 개를 실행하는 것도 흔한 고가용성 패턴입니다. 이후 전역 쿼리 계층에는 두 복제본을 구분하는 레이블이나 중복 제거 규칙이 필요합니다.
각 대상은 독립적으로 유지됩니다. 느린 익스포터는 일반적으로 스크레이프 타임아웃 범위 안에서 해당 대상으로 격리할 수 있습니다. 하지만 대상 집합이 샤드로 나뉘고 나면 전역 쿼리와 규칙 평가에는 Thanos 같은 쿼리 계층이나 중앙 Remote Write 백엔드가 필요할 수 있습니다.
Push는 많은 송신자가 더 적은 수신기로 모이는 팬인 토폴로지입니다.
수백 또는 수천 개의 송신자
→ Collector 게이트웨이 풀
→ 백엔드
로드 밸런서 뒤에서 수신기를 확장하는 일은 단순해 보이지만, 메트릭에는 중요한 제약이 있습니다. 여러 작성자가 동일한 메트릭 스트림을 동시에 보내면 운영자는 중복, 재설정 해석 오류, 순서가 맞지 않는 샘플을 볼 수 있습니다. service.instance.id 같은 리소스 식별 정보와 단일 작성자 경계는 안정적으로 유지되어야 합니다.
Collector가 상태 저장 프로세서를 사용한다면, 플랫폼은 어느 게이트웨이든 어느 배치나 처리할 수 있는지도 결정해야 합니다. 수평 확장은 단순히 Pod를 추가하는 일이 아닙니다. 메트릭 식별 정보와 처리 상태가 어디에 존재하는지도 결정해야 합니다.
Push가 항상 Pull보다 Kubernetes에 더 적합하다고 말하는 것은 정확하지 않습니다. 각 모델은 서로 다른 Kubernetes 특성과 잘 맞습니다.
Prometheus Operator에서는 ServiceMonitor 또는 PodMonitor로 대상을 선언할 수 있습니다. 아래 예시에서 선택자는 Pod를 직접 선택하는 것이 아니라 app: checkout-api 레이블이 붙은 Service를 선택하며, 그 Service 뒤의 엔드포인트가 스크레이프 대상이 됩니다.
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: checkout-api
labels:
team: commerce
spec:
selector:
matchLabels:
app: checkout-api
endpoints:
- port: metrics
interval: 15s
path: /metrics
Pod가 나타나고 사라지면 Kubernetes 레이블과 서비스 디스커버리가 대상 집합을 갱신합니다. 애플리케이션 Pod에는 백엔드 주소나 자격 증명이 필요하지 않습니다.
이는 특히 다음에 자연스럽습니다.
OTLP를 내보내는 애플리케이션의 경로는 DaemonSet Agent 및 Deployment Gateway 패턴과 잘 맞습니다.
각 노드: DaemonSet Collector
각 클러스터: Gateway Collector Deployment
각 리전: 중앙 수집 또는 장기 백엔드
DaemonSet Collector는 같은 노드의 애플리케이션에서 텔레메트리를 수신하고 호스트, kubelet, 컨테이너, Kubernetes 리소스 컨텍스트로 보강할 수 있습니다. kubeletstats나 Prometheus 수신기 같은 구성 요소를 통해 데이터를 Pull할 수도 있습니다. Collector를 도입한다고 모든 수집 경로가 Push가 되는 것은 아닙니다. Gateway는 인증, 필터링, 라우팅 같은 공유 정책을 담당할 수 있습니다.
이 모델은 다음과 같은 경우에 유용합니다.
Collector 자체가 운영 대상이 됩니다. 팀은 CPU와 메모리, 큐 사용량, 거부되거나 드롭된 텔레메트리, 내보내기 실패, 백엔드 지연 시간을 모니터링해야 합니다.
짧은 배치 작업과 서버리스 워크로드는 Pull의 명확한 한계를 드러냅니다. 3초 동안 실행되는 작업은 15초 간격을 사용하는 수집기가 한 번도 보기 전에 끝날 수 있습니다.
Push가 더 자연스러운 이유는 프로세스가 종료 전에 최종 배치를 플러시할 수 있기 때문입니다. 그렇다고 전송이 보장되는 것은 아닙니다. 강제 종료나 네트워크 장애는 최종 데이터를 잃게 할 수 있고, 종료 훅만으로는 영속적인 전송 의미론을 제공하지 않습니다. 비즈니스에 중요한 작업 결과에는 메트릭 경로 밖의 영속적인 작업 상태나 이벤트 기록도 필요합니다.
Prometheus Pushgateway가 이 맥락에서 자주 언급되지만, 서비스용 범용 Push 수집기로 취급해서는 안 됩니다. 이는 직접 스크레이프할 수 없는 서비스 수준 배치 작업의 결과를 보존하기 위한 제한적인 도구입니다. 명시적인 수명 주기 정리가 없으면 완료된 인스턴스의 시계열이 무기한 남을 수 있고, 원래 대상을 직접 스크레이프할 때 얻을 수 있는 up 신호도 사라집니다.
OpenTelemetry와 OTLP는 애플리케이션 계측의 더 많은 부분을 포괄하고 있습니다. 특정 백엔드와 독립적인 애플리케이션 API를 유지하면서 메트릭, 트레이스, 로그에 공통 리소스 식별 정보와 전송 경로를 적용합니다.
그렇다고 Prometheus 스크레이프가 시대에 뒤떨어진 것은 아닙니다. Kubernetes와 인프라 환경에는 이미 방대한 /metrics 엔드포인트, 익스포터, ServiceMonitor 리소스, 경보 규칙 생태계가 있습니다. 중앙 발견과 스크레이프 상태 관리는 여전히 실용적입니다.
두 생태계는 점점 서로의 수집 경로를 지원하고 있습니다.
이로 인해 하이브리드 플랫폼 아키텍처가 자연스러워집니다. 인프라 익스포터는 스크레이프하고, 애플리케이션 텔레메트리는 OTLP로 수신하며, 두 경로를 동일한 메트릭 백엔드와 운영 컨텍스트에 연결합니다.
Pull과 Push는 조직 전체에서 하나만 선택하는 방식이 아닙니다. 소스와 네트워크 경계마다 선택한 뒤 저장 및 쿼리 계층에서 연결할 수 있습니다.
Pull과 Push는 조직이 한 번만 선택해야 하는 전역 설정이 아닙니다. 소스와 네트워크 경계별로 선택할 수 있습니다. “인프라에는 Pull, 애플리케이션에는 Push”는 유용한 출발점이지만 보편적인 규칙은 아닙니다.
다음과 같은 경우에는 먼저 Pull을 고려하세요.
다음과 같은 경우에는 먼저 Push를 고려하세요.
다음과 같은 경우에는 하이브리드 구성을 고려하세요.
[ ] 누가 수집 연결을 시작하는가?
[ ] 대상 또는 송신자 식별 정보가 재시작 후에도 올바르게 유지되는가?
[ ] 장애 중 데이터는 어디에서 얼마나 오래 버퍼링되는가?
[ ] 큐가 가득 차면 무엇을 버리는가?
[ ] 대상 장애와 수집 경로 장애를 구분할 수 있는가?
[ ] 중복 작성자와 중복 스크레이프를 방지하거나 의도적으로 처리하는가?
[ ] 수집 및 내보내기 간격이 감지 목표에 맞는가?
[ ] 어느 계층이 자격 증명과 TLS를 담당하는가?
[ ] Prometheus와 Collector를 일급 서비스로 모니터링하는가?
[ ] 어느 계층이 장기 저장소와 전역 쿼리를 담당하는가?
메트릭 수집 모델을 선택하는 일은 단지 엔드포인트 형태를 고르는 일이 아닙니다. 운영 장애의 책임이 어디에 속하는지 결정하는 일입니다.
Pull은 대상을 단순하게 유지하고 중앙 수집기가 발견과 장애 감지를 담당하게 합니다. Push는 네트워크 경계를 넘고 텔레메트리 신호를 더 쉽게 통합하지만, 송신자와 Collector가 전송 신뢰성을 책임져야 합니다.
메트릭 수집은 시작일 뿐입니다. 운영자는 어떤 리소스가 신호를 만들었는지 식별하고 대시보드와 경보에서 일관되게 해석해야 합니다. Konduo는 Prometheus 호환 메트릭 소스를 리소스 플러그인과 연결하여 팀이 Redis, Kafka, PostgreSQL 같은 대상의 메트릭을 하나의 운영 컨텍스트에서 읽을 수 있게 합니다.
현재 아키텍처는 하나의 방향을 고집하기보다 경계를 나눕니다.
인프라와 익스포터에는 Pull,
애플리케이션 텔레메트리에는 Push,
그리고 둘을 하나의 운영 컨텍스트에서 연결.