IL-0044 Saifeddine Rajhi · 2024-06-14kubernetesobservability
글쓴이의 팀은 2024년 6월 14일 kube-prometheus-stack 헬름 차트를 업그레이드하다가 Prometheus 파드가 Ready 가 되지 않는 것을 발견했다. Prometheus 는 재시작하면 디스크에 먼저 써 둔 로그인 WAL 을 읽어 데이터를 복구한다. 이 WAL 재생 과정이 메모리를 많이 쓴다. 평소 30Gi 정도로 돌던 Prometheus 가 WAL 재생 중에는 50Gi 넘게 요구했고, 시작할 때마다 OOMKilled 로 죽었다.
글쓴이는 이 문제가 GitHub 에 2020년부터 열려 있는 오래된 이슈와 같다고 보았다. 재생 중 메모리 오버헤드가 300% 까지 오르면 평소 메모리 제한의 70% 로 돌던 Prometheus 도 쉽게 죽는다. 반면 Google 의 최근 벤치마크에서는 재생 중 CPU 사용량은 두 배로 늘지만 메모리 오버헤드는 1% 에서 5% 정도였다. 글쓴이는 재생 중 OOM 이 더 큰 문제가 드러난 증상일 수 있다고 보았고, 흔한 경우로 두 가지를 들었다. 시계열이나 샘플을 너무 많이 수집하는 것, 그리고 메모리 제한에 너무 가깝게 운영하는 것이다. 이런 문제는 대개 지표의 레이블 값 조합 수, 곧 카디널리티와 얽혀 있다.
Prometheus 가 떠 있지 않으면 PromQL 로 카디널리티를 볼 수 없다. 그래서 글쓴이는 Prometheus 파드에 kubectl exec 로 들어가 promtool tsdb analyze . 를 실행해 haproxy_server_http_responses_total 처럼 카디널리티가 높은 지표를 찾았다. 그런 지표를 고치거나 줄이면 메모리 부담이 줄어든다. 글쓴이는 메모리를 더 주거나 메모리가 넉넉한 노드 그룹에 Prometheus 를 배포하는 방법도 함께 제시했다.
kube-prometheus-stack 헬름 차트를 업그레이드하는 중에 여러 파드가 Ready 가 되지 않았다. 그중 prometheus-prometheus-operator-prometheus-0 파드는 3/4 Running 상태였고 최근에 OOMKilled 로 종료된 기록이 있었다.
Prometheus 로그에는 다음 줄이 남아 있었다. ts=2024–06–14T09:49:10.383Z caller=head.go:840 level=info component=tsdb msg="Deletion of corrupted mmap chunk files failed, discarding chunk files completely" err="cannot handle error: iterate on on-disk chunks: out of sequence m-mapped chunk for series ref 946594555, last chunk: [1718071739971, 1718075459971], new: [1718049629971, 1718053199971]"
kubectl describe pod 로 보면 파드는 Running 상태에 머물러 Ready 가 되지 않았고, 직전 상태는 Terminated 에 Reason 은 OOMKilled 였다. State: Running Started: Tue, 14 Jun 2024 10:04:03 +0200 Last State: Terminated Reason: OOMKilled
Prometheus 는 평소 30Gi 정도의 메모리로 문제없이 돌았지만, 재시작 후 WAL 을 재생하는 동안에는 50Gi 넘게 요구했다. 처음에는 메모리를 더 주는 방법을 생각했지만, 메모리가 치솟는 것은 재생 단계뿐이었으므로 메모리 제한만 올려서는 답이 되지 않았다.
원인 ? 용량 한계
팀은 kube-prometheus-stack 헬름 차트를 업그레이드하던 중 Prometheus 파드를 포함한 여러 파드가 Ready 가 되지 않는 것을 보았다. kubectl describe pod 와 Prometheus 로그로 OOMKilled 를 확인했다.
Prometheus 를 메모리 제한에 가깝게 운영하면 WAL 재생 중의 작은 오버헤드로도 OOM 이 난다. 가비지 컬렉션은 들쭉날쭉하고 카디널리티나 쿼리는 갑자기 늘 수 있으므로 메모리에 여유를 둔다.
Prometheus 메모리 문제의 상당 부분은 카디널리티에서 온다. Prometheus 가 떠 있지 않을 때는 promtool tsdb analyze 로 카디널리티가 높은 지표를 찾는다.
메모리 제한만 올려서는 답이 되지 않았다. 메모리가 치솟는 것은 재생 단계뿐이었기 때문이다.
같은 원인 · 공통 Prometheus, 컨테이너 메모리 한도
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 Prometheus
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 Prometheus
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 Prometheus
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 Prometheus
같은 원인 · 공통 컨테이너 메모리 한도
같은 원인 · 공통 컨테이너 메모리 한도