Skip to content

필사 모드: Prometheus 서비스 디스커버리 메커니즘 완전 분석

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

1. 개요

Prometheus의 서비스 디스커버리(Service Discovery)는 모니터링 타겟을 자동으로 발견하고 관리하는 핵심 서브시스템입니다. 클라우드 네이티브 환경에서 서비스 인스턴스가 동적으로 생성/삭제되므로, 정적 설정만으로는 모든 타겟을 추적할 수 없습니다.

이 글에서는 Discovery Manager의 아키텍처, Provider 인터페이스, 각 SD 구현체의 동작 방식, relabeling 메커니즘, 타겟 생명주기를 소스코드 레벨에서 분석합니다.

2. Discovery Manager 아키텍처

2.1 전체 구조

prometheus.yml의 scrape_configs

|

v

+-------------------+

| Discovery Manager |

| |

| +-- Provider 1 (kubernetes_sd) -- goroutine

| +-- Provider 2 (consul_sd) -- goroutine

| +-- Provider 3 (file_sd) -- goroutine

| +-- Provider 4 (static_config) -- goroutine

| |

+--------+----------+

|

Target Groups Channel

|

v

+-------------------+

| Scrape Manager |

+-------------------+

2.2 Discovery Manager의 역할

Discovery Manager는 다음을 담당합니다:

1. **프로바이더 관리**: 각 서비스 디스커버리 프로바이더의 생명주기 관리

2. **업데이트 수집**: 프로바이더로부터 타겟 그룹 변경 사항 수집

3. **일괄 전달**: 변경 사항을 버퍼링하여 Scrape Manager에 일괄 전달

4. **설정 리로드**: 새 설정 적용 시 프로바이더 재생성

2.3 업데이트 흐름

Provider 변경 감지

|

v

업데이트를 내부 채널로 전송

|

v

Discovery Manager가 수신

|

v

5초간 추가 업데이트 대기 (디바운싱)

|

v

모든 프로바이더의 최신 타겟 그룹 병합

|

v

Scrape Manager에 전체 타겟 맵 전달

디바운싱(debouncing)은 빈번한 변경이 발생하는 환경에서 Scrape Manager의 과도한 업데이트를 방지합니다.

3. Provider 인터페이스

3.1 Discoverer 인터페이스

모든 서비스 디스커버리 프로바이더는 Discoverer 인터페이스를 구현합니다:

type Discoverer interface {

Run(ctx context.Context, up chan<- []*targetgroup.Group)

}

Run 메서드의 계약:

- context가 취소될 때까지 실행을 유지

- 타겟 그룹 변경 시 up 채널로 전체 그룹 목록 전송

- 초기 실행 시 현재 알고 있는 전체 타겟 전송

3.2 TargetGroup 구조

TargetGroup:

Source: "kubernetes/pod/default/nginx-abc123" (고유 식별자)

Targets:

- __address__: "10.0.1.5:8080"

- __address__: "10.0.1.6:8080"

Labels:

__meta_kubernetes_namespace: "default"

__meta_kubernetes_pod_name: "nginx-abc123"

...

3.3 프로바이더 등록

프로바이더는 팩토리 함수로 등록됩니다:

등록 과정:

1. 설정 파일에서 *_sd_config 섹션 파싱

2. 해당 SD 타입의 NewDiscoverer 팩토리 호출

3. Discovery Manager에 프로바이더 등록

4. 별도 goroutine에서 Run() 실행

4. Kubernetes SD

4.1 kubernetes_sd 개요

Kubernetes SD는 Prometheus에서 가장 많이 사용되는 서비스 디스커버리입니다. Kubernetes API 서버의 Watch 메커니즘을 사용하여 리소스 변경을 실시간으로 감지합니다.

4.2 역할(Role) 타입

kubernetes_sd는 6가지 역할 타입을 지원합니다:

1. node:

- Kubernetes 노드 목록

- __address__: 노드의 Kubelet 주소

- __meta_kubernetes_node_name, __meta_kubernetes_node_label_*

2. service:

- Kubernetes Service 목록

- __address__: Service의 ClusterIP:Port

- __meta_kubernetes_service_name, __meta_kubernetes_service_port_name

3. pod:

- Kubernetes Pod 목록

- __address__: Pod IP:Container Port

- __meta_kubernetes_pod_name, __meta_kubernetes_pod_container_name

4. endpoints:

- Kubernetes Endpoints 목록

- __address__: 개별 엔드포인트 주소

