Pod 가 OOMKilled 라면 Kubernetes 는 컨테이너가 memory limit 에 걸려 커널에 의해 종료됐다고 알려 주는 것입니다. 여기서 중요한 질문은 단순히 “limit 을 올릴까?” 가 아닙니다. 실제로 leak 또는 retention 이 있는지, bursty memory behavior 인지, 아니면 request 와 limit sizing 이 현실 운영에 맞지 않는지 구분해야 합니다.
짧게 말하면 핵심은 이것입니다. usage pattern 과 limit 을 같이 봐야 합니다. limit 하나를 올린다고 leak 이 해결되지는 않고, 너무 낮은 limit 은 멀쩡한 workload 를 비정상처럼 보이게 만들 수 있습니다.
usage pattern 과 limit 을 같이 본다
메모리 incident 는 단순화하기 쉽습니다.
실제로는 아래를 같이 봐야 합니다.
- 실제 memory usage
- steady growth 인지 short spike 인지
- requests 와 limits
- restart timing
이걸 같이 보지 않으면 undersizing 인지, retention 인지, burst pressure 인지 구분하기 어렵습니다.
OOMKilled 는 보통 무엇을 뜻하나
실전에선 보통 아래 중 하나입니다.
- memory limit 이 너무 낮다
- 애플리케이션이 메모리를 너무 오래 붙잡는다
- classic leak 이 아니어도 짧은 spike 가 limit 을 넘는다
- request / limit sizing 이 동작을 헷갈리게 만든다
restart reason 은 명확해도, fix path 는 usage shape 에 따라 달라집니다.
흔한 원인
1. memory limit 이 너무 낮다
workload 자체는 정상인데 configured limit 이 현실적인 peak usage 보다 낮을 수 있습니다.
특히 이런 뒤 자주 보입니다.
- traffic 증가
- payload 증가
- 동시 작업 증가
2. 애플리케이션이 메모리를 누수하거나 오래 붙잡는다
memory 가 꾸준히 올라가다가 결국 limit 을 치고 죽을 수 있습니다.
이게 항상 고전적인 forever leak 은 아닙니다. unbounded cache, queue, 큰 retained graph 도 운영상으로는 같은 결과를 만들 수 있습니다.
3. bursty workload 가 짧은 spike 를 만든다
leak 이 아니어도 cache, request, parsing, batch work 가 짧은 spike 로 limit 을 넘길 수 있습니다.
평균 usage 만 보면 이런 incident 는 랜덤해 보이기 쉽습니다.
4. requests 와 limits 가 어긋나 있다
request sizing 이 나쁘면 scheduling 과 runtime behavior 가 함께 해석하기 어려워집니다.
배치될 때의 가정과, 실제 runtime limit 이 너무 다르게 느껴질 수 있습니다.
5. 진짜 문제는 다른 데서 시작됐다
queue backlog, retry, downstream slowdown 이 pod 내부 retention 을 간접적으로 키울 수도 있습니다.
그래서 OOM incident 는 memory setting 만의 문제가 아니라 workload behavior 와도 자주 연결됩니다.
실전 점검 순서
1. pod 가 정말 memory pressure 로 죽었는지 확인한다
pod 가 불안정하다고 해서 모든 restart 가 OOM 인 것은 아닙니다.
restart reason 이 실제로 memory kill 인지 먼저 확인해야 합니다.
2. memory usage trend 와 configured limit 을 비교한다
알고 싶은 것은 이렇습니다.
- memory 가 꾸준히 오르는가
- 급격히 spike 하는가
- restart 직전 limit 에 얼마나 가까워지는가
3. steady growth 와 short spike 를 구분한다
이 구분이 매우 중요합니다.
steady growth 는 retention 또는 leak 성향을 시사합니다.
short spike 는 burst workload 나 너무 빡빡한 limit 을 시사합니다.
4. workload 또는 dependency 변화가 메모리 동작을 바꿨는지 본다
최근 아래 변화가 설명이 되는 경우가 많습니다.
- request size
- traffic level
- concurrency
- response aggregation
- retry
5. usage pattern 이 분명해진 뒤에만 requests / limits 를 바꾼다
메모리를 더 주면 시간을 벌 수는 있지만, retention 이 진짜 문제라면 진단을 대신해선 안 됩니다.
빠른 명령
kubectl describe pod <pod> -n <ns>
kubectl top pod <pod> -n <ns>
kubectl get pod <pod> -n <ns> -o yaml
restart reason, 실제 memory usage, requests / limits 를 한 번에 비교하기 좋은 기본 조합입니다.
memory spike 가 limit 근처에서 반복되는지, OOM kill event 가 이어지는지, requests / limits 가 workload 에 비해 어색하지 않은지 보세요.
메모리 패턴을 찾은 뒤 무엇을 바꾸면 좋나
limit 이 그냥 너무 낮다면
관측된 peak 에 맞춰 의도적으로 올려야 합니다.
retention 이 문제라면
더 큰 limit 에 기대기보다 cache, queue, object lifetime 동작을 먼저 고쳐야 합니다.
spike 가 문제라면
workload 를 더 부드럽게 만들거나 burst 에 맞는 limit 을 잡아야 합니다.
requests 가 misleading 하다면
scheduling 과 runtime behavior 가 같이 말이 되도록 workload 에 맞게 조정해야 합니다.
backlog 로 시작한 incident 라면
pod 메모리 ceiling 뿐 아니라 backlog 원인도 함께 고쳐야 합니다.
장애 중에 던져볼 질문
이 질문이 꽤 유용합니다.
memory 가 계속 자라다가 죽은 건가, 아니면 정상 운영에서도 나올 수 있는 burst 가 잠깐 limit 을 넘긴 건가?
이 구분이 fix 방향을 거의 결정해 줍니다.
FAQ
Q. 그냥 limit 을 먼저 올리면 되나
undersizing, burst usage, retention 중 무엇인지 보기 전에는 권하지 않습니다.
Q. 가장 빠른 첫 단계는 무엇인가
OOM kill 여부를 확인하고, 실제 memory usage 와 current limit 을 비교하는 것입니다.
Q. 모든 OOMKilled 가 memory leak 인가
아닙니다. spike, backlog, limit undersizing 도 매우 흔합니다.
Q. requests 도 중요한가, limits 만 중요하지 않나
requests 는 placement 와 cluster behavior 에 영향을 주고, limits 는 kill threshold 를 만든다는 점에서 둘 다 중요합니다.
Read Next
- restart 증상이 memory pressure 보다 더 일반적이라면 Kubernetes CrashLoopBackOff 와 비교해 보세요.
- 컨테이너는 살아 있는데 ready 가 되지 않는다면 Kubernetes Readiness Probe Failed 를 이어서 보세요.
- 전체 인프라 글 흐름은 Infra 카테고리 에서 이어 볼 수 있습니다.
Related Posts
Sources:
심사 대기 중에는 광고 대신 관련 가이드를 먼저 보여줍니다.
먼저 읽어볼 가이드
검색 유입이 많은 핵심 글부터 이어서 보세요.
- 미들웨어 트러블슈팅 가이드: Redis vs RabbitMQ vs Kafka 개발자를 위한 미들웨어 트러블슈팅 허브 글입니다. Redis, RabbitMQ, Kafka 중 어떤 증상부터 먼저 봐야 하는지와 어떤 문제 패턴이 각 시스템에 가까운지 정리합니다.
- Kubernetes CrashLoopBackOff: 먼저 볼 것들 startup failure, probe, config, resource limit 관점에서 CrashLoopBackOff를 어떻게 나눠서 봐야 하는지 정리한 가이드입니다.
- Kafka consumer lag가 계속 늘 때: 트러블슈팅 가이드 Kafka consumer lag가 계속 늘어날 때 무엇부터 봐야 하는지 정리합니다. poll 주기, 처리 속도, rebalance, consumer 설정까지 실전 기준으로 다룹니다.
- Kafka Rebalancing Too Often 가이드 Kafka consumer group에서 rebalance가 너무 자주 일어날 때 membership flapping, poll timing, protocol, assignment churn을 어떤 순서로 봐야 하는지 설명하는 실전 가이드입니다.
- Docker container가 계속 재시작될 때: 먼저 확인할 것들 exit code, command failure, environment mistake, health check 관점에서 Docker restart loop를 푸는 실전 가이드입니다.
심사 대기 중에는 광고 대신 관련 가이드를 먼저 보여줍니다.