본문으로 건너뛰기

템포 단일 바이너리 OOM

증상

특히 약 30분 루프에서 tempo-0OOMKilled를 반복적으로 실행하는 경우 또는 포드가 emptyDir에 데이터를 저장하기 때문에 다시 시작할 때마다 추적이 사라지는 경우 이 가이드를 사용하세요.

현재 저장소에서 기대하는 것

체크인된 Tempo 값은 로컬 임시 스토리지, 512Mi 메모리 제한, GOMEMLIMIT 및 메트릭 생성기가 비활성화된 단일 바이너리 모드에서 배포를 유지합니다.

resources:
requests:
cpu: 15m
memory: 128Mi
limits:
memory: 512Mi
extraEnv:
- name: GOMEMLIMIT
value: "460MiB"
metricsGenerator:
enabled: false

출처: lumie-infra/observability/tempo/helm-values.yaml

이 실패 모드가 발생한 이유

2026년 4월 25일부터 4월 27일까지 검사된 커밋 시퀀스에는 서로 겹쳐진 네 가지 개별 원인이 표시됩니다.

커밋변경그것이 증명한 것
b9eb5593105Mi256Mi로 제한됩니다. 이전 한도는 VPA 지침보다 낮았고 심층 분석 이전에도 너무 작았습니다
0afb7859비활성화된 metricsGenerator원격 쓰기에 실패하면 Pod가 OOM될 때까지 Tempo의 WAL이 커집니다
5f6c0f19GOMEMLIMIT 추가Go GC만으로는 곧 컨테이너 한도를 준수하지 못했습니다
4688ce0d512MiGOMEMLIMIT에 대한 제한이 460MiB로 증가됨단일 바이너리 Tempo에는 Go 힙 외부의 파일 지원 및 페이지 캐시 메모리를 위한 여유 공간도 필요합니다.

진단 경로

일반적인 OOMKilled 재시작 확인

kubectl describe pod -n tempo tempo-0
kubectl get pod -n tempo tempo-0 -o jsonpath='{.status.containerStatuses[0].lastState.terminated.reason}{"\n"}'

마지막 종료 사유가 OOMKilled인 경우 아래 확인 사항을 계속 진행하세요.

저장소가 여전히 두 가지 알려진 원인을 보호하는지 확인하세요.

  • metricsGenerator.enabled: falselumie-infra/observability/tempo/helm-values.yaml에 계속 존재해야 합니다.
  • GOMEMLIMIT는 동일한 파일에서 여전히 메모리 제한 이하로 설정되어야 합니다.
  • persistence.enabled: false/var/tempo 아래의 emptyDir 마운트는 다시 시작할 때마다 추적 기록도 지워지는 이유를 설명합니다.

추적 파생 측정항목을 다시 활성화하기 전에 Prometheus 측을 다시 확인하세요.

4월 26일 수정 사항은 원격 쓰기 실패와 관련이 있었습니다. 현재 Prometheus 값은 여전히 설정되어 있습니다.

enableRemoteWriteReceiver: false

출처: lumie-infra/observability/prometheus/helm-values.yaml

해당 계약이 먼저 변경되지 않는 한 Tempo 메트릭 생성을 다시 활성화하지 마십시오.

수정

  1. 배포 모델이 단일 바이너리 로컬 스토리지에서 벗어나지 않는 한 512Mi Tempo 메모리 제한을 유지합니다.
  2. GOMEMLIMIT를 컨테이너 천장에 맞춰 정렬합니다. 현재 저장소는 512Mi 제한에 460MiB를 사용합니다.
  3. Prometheus가 Tempo 원격 쓰기를 위해 명시적으로 준비될 때까지 metricsGenerator.enabled: false를 그대로 둡니다.
  4. 메모리 제한을 낮추거나 메트릭 생성기를 다시 활성화하는 경우 이를 정확한 실패 모드에 대한 회귀 테스트 지점으로 처리하십시오.

예방

  • 단일 바이너리 템포 크기 조정은 Go 힙 증가보다 더 많은 것을 설명해야 합니다. 4월 27일 수정 사항은 파일 지원 및 페이지 캐시 메모리를 명시적으로 호출했습니다.
  • 스토리지는 emptyDir이므로 모든 OOM은 단기 보존 데이터 손실 이벤트이기도 합니다.
  • resources, extraEnv 또는 metricsGenerator에 영향을 미치는 향후 차트 변경 사항은 독립적으로 검토하는 것이 아니라 함께 검토해야 합니다.

확인

kubectl get applications.argoproj.io -n argocd tempo
kubectl get pod -n tempo tempo-0
kubectl logs -n tempo statefulset/tempo --tail=200
kubectl get application -n argocd prometheus -o yaml | rg enableRemoteWriteReceiver

성공은 Tempo Pod가 새로운 OOMKills 없이 계속 실행되고, 로그에 실패한 측정항목 생성기 원격 쓰기가 표시되지 않으며, 값이 위에 설명된 보호된 단일 바이너리 계약과 여전히 일치함을 의미합니다.

관련 페이지

  • Tempo 운영 참조
  • Prometheus 운영 참조

운영 세부사항

Tempo single-binary mode는 ingestion, query, local storage, compaction behavior, optional metrics generation을 한 pod 안에 압축합니다. 하나의 설정값만 조정한 memory fix는 다른 설정이 계속 memory growth를 밀어 올리면 임시방편이 됩니다.

설정중요한 이유
resources.limits.memorytotal container memory가 이 경계를 넘으면 Kubernetes가 pod를 종료합니다.
GOMEMLIMITcontainer kill boundary에 도달하기 전에 Go GC를 유도합니다.
metricsGenerator.enabledPrometheus가 write를 받지 않을 때 WAL과 remote-write pressure를 만들 수 있습니다.
persistence.enabled: false모든 restart가 trace retention 손실이 됩니다.

OOM 진단은 memory 실패와 trace retention 영향을 함께 기록해야 합니다. 이 deployment shape에서는 둘이 연결되어 있습니다.

복구 절차

  1. 마지막 종료 사유가 OOMKilled인지 확인합니다.
  2. restart가 traffic burst, metrics-generator error, steady periodic growth 중 무엇과 맞물리는지 확인합니다.
  3. checked-in memory limit과 GOMEMLIMIT가 live StatefulSet에 적용됐는지 검증합니다.
  4. resource limit을 바꾸기 전에 metricsGenerator.enabled가 여전히 false인지 확인합니다.
  5. 사고 분석에 trace가 필요하면 pod를 다시 재시작하기 전에 남아 있는 데이터를 export하거나 확인합니다.
  6. persistence enablement는 emergency toggle이 아니라 별도 architecture change로 다룹니다.

검증 증거

다음을 기록합니다.

  • 이전 restart count와 마지막 OOM timestamp.
  • live memory limit과 GOMEMLIMIT.
  • metrics-generator 설정과 Prometheus remote-write receiver 설정.
  • 수정 후 pod uptime.
  • emptyDir 때문에 trace data loss가 있었는지 여부.

피해야 할 패턴

  • failed remote-write 또는 metrics-generator behavior를 확인하지 않고 memory만 올리는 것.
  • headroom 없이 GOMEMLIMIT를 Kubernetes limit과 같게 설정하는 것.
  • Prometheus remote-write receiver가 disabled인데 metrics generation을 다시 켜는 것.
  • 현재 single-binary footprint에서 emptyDir이 괜찮다는 이유로 앞으로의 tracing 요구에도 괜찮다고 가정하는 것.