- __meta_kubernetes_endpoints_name

5. endpointslice:

- Kubernetes EndpointSlice 목록 (Endpoints의 확장형)

- 대규모 클러스터에서 더 효율적

6. ingress:

- Kubernetes Ingress 목록

- __address__: Ingress 호스트

- __meta_kubernetes_ingress_name, __meta_kubernetes_ingress_path

4.3 Watch 메커니즘

Kubernetes SD Watch 동작:

1. 초기 동기화:

a. List API로 전체 리소스 목록 조회

b. 모든 리소스를 TargetGroup으로 변환

c. 전체 목록을 Discovery Manager에 전송

2. Watch 시작:

a. Watch API로 이벤트 스트림 연결

b. resourceVersion 기반 증분 업데이트

3. 이벤트 처리:

ADDED -> 새 TargetGroup 생성

MODIFIED -> 기존 TargetGroup 업데이트

DELETED -> 빈 Targets로 TargetGroup 업데이트

4. 에러 처리:

Watch 연결 끊김 -> 자동 재연결

410 Gone 에러 -> 전체 재목록화(re-list)

타임아웃 -> Watch 재시작

4.4 Informer/Reflector 패턴

kubernetes_sd는 client-go의 Informer 패턴을 활용합니다:

Informer 구조:

Reflector

|-- List: 초기 전체 동기화

|-- Watch: 증분 업데이트 수신

|-- Store: 로컬 캐시에 저장

v

Informer

|-- EventHandler: 이벤트 콜백 등록

|-- Indexer: 효율적인 검색을 위한 인덱스

v

Prometheus SD

|-- 이벤트를 TargetGroup으로 변환

|-- Discovery Manager에 전달

4.5 \_\_meta 레이블

kubernetes_sd는 풍부한 메타 레이블을 제공합니다:

공통:

__meta_kubernetes_namespace

Pod 역할:

__meta_kubernetes_pod_name

__meta_kubernetes_pod_ip

__meta_kubernetes_pod_container_name

__meta_kubernetes_pod_container_port_name

__meta_kubernetes_pod_container_port_number

__meta_kubernetes_pod_label_*

__meta_kubernetes_pod_annotation_*

__meta_kubernetes_pod_node_name

__meta_kubernetes_pod_ready

__meta_kubernetes_pod_phase

Node 역할:

__meta_kubernetes_node_name

__meta_kubernetes_node_label_*

__meta_kubernetes_node_annotation_*

__meta_kubernetes_node_address_*

Service 역할:

__meta_kubernetes_service_name

__meta_kubernetes_service_port_name

__meta_kubernetes_service_port_number

__meta_kubernetes_service_label_*

__meta_kubernetes_service_annotation_*

5. Relabeling 메커니즘

5.1 Relabeling 개요

Relabeling은 타겟의 레이블을 변환하는 강력한 메커니즘입니다. 두 단계에서 적용됩니다:

1단계: relabel_configs (스크래핑 전)

- 디스커버리에서 받은 __meta_* 레이블 처리

- 타겟 레이블 결정 (job, instance 등)

- 타겟 유지/삭제 결정

2단계: metric_relabel_configs (스크래핑 후)

- 수집된 메트릭의 레이블 변환

- 불필요한 메트릭 삭제

- 레이블 이름/값 변환

5.2 Relabeling 액션

replace: 소스 레이블 값을 정규식 매칭 후 대상 레이블에 설정

keep: 정규식에 매칭되지 않는 타겟 삭제

drop: 정규식에 매칭되는 타겟 삭제

hashmod: 소스 레이블의 해시값을 모듈로 연산하여 대상 레이블에 설정

labelmap: 정규식에 매칭되는 레이블 이름을 변환

labeldrop: 정규식에 매칭되는 레이블 삭제

labelkeep: 정규식에 매칭되지 않는 레이블 삭제

lowercase: 대상 레이블 값을 소문자로 변환

uppercase: 대상 레이블 값을 대문자로 변환

keepequal: 소스와 대상 레이블 값이 같은 타겟만 유지

dropequal: 소스와 대상 레이블 값이 같은 타겟 삭제

5.3 Relabeling 처리 흐름

__meta_* 레이블 + __address__ + __scheme__ + __metrics_path__

|

v

relabel_configs 순차 적용

|

v

__address__ -> instance 레이블로 복사

__scheme__, __metrics_path__ 등 내부 레이블 제거

|

v

최종 타겟 레이블 셋 결정

5.4 일반적인 Relabeling 패턴

