コレクタ設定ファイルを一式仕上げる
한국어 원문으로 표시합니다.
목표
프로덕션에 올릴 수 있는 컬렉터 설정 파일 한 벌을 처음부터 끝까지 작성합니다. 끝나면 남의 컬렉터 설정을 보고 프로세서 순서만으로 어떤 사고가 날지 예측할 수 있습니다.
왜 중요한가
컬렉터 설정은 YAML 한 줄만 어긋나도 프로세스가 기동하지 못하는데, 문제는 그 사실을 대부분 클러스터에서 CrashLoopBackOff 를 본 뒤에야 알게 된다는 점입니다. 더 나쁜 것은 기동은 하는데 조용히 틀린 설정입니다. memory_limiter 를 뒤에 두면 평소에는 아무 문제가 없다가 부하가 올 때만 OOM 으로 죽고, batch 를 tail_sampling 앞에 두면 트레이스가 무작위로 잘리는데 지표는 아무 이상도 보고하지 않습니다. 컴포넌트를 정의만 하고 service 에 올리지 않으면 설정 파일에는 있는데 동작은 하지 않습니다. 이 세 가지가 컬렉터 사고의 대부분이고, 셋 다 설정 파일을 읽는 것만으로 잡을 수 있습니다.
단계
/root/otca-collector/config.yaml을 만들고receivers.otlp.protocols아래grpc.endpoint: 0.0.0.0:4317과http.endpoint: 0.0.0.0:4318을 씁니다.processors.memory_limiter에check_interval: 1s,limit_mib: 1638,spike_limit_mib: 328을 씁니다. (컨테이너 메모리 한도 2Gi 기준)processors.k8sattributes에auth_type: serviceAccount를 쓰고extract.metadata에k8s.namespace.name,k8s.deployment.name,k8s.pod.name,k8s.node.name네 개를 넣습니다.processors에attributes/redact를 만들고actions에 세 개를 넣습니다.http.request.header.authorization은delete,user.email은delete,db.query.text는hash.processors.batch에timeout: 5s,send_batch_size: 8192,send_batch_max_size: 16384를 씁니다.exporters에 세 개를 정의합니다.otlp/tempo는endpoint에 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)를 붙입니다.extensions에health_check.endpoint: 0.0.0.0:13133과zpages.endpoint: 0.0.0.0:55679를 정의하고,service.extensions에 두 이름을 모두 올립니다.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]입니다.
참고
attributes/redact처럼 슬래시를 붙인 이름은 같은 타입의 두 번째 인스턴스를 뜻합니다. YAML 키에 슬래시가 들어가므로 참조할 때 이름을 정확히 맞추세요.- 흔한 실수 1: 컴포넌트를 정의만 하고
service에 올리지 않는 것. 확장도 마찬가지입니다. - 흔한 실수 2:
send_batch_max_size를 빠뜨리는 것.send_batch_size는 트리거일 뿐입니다. - 흔한 실수 3:
attributes/redact를k8sattributes앞에 두는 것. 새로 붙는 속성이 삭제를 빠져나갑니다.
OTLP 리시버 두 포트
/root/otca-collector/config.yaml 을 만들고 receivers.otlp.protocols 아래 grpc.endpoint: 0.0.0.0:4317 과 http.endpoint: 0.0.0.0:4318 을 씁니다.
otlp 리시버는 protocols 아래에 grpc 와 http 를 따로 갖습니다. 한쪽만 열어 두면 그쪽으로 안 보내는 SDK 는 연결 자체가 실패하고 컬렉터 지표에는 아무 흔적도 남지 않습니다. 컨테이너 안에서는 루프백이 아니라 모든 인터페이스에 바인딩해야 합니다.
memory_limiter 값 산정
processors.memory_limiter 에 check_interval: 1s, limit_mib: 1638, spike_limit_mib: 328 을 씁니다. (컨테이너 메모리 한도 2Gi 기준)
컨테이너 메모리 한도가 2Gi 라고 가정합니다. 하드 리밋은 그 80%, 스파이크 허용치는 하드 리밋의 20% 로 잡는 것이 관례입니다. 컨테이너 한도보다 높게 잡으면 프로세서가 개입하기 전에 커널이 먼저 죽입니다.
쿠버네티스 메타데이터 부착
processors.k8sattributes 에 auth_type: serviceAccount 를 쓰고 extract.metadata 에 k8s.namespace.name, k8s.deployment.name, k8s.pod.name, k8s.node.name 네 개를 넣습니다.
이 프로세서는 파드 IP 를 단서로 API 서버에서 메타데이터를 찾아 리소스 속성으로 붙입니다. 그래서 인증 방식을 지정해야 하고, 필요한 항목만 extract 에 나열해 부하를 줄입니다.
민감 속성 삭제와 해싱
processors 에 attributes/redact 를 만들고 actions 에 세 개를 넣습니다. http.request.header.authorization 은 delete, user.email 은 delete, db.query.text 는 hash.
프로세서 이름에 슬래시를 붙이면 같은 타입의 두 번째 인스턴스를 만들 수 있습니다. 완전히 지우면 나중에 같은 값끼리 묶어 보는 것이 불가능해지므로, 쿼리문처럼 그룹핑이 필요한 값은 지우는 대신 해싱합니다.
batch 트리거와 상한
processors.batch 에 timeout: 5s, send_batch_size: 8192, send_batch_max_size: 16384 를 씁니다.
send_batch_size 는 '이만큼 모이면 즉시 보내라'는 트리거이지 배치 크기의 상한이 아닙니다. 상한은 별도 키로 지정해야 하고, 지정하지 않으면 배치가 예상보다 훨씬 커질 수 있습니다.
익스포터 세 개와 큐·재시도
exporters 에 세 개를 정의합니다. otlp/tempo 는 endpoint 에 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
extensions 에 health_check.endpoint: 0.0.0.0:13133 과 zpages.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 가 돌아가고, 배치는 맨 뒤여야 풀었다 다시 묶는 낭비가 없습니다. 메타데이터를 붙이는 프로세서가 새 속성을 만들 수 있으므로 삭제는 그 뒤에 옵니다.