LabHub
배우기 러닝패스 코스

OTCA — OpenTelemetry Certified Associate

Completing a Full Collector Configuration

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

프로덕션에 올릴 수 있는 컬렉터 설정 파일 한 벌을 처음부터 끝까지 작성합니다. 끝나면 남의 컬렉터 설정을 보고 프로세서 순서만으로 어떤 사고가 날지 예측할 수 있습니다.

왜 중요한가

컬렉터 설정은 YAML 한 줄만 어긋나도 프로세스가 기동하지 못하는데, 문제는 그 사실을 대부분 클러스터에서 CrashLoopBackOff 를 본 뒤에야 알게 된다는 점입니다. 더 나쁜 것은 기동은 하는데 조용히 틀린 설정입니다. memory_limiter 를 뒤에 두면 평소에는 아무 문제가 없다가 부하가 올 때만 OOM 으로 죽고, batchtail_sampling 앞에 두면 트레이스가 무작위로 잘리는데 지표는 아무 이상도 보고하지 않습니다. 컴포넌트를 정의만 하고 service 에 올리지 않으면 설정 파일에는 있는데 동작은 하지 않습니다. 이 세 가지가 컬렉터 사고의 대부분이고, 셋 다 설정 파일을 읽는 것만으로 잡을 수 있습니다.

단계

  1. /root/otca-collector/config.yaml 을 만들고 receivers.otlp.protocols 아래 grpc.endpoint: 0.0.0.0:4317http.endpoint: 0.0.0.0:4318 을 씁니다.
  2. processors.memory_limitercheck_interval: 1s, limit_mib: 1638, spike_limit_mib: 328 을 씁니다. (컨테이너 메모리 한도 2Gi 기준)
  3. processors.k8sattributesauth_type: serviceAccount 를 쓰고 extract.metadatak8s.namespace.name, k8s.deployment.name, k8s.pod.name, k8s.node.name 네 개를 넣습니다.
  4. processorsattributes/redact 를 만들고 actions 에 세 개를 넣습니다. http.request.header.authorizationdelete, user.emaildelete, db.query.texthash.
  5. processors.batchtimeout: 5s, send_batch_size: 8192, send_batch_max_size: 16384 를 씁니다.
  6. exporters 에 세 개를 정의합니다. otlp/tempoendpoint 에 4317 포트를 가진 주소, otlp/gateway 도 4317 포트를 가진 주소, prometheusremotewrite/api/v1/push 로 끝나는 http URL 에 sending_queue(enabled: true, num_consumers: 10, queue_size: 5000)와 retry_on_failure(enabled: true, initial_interval: 5s, max_elapsed_time: 300s)를 붙입니다.
  7. extensionshealth_check.endpoint: 0.0.0.0:13133zpages.endpoint: 0.0.0.0:55679 를 정의하고, service.extensions 에 두 이름을 모두 올립니다.
  8. service.pipelines 에 세 파이프라인을 씁니다. traces 는 프로세서 [memory_limiter, k8sattributes, attributes/redact, batch] 에 익스포터 [otlp/tempo], metrics[memory_limiter, k8sattributes, batch][prometheusremotewrite], logs[memory_limiter, k8sattributes, attributes/redact, batch][otlp/gateway]. 세 파이프라인 모두 리시버는 [otlp] 입니다.

참고

OTLP 리시버 두 포트

/root/otca-collector/config.yaml 을 만들고 receivers.otlp.protocols 아래 grpc.endpoint: 0.0.0.0:4317http.endpoint: 0.0.0.0:4318 을 씁니다.

otlp 리시버는 protocols 아래에 grpc 와 http 를 따로 갖습니다. 한쪽만 열어 두면 그쪽으로 안 보내는 SDK 는 연결 자체가 실패하고 컬렉터 지표에는 아무 흔적도 남지 않습니다. 컨테이너 안에서는 루프백이 아니라 모든 인터페이스에 바인딩해야 합니다.

memory_limiter 값 산정