**Pod 어노테이션 기반 스크래핑**:

relabel_configs:

prometheus.io/scrape 어노테이션이 true인 Pod만 스크래핑

- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]

action: keep

regex: true

포트 변경

- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port]

action: replace

target_label: __address__

regex: (.+)

replacement: __meta_kubernetes_pod_ip:$1

경로 변경

- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]

action: replace

target_label: __metrics_path__

regex: (.+)

**네임스페이스 필터링**:

relabel_configs:

- source_labels: [__meta_kubernetes_namespace]

action: keep

regex: production|staging

6. File-based SD

6.1 개요

File SD는 JSON 또는 YAML 파일에서 타겟을 읽는 가장 단순한 동적 디스커버리입니다:

prometheus.yml

scrape_configs:

- job_name: 'file_sd'

file_sd_configs:

- files:

- '/etc/prometheus/targets/*.json'

refresh_interval: 5m

6.2 타겟 파일 형식

JSON 형식:

[

{

"targets": ["10.0.1.1:9090", "10.0.1.2:9090"],

"labels": {

"env": "production",

"team": "backend"

}

}

]

YAML 형식:

- targets:

- '10.0.1.1:9090'

- '10.0.1.2:9090'

labels:

env: production

team: backend

6.3 파일 감시 메커니즘

File SD 동작:

1. 초기 로드: 지정된 파일 패턴에 매칭되는 모든 파일 읽기

2. inotify 감시: Linux에서 파일 변경 이벤트 구독

3. 주기적 폴링: refresh_interval(기본 5분)마다 전체 재로드

4. 파일 변경 시: 변경된 파일만 재파싱하여 TargetGroup 업데이트

5. 파일 삭제 시: 해당 파일의 모든 타겟 제거

6.4 Custom SD Bridge 패턴

File SD는 커스텀 서비스 디스커버리의 브릿지로 활용됩니다:

커스텀 SD 프로세스 (외부):

1. 자체 서비스 레지스트리 조회

2. 결과를 JSON/YAML 파일로 생성

3. Prometheus가 감시하는 디렉토리에 저장

Prometheus (File SD):

1. 파일 변경 감지

2. 타겟 목록 업데이트

3. 스크래핑 시작/중지

이 패턴은 Prometheus에 직접 통합되지 않은 서비스 레지스트리(Zookeeper, etcd 등)와 연동할 때 유용합니다.

7. HTTP SD

7.1 개요

HTTP SD는 HTTP 엔드포인트에서 타겟 목록을 주기적으로 폴링합니다:

scrape_configs:

- job_name: 'http_sd'

http_sd_configs:

- url: 'http://service-registry:8080/targets'

refresh_interval: 30s

7.2 응답 형식

HTTP SD 엔드포인트는 JSON 배열을 반환해야 합니다:

[

{

"targets": ["10.0.1.1:9090"],

"labels": {

"__meta_datacenter": "us-east",

"__meta_env": "production"

}

}

]

7.3 동작 방식

HTTP SD 처리:

1. refresh_interval마다 URL에 GET 요청

2. 응답 JSON 파싱

3. TargetGroup으로 변환

4. Discovery Manager에 전달

5. HTTP 에러 시 이전 결과 유지

6. 연속 실패 시 메트릭으로 알림

8. 기타 SD 구현체

8.1 Consul SD

Consul SD:

- Consul의 Service Catalog API 사용

- Watch/Blocking Query로 변경 감지

- 서비스 이름, 태그, 데이터센터 기반 필터링

- __meta_consul_service, __meta_consul_tags 등 메타 레이블

8.2 EC2 SD

EC2 SD:

- AWS EC2 DescribeInstances API 사용

- 리전, 가용 영역, 태그 기반 필터링

- IAM 역할 또는 액세스 키 인증

- __meta_ec2_instance_id, __meta_ec2_tag_* 등 메타 레이블

- refresh_interval 기반 폴링 (Watch 미지원)

8.3 DNS SD

DNS SD:

- DNS SRV 또는 A/AAAA 레코드 조회

- 주기적 폴링 방식

- 간단한 환경에서 유용

- __meta_dns_name 메타 레이블

8.4 Static Config

Static Config:

- 가장 단순한 타겟 정의 방식

- 설정 파일에 직접 타겟 주소 기입

- 테스트나 고정 인프라에 적합

- 동적 업데이트 불가 (리로드 필요)

9. 타겟 생명주기

9.1 타겟 상태 전이

타겟 생명주기:

Discovered (발견됨)

|

v

Relabeled (레이블 적용됨)

|

+-- 삭제 결정 --> Dropped (삭제됨)

|

v

Active (활성화됨, 스크래핑 시작)

|

+-- 스크래핑 성공 --> up=1

+-- 스크래핑 실패 --> up=0

|

v

Disappeared (사라짐)

|

v

Stale (stale marker 추가)

|

v

Removed (Scrape Loop 종료)

9.2 Dropped 타겟

타겟이 삭제(Drop)되는 조건:

1. relabel_configs에서 drop 액션 적용

2. relabel_configs에서 keep 액션에 매칭되지 않음

3. __address__ 레이블이 비어있음

4. 중복 타겟 (동일 레이블 셋)

삭제된 타겟은 /targets UI의 "Dropped Targets" 섹션에 표시됩니다.

이를 통해 디스커버리와 relabeling 설정을 디버깅할 수 있습니다.

9.3 타겟 건강 상태 모니터링

내장 메트릭:

up: 0 또는 1 (스크래핑 성공 여부)

scrape_duration_seconds: 스크래핑 소요 시간

scrape_samples_scraped: 수집된 샘플 수

scrape_samples_post_metric_relabeling: relabeling 후 샘플 수

scrape_series_added: 새로 추가된 시계열 수

API 엔드포인트:

GET /api/v1/targets: 전체 타겟 목록과 상태

GET /api/v1/targets/metadata: 타겟별 메트릭 메타데이터

10. 성능 고려사항

10.1 대규모 클러스터에서의 최적화

Kubernetes SD 성능 팁:

1. 네임스페이스 제한: namespaces 필드로 감시 범위 축소

2. 레이블 셀렉터: selectors 필드로 리소스 필터링

3. attach_metadata: 불필요하면 비활성화

4. EndpointSlice 사용: 대규모 클러스터에서 Endpoints보다 효율적

10.2 디스커버리 부하 모니터링

주요 메트릭:

prometheus_sd_discovered_targets: 발견된 타겟 수 (SD 타입별)

prometheus_sd_received_updates_total: 수신된 업데이트 수

prometheus_sd_updates_total: 전달된 업데이트 수

prometheus_sd_updates_delayed_total: 지연된 업데이트 수

경고 신호:

- 발견된 타겟 수의 급격한 변동

- 높은 업데이트 빈도

- 지연된 업데이트 증가

11. 디버깅과 문제 해결

11.1 일반적인 문제

1. 타겟이 발견되지 않음:

- SD 설정 확인 (namespace, selector 등)

- Prometheus 로그에서 SD 에러 확인

- /service-discovery UI 페이지에서 발견된 타겟 확인

2. 타겟이 Dropped 상태:

- relabel_configs 규칙 순서 확인

- keep/drop 액션의 regex 검증

- /targets 페이지에서 Dropped Targets 확인

3. 타겟 레이블이 예상과 다름:

- __meta_* 레이블 확인 (/service-discovery 페이지)

- relabel_configs의 replace 규칙 확인

- 레이블 충돌 시 honor_labels 설정 확인

11.2 디버깅 도구

1. /service-discovery UI:

- 각 SD 프로바이더에서 발견된 원시 타겟 그룹 표시

- __meta_* 레이블 전체 확인 가능

2. /targets UI:

- 활성/삭제된 타겟 목록

- 각 타겟의 건강 상태, 마지막 스크래핑 시간

- 적용된 레이블 확인

3. Prometheus 로그:

- --log.level=debug로 상세 SD 로그 활성화

- SD 프로바이더별 연결/에러 로그

12. 정리

Prometheus의 서비스 디스커버리는 플러그인 아키텍처를 통해 다양한 인프라 환경을 지원합니다. Kubernetes SD의 Watch 메커니즘, relabeling의 강력한 레이블 변환, 그리고 File SD/HTTP SD를 통한 커스텀 확장이 핵심입니다.

다음 글에서는 Prometheus의 알림 파이프라인을 분석합니다. Rule Manager의 평가 메커니즘, Alert 상태 머신, Alertmanager의 라우팅과 알림 전달 과정을 살펴볼 예정입니다.

현재 단락 (1/356)

Prometheus의 서비스 디스커버리(Service Discovery)는 모니터링 타겟을 자동으로 발견하고 관리하는 핵심 서브시스템입니다. 클라우드 네이티브 환경에서 서비스 인스...

작성 글자: 0원문 글자: 8,650작성 단락: 0/356