OOM 4

컨테이너 메모리 제한, 내부적으로는 뭘 어떻게 하는 걸까

resources.limits.memory: 512Mi 한 줄. 이게 사실 얼마나 복잡한 일을 시키는 건지, 최근에 팀 내부에서 OOM 관련 장애를 하나 겪고 나서야 제대로 파봤다. 대충 "커널이 알아서 죽여준다" 수준으로만 알고 있었는데, cgroup v2로 넘어오면서 동작이 꽤 달라졌다는 걸 그제서야 알았다.이 글은 그때 정리한 노트에 가깝다. Kubernetes에서 메모리 limit이 실제로 커널까지 내려가서 어떤 파일에 어떤 값이 쓰이고, OOM이 터질 때 어떤 순서로 뭐가 일어나는지 — 이게 왜 최근 몇 년 사이 근본적으로 바뀌었는지 순서대로 짚어본다.메모리 limit이 커널로 내려가는 경로파드 매니페스트에 limits.memory: 512Mi를 적었다고 하자. 이 값은 kubelet → CRI..

IT/컨테이너 2026.07.22

OTel Collector tail sampling에서 OOM으로 세 번 죽은 이야기

지난주에 OpenTelemetry Collector가 새벽에 세 번이나 OOM으로 재시작됐다. 알림이 잔뜩 쌓여있었고, 아침에 슬랙 열자마자 "이거 뭐야" 소리가 절로 나왔다. 원인은 결국 tail sampling processor였는데, 문제를 잡기까지 꽤 돌아왔다. 기록 삼아 남긴다.처음엔 그냥 트래픽 스파이크인 줄 알았다우리 팀은 최근에 head sampling에서 tail sampling으로 옮겼다. 이유는 명확했다. 에러 트레이스나 P99 넘어가는 느린 트레이스는 무조건 살려두고 싶은데, head sampling으로는 그게 불가능하니까. 트레이스 전체가 다 모여야 판단할 수 있는 정책들, 예를 들어 "이 트레이스에 5xx가 하나라도 있으면 keep" 같은 것들 말이다.옮긴 지 2주 정도는 조용했..

IT/모니터링 2026.07.15

OTel Collector에 memory_limiter 안 걸어서 OOM 무한루프 겪은 이야기

지난주 새벽에 알림으로 깼다. otel-collector 데몬셋의 절반이 CrashLoopBackOff로 떨어졌다는 메시지. 그 시점에 트레이스 수집이 사실상 끊겨 있어서 우리 팀이 운영하는 서비스 절반 정도의 트레이스 대시보드가 비어 있었다. 평일 새벽 두 시였고 멘탈은 그닥이었다.처음엔 단순히 노드 메모리 압박이려니 했다. 그런데 살펴보니까 콜렉터만 죽는 거다. 다른 파드는 다 멀쩡. OOMKilled가 한두 번이 아니라 5분에 3-4번씩 반복되고 있었다. 메모리 limit이 1Gi였는데, 어떻게 잡힌 메모리가 그 한도를 매번 풀로 채우고 떨어졌다 다시 살아나고를 반복.일단 상황 정리kubectl describe로 보니까 Last State가 Terminated, Reason: OOMKilled, E..

IT/모니터링 2026.06.03

OpenTelemetry Collector가 새벽마다 OOM 나던 이야기

며칠 전 새벽 2시 반쯤, 핸드폰이 또 울렸다. 또 otel-collector 파드 OOMKilled 알람. 이번 주만 네 번째다.처음에는 그냥 메모리 limit이 작다고 생각해서 1Gi → 2Gi → 4Gi 까지 올렸다. 그래도 죽었다. 8Gi로 올렸더니 죽기 직전까지 가서 GC가 미친듯이 돌면서 export 큐가 밀리고, 결국 백엔드(Tempo)로 가는 trace 데이터가 통째로 30분쯤 누락됐다. 멘탈이 나갔다.상황우리 환경은 좀 흔하다. EKS 1.30, otel-collector v0.115 (contrib), DaemonSet으로 노드 28대에 깔려있고, Receiver는 OTLP gRPC/HTTP, Processor는 batch + memory_limiter + resource, Export..

IT/모니터링 2026.05.18