processors.memory_limitercheck_interval: 1s, limit_mib: 1638, spike_limit_mib: 328 을 씁니다. (컨테이너 메모리 한도 2Gi 기준)

컨테이너 메모리 한도가 2Gi 라고 가정합니다. 하드 리밋은 그 80%, 스파이크 허용치는 하드 리밋의 20% 로 잡는 것이 관례입니다. 컨테이너 한도보다 높게 잡으면 프로세서가 개입하기 전에 커널이 먼저 죽입니다.

쿠버네티스 메타데이터 부착

processors.k8sattributesauth_type: serviceAccount 를 쓰고 extract.metadatak8s.namespace.name, k8s.deployment.name, k8s.pod.name, k8s.node.name 네 개를 넣습니다.

이 프로세서는 파드 IP 를 단서로 API 서버에서 메타데이터를 찾아 리소스 속성으로 붙입니다. 그래서 인증 방식을 지정해야 하고, 필요한 항목만 extract 에 나열해 부하를 줄입니다.

민감 속성 삭제와 해싱

processorsattributes/redact 를 만들고 actions 에 세 개를 넣습니다. http.request.header.authorizationdelete, user.emaildelete, db.query.texthash.

프로세서 이름에 슬래시를 붙이면 같은 타입의 두 번째 인스턴스를 만들 수 있습니다. 완전히 지우면 나중에 같은 값끼리 묶어 보는 것이 불가능해지므로, 쿼리문처럼 그룹핑이 필요한 값은 지우는 대신 해싱합니다.

batch 트리거와 상한

processors.batchtimeout: 5s, send_batch_size: 8192, send_batch_max_size: 16384 를 씁니다.

send_batch_size 는 '이만큼 모이면 즉시 보내라'는 트리거이지 배치 크기의 상한이 아닙니다. 상한은 별도 키로 지정해야 하고, 지정하지 않으면 배치가 예상보다 훨씬 커질 수 있습니다.

익스포터 세 개와 큐·재시도

exporters 에 세 개를 정의합니다. otlp/tempoendpoint 에 4317 포트를 가진 주소, otlp/gateway 도 4317 포트를 가진 주소, prometheusremotewrite/api/v1/push 로 끝나는 http URL 에 sending_queue(enabled: true, num_consumers: 10, queue_size: 5000)와 retry_on_failure(enabled: true, initial_interval: 5s, max_elapsed_time: 300s)를 붙입니다.

sending_queue 는 백엔드가 잠깐 느려질 때 데이터를 붙잡아 두고, retry_on_failure 는 실패를 지수 백오프로 다시 시도합니다. 둘 다 꺼져 있으면 백엔드가 흔들릴 때마다 데이터가 그대로 사라집니다.

health_check 와 zpages

extensionshealth_check.endpoint: 0.0.0.0:13133zpages.endpoint: 0.0.0.0:55679 를 정의하고, service.extensions 에 두 이름을 모두 올립니다.

확장은 정의만 하면 동작하지 않습니다. service 아래에도 이름을 올려야 활성화됩니다. health_check 는 liveness/readiness 프로브가 찌를 엔드포인트이고 zpages 는 최근 트레이스와 파이프라인 상태를 보여 줍니다.

파이프라인 세 개와 프로세서 순서

service.pipelines 에 세 파이프라인을 씁니다. traces 는 프로세서 [memory_limiter, k8sattributes, attributes/redact, batch] 에 익스포터 [otlp/tempo], metrics[memory_limiter, k8sattributes, batch][prometheusremotewrite], logs[memory_limiter, k8sattributes, attributes/redact, batch][otlp/gateway]. 세 파이프라인 모두 리시버는 [otlp] 입니다.

나열한 순서가 곧 처리 순서입니다. 메모리 보호는 맨 앞에서 해야 상류로 backpressure 가 돌아가고, 배치는 맨 뒤여야 풀었다 다시 묶는 낭비가 없습니다. 메타데이터를 붙이는 프로세서가 새 속성을 만들 수 있으므로 삭제는 그 뒤에 옵니다.