Incident Library
  • 원인
  • 구성 요소
  • 증상
  • 기여 요인
  • 사례

사례7건

7건 중 4~7번째

  1. 증상

    2023-09-18 13:42, 팀은 High-priority-alert 채널에서 RootVolUtilisation-Critical 알림을 봤다. 14:03 에는 한 사용자가 이미지 풀이 no space left on device 오류로 실패한다고 알렸다.

    촉발

    EKS 모듈을 버전 18 로 올리면서 런치 템플릿이 바뀌었고, 새 노드의 디스크가 100Gb 에서 20Gb 로 줄었다.

    원인
    구성 요소
    기여 요인
    감지

    13:42 에 High-priority-alert 채널로 RootVolUtilisation-Critical 알림이 왔다. 14:03 에 사용자가 이미지 풀 실패를 보고했고, 장애 선언은 15:12 였다.

    조치
    • 예전 기본 노드 그룹을 uncordon 하고, 새 노드를 drain 해 워크로드를 예전 노드 그룹으로 되돌렸다.
    • 루트 볼륨을 20Gb 로 줄인 런치 템플릿 변경을 찾아, manager 클러스터와 live 클러스터에 수정을 적용했다.
    • 예전 노드 그룹을 drain 해 워크로드를 수정한 노드로 옮겼다.
    후속 조치
    • EKS 모듈을 올릴 때 런치 템플릿 변경을 비교하는 절차를 런북에 넣는다.
    • live 클러스터처럼 크기가 다양한 이미지를 받아 보는 테스트 환경을 만든다.
    • RootVolUtilisation 알림 런북에 디스크 크기 설정을 확인하는 단계를 넣는다.
    • 노드 수에 따라 CoreDNS 를 자동으로 늘리고 줄인다.
    • IP 접두사 부족을 IPv6 로 풀 수 있는지 조사한다.
    • terraform plan 에서 런치 템플릿이 바뀌면 알아챌 수 있게 드리프트 테스트를 추가한다.
    • CNI 와 ipamd 로그를 볼 수 있게 로깅을 갖추고, IP 접두사 부족 오류가 나면 알림을 보낸다.
    교훈

    이 글은 교훈 대신 후속 조치를 적었다. 조치를 보면 팀에는 빈틈이 두 가지 있었다. 하나는 모듈 업그레이드가 바꾼 런치 템플릿을 배포 전에 비교하지도, 드리프트 테스트로 잡지도 않은 것이다. 다른 하나는 drain 중 팀이 의심한 IP 접두사 부족을 확인할 CNI 와 ipamd 로그도, 알림도 없었던 것이다.

  2. 증상

    2023년 2월 1일 leap 클러스터의 prod 허브에서 노드가 대량으로 늘었고, hub 파드가 알 수 없는 이유로 재시작됐다. 사용자 지원 티켓도 들어왔다.

    촉발

    한 사용자의 dask-gateway 작업이 1분 사이에 dask-worker 노드를 100대쯤 늘렸고, Prometheus 는 노드 200대쯤의 지표 내보내기 대상을 수집하기 시작했다.

    원인
    구성 요소
    기여 요인
    감지

    2i2c Freshdesk에 들어온 사용자 지원 티켓 414로 드러났다. 이후 엔지니어가 Grafana와 클러스터의 노드, event를 살폈다. 조사 내용은 같은 날 UTC+1 기준 저녁 8시에서 9시 사이에 이슈에 정리됐다.

    후속 조치
    • basehub에서 hub와 proxy 파드의 CPU와 메모리 요청을 넉넉히 설정한다. 이슈 #2127이다.
    • Grafana의 OOMKiller 대시보드가 제대로 동작하게 고친다. 이슈 #2213이다.
    • LEAP 클라우드 인프라를 공유 노드 구성으로 옮긴다. 이슈 #2209다.
    • ingress-nginx와 Prometheus의 리소스 요청과 한도를 고친다. Prometheus 서버는 메모리 요청을 한도와 같게 맞춘다. 이슈 #2324다.
    • Prometheus가 daskhub 워커 파드를 수집하도록 넣은 설정이 필요한지 다시 본다. 이슈 #2366이다.
    교훈

    Prometheus 서버처럼 메모리를 많이 쓰는 파드가 요청보다 훨씬 많이 쓰면 같은 노드의 중요한 파드가 축출된다. 노드가 한꺼번에 100대 늘면 Prometheus가 수집할 대상도 함께 늘어난다. hub와 proxy처럼 중요한 파드는 실제 사용량보다 요청을 넉넉히 잡아야 축출과 CPU 부족을 피할 수 있다. 쿠버네티스 event는 60분이 지나면 사라지므로, OOMKill 여부를 나중에 확인하려면 따로 기록해 두어야 한다.

  3. 증상

    2019년 7월 19일 금요일, Grafana Cloud 의 Hosted Prometheus 서비스가 장애를 겪었다. 오류 예산 기반 Prometheus 알림이 장애 시작 4분 안에 당직자를 호출했다.

    촉발

    7월 19일 한 엔지니어가 큰 고객을 위한 전용 Cortex 클러스터를 새로 띄웠다. 새 클러스터 설정에는 새로 도입한 파드 우선순위 지정이 없어서, 모든 파드가 기본값인 medium 우선순위를 받았다. 쿠버네티스 클러스터에는 새 Cortex 클러스터를 올릴 자원이 부족했다.

    원인
    구성 요소
    기여 요인
    감지

    새로 도입한 오류 예산 기반 Prometheus 알림이 장애 시작 4분 안에 당직자를 호출했다.

    조치
    • 쿠버네티스 클러스터를 늘려 새 Cortex 클러스터와 기존 운영 Cortex 클러스터가 모두 들어가게 했다.
    • Cortex 앞의 인증 리버스 프록시에서 난 OOM 을 찾아 고쳤다.
    후속 조치
    • 운영 Ingester 에 high 우선순위 지정을 반영했다.
    • 클러스터 전역 설정처럼 네임스페이스 밖에 있는 객체의 배포는 더 많은 사람이 리뷰한다.
    • 네임스페이스 밖 설정 변경에는 모두 설계 문서를 요구한다.
    • 인증 리버스 프록시의 규모 조정을 자동화해 과부하 때 OOM 이 나지 않게 한다.
    • 한꺼번에 몰려드는 재시도를 막으려고 Prometheus 의 기본 백오프와 확장 동작을 조사한다.
    교훈

    운영 Ingester 에 high 우선순위를 지정하기 전에 medium 을 기본 우선순위로 만들지 말았어야 했다. 운영 Ingester 의 high 지정도 더 일찍 배포했어야 했다. 팀은 이 변경이 설계 문서를 쓸 만큼 크지 않다고 보고 GitHub 이슈에서만 논의했다. 좋은 점도 있었다. Cortex 는 자원이 충분해지자 추가 조치 없이 스스로 회복했다. 팀은 새 로그 수집 시스템인 Grafana Loki 로 Ingester 가 정상적으로 종료됐는지 확인했다.

  4. 증상

    kubelet 변경을 클러스터 전체에 롤링 업데이트하던 중 kubelet 이 다시 올라오지 못했다. 쿠버네티스 API 는 노드가 죽었다고 판단했고 노드들이 NotReady 상태로 바뀌었다.

    촉발

    kubelet 변경을 롤링 업데이트로 배포했다. kubelet 은 재시작할 때 시작 전에 임시 cgroup 파일을 정리하는데, 이 과정에서 쿠버네티스 버그로 멈췄다. 이 업데이트가 한 클러스터의 노드 전체로 퍼졌다.

    원인
    구성 요소
    기여 요인
    감지

    업데이트 중 kubelet 이 올라오지 않으면서 노드가 NotReady 로 바뀌었고, 그래프에서 eviction 큐에 들어가 축출되는 노드 수가 늘어나는 것이 보였다.

    조치
    • 해당 데이터 센터에서 다음 데이터 센터로 페일오버해 사용자를 옮겼다.
    후속 조치
    • kubelet 업데이트를 적용한 뒤 테스트 프레임워크로 kubelet 을 검증하고, 검증이 끝나야 다음 30% 묶음의 업데이트로 넘어가게 했다.
    교훈

    kubelet 을 업그레이드한 뒤에는 반드시 테스트한다. kubelet API 에 간단한 curl 명령 하나만 보내 봐도 충분하다. 노드 컨트롤러는 노드의 50% 이상이 NotReady 가 되면 축출 속도를 늦추고, 노드가 모두 내려가면 full disruption 모드로 들어가 축출을 멈춘다. 이 동작 덕분에 이번 장애에서 파드의 절반이 살아남았다. 데이터 센터와 클러스터가 여럿이면 품질이 떨어진 데이터 센터에서 다른 데이터 센터로 페일오버해 사용자를 빠르게 옮길 수 있다.

