Google Kubernetes Engine (GKE)의 개별 문제 해결 도구를 이해하는 것도 도움이 되지만, 실제 문제를 해결하기 위해 함께 사용되는 것을 보면 지식을 확실하게 다질 수 있습니다.
Google Cloud 콘솔, kubectl
명령줄 도구, Cloud Logging, Cloud Monitoring을 함께 사용하여 OutOfMemory
(OOMKilled
) 오류의 근본 원인을 식별하는 안내 예시를 따릅니다.
이 예는 이 시리즈에 설명된 문제 해결 기법의 실제 적용을 확인하려는 모든 사용자, 특히 플랫폼 관리자 및 운영자, 애플리케이션 개발자에게 유용합니다.Google Cloud 콘텐츠에서 참조하는 일반적인 역할과 예시 태스크에 대한 자세한 내용은 일반 GKE 사용자 역할 및 태스크를 참고하세요.
시나리오
GKE에서 실행되는 product-catalog
이라는 웹 앱의 당직 엔지니어입니다.
Cloud Monitoring에서 자동 알림을 받으면 조사가 시작됩니다.
Alert: High memory utilization for container 'product-catalog' in 'prod' cluster.
이 알림은 문제가 있음을 알려주고 문제와 product-catalog
워크로드 간에 관련성이 있음을 나타냅니다.
Google Cloud 콘솔에서 문제 확인
워크로드의 개략적인 보기를 통해 문제를 확인합니다.
- Google Cloud 콘솔에서 워크로드 페이지로 이동하여
product-catalog
워크로드를 필터링합니다. - 포드 상태 열을 확인합니다. 정상적인
3/3
대신 값이 비정상 상태를 꾸준히 보여줍니다(2/3
). 이 값은 앱의 포드 중 하나의 상태가Ready
이 아님을 나타냅니다. - 추가 조사를 위해
product-catalog
워크로드의 이름을 클릭하여 세부정보 페이지로 이동합니다. - 세부정보 페이지에서 관리 포드 섹션을 확인합니다. 문제를 즉시 파악합니다. 포드의
Restarts
열에 비정상적으로 높은 수치인14
이 표시됩니다.
다시 시작 횟수가 많다는 것은 이 문제로 인해 앱이 불안정해지고 컨테이너가 상태 점검에 실패하거나 비정상 종료된다는 것을 의미합니다.
kubectl
명령어로 이유 찾기
앱이 반복적으로 다시 시작된다는 것을 알았으므로 그 이유를 알아내야 합니다. kubectl describe
명령어가 이 작업에 적합한 도구입니다.
불안정한 포드의 정확한 이름을 가져옵니다.
kubectl get pods -n prod
출력은 다음과 같습니다.
NAME READY STATUS RESTARTS AGE product-catalog-d84857dcf-g7v2x 0/1 CrashLoopBackOff 14 25m product-catalog-d84857dcf-lq8m4 1/1 Running 0 2h30m product-catalog-d84857dcf-wz9p1 1/1 Running 0 2h30m
불안정한 포드를 설명하여 자세한 이벤트 기록을 가져옵니다.
kubectl describe pod product-catalog-d84857dcf-g7v2x -n prod
출력을 검토하고
Last State
및Events
섹션에서 단서를 찾습니다.Containers: product-catalog-api: ... State: Waiting Reason: CrashLoopBackOff Last State: Terminated Reason: OOMKilled Exit Code: 137 Started: Mon, 23 Jun 2025 10:50:15 -0700 Finished: Mon, 23 Jun 2025 10:54:58 -0700 Ready: False Restart Count: 14 ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 25m default-scheduler Successfully assigned prod/product-catalog-d84857dcf-g7v2x to gke-cs-cluster-default-pool-8b8a777f-224a Normal Pulled 8m (x14 over 25m) kubelet Container image "us-central1-docker.pkg.dev/my-project/product-catalog/api:v1.2" already present on machine Normal Created 8m (x14 over 25m) kubelet Created container product-catalog-api Normal Started 8m (x14 over 25m) kubelet Started container product-catalog-api Warning BackOff 3m (x68 over 22m) kubelet Back-off restarting failed container
출력에서 두 가지 중요한 단서를 확인할 수 있습니다.
- 먼저
Last State
섹션에는 컨테이너가Reason: OOMKilled
로 종료되었다고 표시되어 메모리가 부족했음을 알 수 있습니다. 이 이유는 과도한 메모리 사용으로 인해 종료된 프로세스의 표준 Linux 종료 코드인Exit Code: 137
에 의해 확인됩니다. - 두 번째로
Events
섹션에는 메시지Back-off restarting failed container
가 포함된Warning: BackOff
이벤트가 표시됩니다. 이 메시지는 컨테이너가 실패 루프에 있음을 확인해 주며, 이는 앞서 본CrashLoopBackOff
상태의 직접적인 원인입니다.
- 먼저
측정항목으로 동작 시각화
kubectl describe
명령어는 발생한 상황을 알려주지만 Cloud Monitoring은 시간 경과에 따른 환경의 동작을 보여줄 수 있습니다.
- Google Cloud 콘솔에서 측정항목 탐색기로 이동합니다.
container/memory/used_bytes
측정항목을 선택합니다.- 출력을 특정 클러스터, 네임스페이스, 포드 이름으로 필터링합니다.
차트에는 명확한 패턴이 표시됩니다. 메모리 사용량이 꾸준히 증가하다가 컨테이너가 OOM으로 종료되고 다시 시작되면 갑자기 0으로 떨어집니다. 이 시각적 증거는 메모리 누수 또는 메모리 제한 부족을 확인합니다.
로그에서 근본 원인 찾기
이제 컨테이너의 메모리가 부족하다는 것을 알지만 정확한 이유는 아직 알 수 없습니다. 근본 원인을 파악하려면 로그 탐색기를 사용하세요.
- Google Cloud 콘솔에서 로그 탐색기로 이동합니다.
마지막 비정상 종료 시간 (
kubectl describe
명령의 출력에 표시됨) 바로 전의 특정 컨테이너 로그를 필터링하는 쿼리를 작성합니다.resource.type="k8s_container" resource.labels.cluster_name="example-cluster" resource.labels.namespace_name="prod" resource.labels.pod_name="product-catalog-d84857dcf-g7v2x" timestamp >= "2025-06-23T17:50:00Z" timestamp < "2025-06-23T17:55:00Z"
로그에서 각 비정상 종료 직전에 반복되는 메시지 패턴을 확인할 수 있습니다.
{ "message": "Processing large image file product-image-large.jpg", "severity": "INFO" }, { "message": "WARN: Memory cache size now at 248MB, nearing limit.", "severity": "WARNING" }
이러한 로그 항목은 앱이 큰 이미지 파일을 메모리에 완전히 로드하여 처리하려고 시도하고 있으며, 결국 컨테이너의 메모리 한도가 소진됨을 나타냅니다.
발견 사항
이 두 도구를 함께 사용하면 문제에 대한 완전한 그림을 그릴 수 있습니다.
- 모니터링 알림을 통해 문제가 있음을 알렸습니다.
- Google Cloud 콘솔에 문제가 사용자에게 영향을 미치고 있음 (다시 시작)이 표시되었습니다.
kubectl
명령어는 다시 시작의 정확한 이유(OOMKilled
)를 지적했습니다.- 측정항목 탐색기에서 시간 경과에 따른 메모리 누수 패턴을 시각화했습니다.
- 로그 탐색기를 통해 메모리 문제를 일으키는 구체적인 동작이 확인되었습니다.
이제 솔루션을 구현할 준비가 되었습니다. 앱 코드를 최적화하여 큰 파일을 더 효율적으로 처리하거나, 단기 해결책으로 워크로드의 YAML 매니페스트에서 컨테이너의 메모리 제한 (특히 spec.containers.resources.limits.memory
값)을 늘릴 수 있습니다.
다음 단계
특정 문제 해결에 관한 조언은 GKE 문제 해결 가이드를 참고하세요.
문서에서 문제 해결 방법을 찾을 수 없으면 지원 받기를 참조하여 다음 주제에 대한 조언을 포함한 추가 도움을 요청하세요.
- Cloud Customer Care에 문의하여 지원 케이스를 엽니다.
- StackOverflow에서 질문하고
google-kubernetes-engine
태그를 사용하여 유사한 문제를 검색해 커뮤니티의 지원을 받습니다.#kubernetes-engine
Slack 채널에 가입하여 더 많은 커뮤니티 지원을 받을 수도 있습니다. - 공개 Issue Tracker를 사용하여 버그나 기능 요청을 엽니다.