내 클러스터에도 있는지 확인하기

이 7건에서 가장 많이 나오는 구성 요소: 노드 풀, AWS VPC CNI. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.

원인별4

용량 한계2건

조직
  1. IL-0099 메모리 상한 없이 8GB 만 보장한 프로필 때문에 워크숍 중 사용자 파드가 서로를 축출해 서버 시작이 15분을 넘고 커널이 죽었다.
    2i2c2025
  2. IL-0070 dask-gateway로 워커를 대량으로 띄우자 노드가 1분 만에 100대 늘었고, Prometheus가 메모리를 거의 다 쓰던 코어 노드에서 hub 파드를 비롯한 중요한 파드들이 축출되거나 재시작됐다
    2i2c2023

배포 결함1건

  1. IL-0020 EKS 1.30 업그레이드 중 디스케줄러가 cordon 된 노드의 파드를 한꺼번에 쫓아내 운영 서비스가 멈췄다

설정 변경3건

  1. IL-0114 클러스터 용량을 늘리던 중 버전이 고정되지 않은 VPC CNI 플러그인이 자동으로 업데이트돼 새 파드가 IP 를 받지 못하고 Pending 에 머물렀고, 메인넷 운영 환경의 정산이 약 3.5시간 멈췄다.
  2. IL-0019 EKS 모듈 18 업그레이드로 새 노드의 디스크가 20Gb 로 줄어 이미지 풀이 no space left on device 로 실패했다
  3. IL-0004 새 Cortex 클러스터에서 기본 우선순위를 받은 파드가 우선순위가 없는 운영 Ingester 를 연쇄적으로 선점해 Hosted Prometheus 쓰기가 실패했다

소프트웨어 결함1건

조직
  1. IL-0038 kubelet 설정 변경을 롤링 업데이트하다 쿠버네티스 버그로 kubelet 이 올라오지 못해 한 클러스터의 노드가 NotReady 가 되고 파드 절반쯤이 축출됐다
    Oath2018