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

사례10건

10건 중 6~10번째

  1. 증상

    2019년 6월 11일, Zalando 가 직접 만들어 운영하는 CI/CD 플랫폼인 CDP 의 빌드가 한 시간 가까이 타임아웃으로 실패했다.

    촉발

    CDP 쿠버네티스 클러스터의 규모가 조정되면서 공교롭게도 빌더 파드가 쓸 수 있는 노드가 한 대만 남았다. 그 노드에서 파드가 빠르게 생성되고 삭제되자 kubelet 이 따라가지 못했다.

    원인
    구성 요소
    기여 요인
    조치
    • 클러스터를 수동으로 늘려 빌더 파드가 노드 한 대가 아니라 여러 대에 흩어지게 했다.
    후속 조치
    • 전역 클러스터 설정으로 kubelet QPS 를 기본값 5 에서 50 으로 올렸다.
  2. 증상

    2019년 5월 30일 13:26 PDT 에 Slack 으로 Prow 가 이상하다는 신고가 들어왔다. GitHub 에는 잡이 실패했다고 올라왔는데 Deck 에서는 같은 잡이 아직 실행 중으로 보였다. 많은 테스트가 뜻밖의 방식으로 실패하거나 실행 도중 뚜렷한 이유 없이 중단됐다.

    촉발

    Kubernetes 1.15 code freeze 를 앞두고 테스트 사용량이 치솟아, k8s-prow-build 클러스터 노드의 디스크 I/O 가 GCP 의 스로틀링 한도에 걸렸다.

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

    여러 사용자가 GitHub 에는 실패로 올라왔지만 잡 상태로는 아직 실행 중인 잡이 있다고 신고했다. 첫 신고는 13:26 에 Slack 으로 들어왔다. 이런 장애를 잡는 알림은 없거나 동작하지 않았다.

    조치
    • 디스크 quota 를 더 요청해 15:14 에 받았다.
    • 17:10 에 500 GB 디스크 노드 55개를 띄웠다.
    • 23:55 에 새 노드 풀로 옮기는 일을 마쳐 모든 노드가 500 GB 디스크를 쓰게 됐다.
    후속 조치
    • tide 가 일을 멈추면 온콜 담당자가 호출을 받도록 모니터링을 만들거나 고친다. 이 일은 이슈 #12829 에서 다룬다.
    • 온콜 순번에 새 사람을 넣는 절차와 지침을 만들어, 새 사람이 준비나 추가 지원 없이 혼자 맡겨지지 않게 한다.
    교훈

    사고 전에 Prow 지표가 기록되지 않아 무슨 일인지 파악하기 어려웠다. 이런 장애를 잡는 알림은 없거나 동작하지 않았다. 원인을 찾고 해결책을 정한 뒤에도 두 시간 동안 아무것도 하지 않았다. 사고로 1.15 code freeze 가 밀렸다. IOPS 가 문제라는 것을 알아본 사람이 마침 자리에 있었던 것은 운이었다.

  3. 증상

    Terraform 이 아시아 운영 GKE 클러스터를 지웠다. 사내 서비스 디스커버리가 사라진 클러스터에 닿지 못하자 클러스터 운영 팀이 호출을 받았다.

    촉발

    클러스터 운영 팀이 아시아 클러스터를 Terraform 상태 파일로 가져오는 PR 을 올렸고, 그 리뷰 빌드가 운영에 쓰이는 전역 상태 파일을 바꿨다. 그런데 이 PR 보다 클러스터 사용자의 PR 이 먼저 머지됐고, 그 PR 에는 아시아 클러스터 정의가 없었다. Terraform 은 정의에 없는 아시아 클러스터를 삭제했다.

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

    사내 서비스 디스커버리가 사라진 클러스터에 닿지 못하자 클러스터 운영 팀이 호출을 받았다.

    조치
    • 서비스 디스커버리 설정에서 사라진 클러스터를 빼고 사내 서비스 디스커버리를 재시작해 파드 IP 를 백엔드 목록에서 지웠고, 트래픽을 쿠버네티스 밖 인스턴스로 넘겼다.
    • 쿠버네티스와 VM 에 반씩 나눠 돌던 한 팀이 부하를 받으려고 쿠버네티스 밖 VM 을 더 만들었다.
    • 미리 복원을 시험해 둔 클러스터 백업으로 삭제된 클러스터를 다시 만들었다.
    • 옛 클러스터 마스터 IP 를 하드코딩한 곳을 찾아 모두 새 값으로 고쳤다.
    후속 조치
    • 드라이런 결과를 PR 댓글로 달아 무엇이 바뀔지 바로 보이게 했다.
    • 머지 전에 브랜치가 최신 master 를 반영해야 하는 필수 상태 검사를 켜서, 드라이런이 실제로 일어날 일을 보여 주게 했다.
    • PR 머지에 승인 리뷰를 필수로 했다.
    • destroy 같은 키워드가 보이면 리뷰를 바로 실패시키고, 클러스터 삭제는 이 저장소 밖에서 손으로 하게 했다.
    • 클러스터 설정을 린터와 검증기로 검사하게 했다.
    • 일정을 미리 잡아 널리 알린 뒤, 클러스터가 사라지는 경우와 그보다 작은 실패를 다루는 재해 복구 훈련을 했다.
    교훈

    Terraform 은 상태 파일을 보고 할 일을 정한다. 리뷰 빌드가 운영 상태 파일을 바꾸게 두면 머지 순서 하나로 운영 리소스가 지워질 수 있다. 같은 리소스도 API 를 호출하는 권한에 따라 다른 속성으로 보이므로, 가져올 때와 관리할 때 권한이 다르면 Terraform 이 그 차이를 변경으로 읽는다. 처음부터 실패에 대비하고, 큰 인프라를 서서히 옮기고, 되돌릴 방법을 남겨 둔 덕분에 운영 클러스터 두 개가 사라져도 최종 사용자 영향이 없었다. 복원을 시험해 보지 않은 백업은 백업이 아니다. 실수를 누가 했는지보다 무엇을 배웠고 같은 종류의 실수를 어떻게 막을지가 중요하다.

  4. 증상

    Boskos 에서 GCP 프로젝트를 받아야 하는 Prow 테스트 작업이 밤사이 전부 실패했다. kubernetes/kubernetes 의 모든 PR 에 필수인 pull-kubernetes-e2e-gce 가 계속 실패해서 PR 을 하나도 병합할 수 없었다.

    촉발

    Prow 클러스터를 쿠버네티스 1.11 에서 1.13 으로 올리는 노드 업그레이드 중 23:04 에 Boskos 파드 하나가 돌던 노드가 drain 됐다. 새 노드에서 다시 만들어진 Boskos 파드는 StatefulSet 스펙에 적힌 새 이미지로 시작했는데, 이 이미지에 버그가 있었다.

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

    알림은 울리지 않았다. Boskos 대시보드에는 실패가 뚜렷하게 보였지만 이를 잡는 알림이 없었다. 사용자들이 02:50 에 GitHub 로, 05:16 과 06:27 에 Slack 으로 장애를 알렸고, 담당자는 07:16 에 일어나 Slack 의 보고를 보고서야 알았다.

    조치
    • 버그를 찾은 뒤 고친 Boskos 이미지를 새로 빌드해 배포했고, Boskos 는 곧바로 살아났다.
    • 장애 동안 반납되지 않고 열린 채로 남은 GCP 프로젝트들을 그 뒤 몇 분에 걸쳐 정리했다.
    후속 조치
    • Boskos 설정을 고쳐 배포하면 실제로 파드가 교체되게 한다.
    • Boskos 배포를 자동화한다.
    • Boskos 상태를 지켜보는 알림을 개선한다.
    교훈

    팀은 당직자가 오후 6시까지만 있는 날 오후 5시가 넘어 10시간짜리 배포를 시작하지 말았어야 했다고 보았다. 배포는 실제로 무언가가 바뀌었는지 확인할 수 있게 지켜봐야 하고, 그럴 수 없으면 아예 하지 않아야 한다고 정리했다. Boskos 의 StatefulSet 은 업데이트하도록 설정되어 있지 않아서 배포해도 아무것도 바뀌지 않았다. 12월의 변경은 한 번도 시험되지 않은 것으로 보였다. Prow 의 다른 부분과 달리 Boskos 는 손으로 배포해서 실수할 여지가 컸다. 담당자가 대응을 시작한 뒤로는 문제를 비교적 빨리 풀었다.

  5. 증상

    16:04 PST 에 Prow 의 응답이 매우 느려졌다. hook 의 응답이 5분쯤 늦었고 봇 명령이 응답하지 않았으며, /lgtm 과 담당자 지정이 오류를 냈다. 작업은 네트워크 문제로 실패하고 GCS 에 로그를 올리지 못했다.

    촉발

    13:20 PST 에 Prow 가 자동으로 만든 버전 올림 PR 이 머지돼 배포가 시작됐다. 새로 들어간 클라이언트 코드 리팩터링이 빌드 클러스터 시크릿에 적힌 "default" 클러스터 별칭을 무시해, Prow 가 작업을 기본 별칭인 서비스 클러스터에 스케줄하기 시작했다.

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

    16:04 PST 에 담당자가 PR 을 보다가 cat 명령이 동작하지 않는 것을 알아챘다. githubstatus.com 은 정상이었다. Slack 에서 Prow 노드가 CPU 와 메모리를 100% 넘게 쓰는 것을 찾았고, 이어서 test-pods 네임스페이스에서 시크릿을 찾지 못해 멈춘 Pending 파드 600개를 확인했다.

    조치
    • 16:40 에 Prow 를 버전 올림 이전인 v20190206-b01b288 로 롤백했고, 그사이 서비스 클러스터의 파드와 prowjob 을 모두 지웠다.
    • 직접 배포할 권한이 없어 이슈를 연 뒤, 16:50 에 되돌린 버전을 kubectl apply 로 직접 배포했다. 문제는 계속됐다.
    • 17:25 에 주어진 "default" 클라이언트를 덮어쓰지 않게 하는 수정 PR https://github.com/kubernetes/test-infra/pull/11209 을 올렸다.
    • 17:25 에 결함이 들어가기 전인 v20190125-2aca69d 로 Prow 를 다시 롤백했다.
    • 17:59 에 잘못 스케줄된 파드와 prowjob 을 모두 다시 지우고 Prow 가 정상임을 확인했다.
    후속 조치
    • 이 동작이 왜 비결정적으로 나타나는지 더 알아본다.
    • Prow 를 크게 바꾸는 변경을 배포할 때 더 조심한다. e2e 테스트를 늘리거나 실제 스테이징 Prow 를 둔다.
    교훈

    사람들이 자리에 있어 문제를 적극적으로 찾고 완화했다. 이번에도 금요일 오후에 일어났고, 동작이 비결정적이었다. 실제 스테이징 Prow 가 필요하다. 지금은 OpenShift 의 Prow 가 잘 돌면 쿠버네티스 Prow 를 올려도 안전하다고 보며 서로에게 기댄다. 그러나 빌드 클러스터를 정의하는 방식처럼 Prow 마다 구성이 다르므로, 쿠버네티스 Prow 와 매우 비슷한 스테이징 환경이 있어야 한다. 크게 바꾸는 Prow 변경은 e2e 테스트를 늘리거나 실제 스테이징 Prow 를 두어 더 조심해서 배포해야 한다.

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

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

원인별4

용량 한계3건

  1. IL-0471 GitHub Actions 워크플로 실행이 대량으로 실패하거나 큐에서 오래 기다렸다
    GitHub2026
  2. IL-0002 빌더 파드가 노드 한 대에 몰리자 kubelet 이 기본 API QPS 한도에 막혀 파드 상태를 늦게 갱신했고, CI 빌드가 AWS IAM 자격 증명을 받지 못해 실패했다
  3. IL-0401 Kubernetes 프로젝트의 Prow 빌드 클러스터 노드가 GCP 디스크 IOPS 스로틀링에 걸려 테스트가 이상하게 실패하고 PR 머지가 몇 시간 멈췄다

배포 결함4건

  1. IL-0234 내부 배포 자동화가 개발용 애플리케이션을 고객의 Managed Kubernetes 클러스터들에 잘못 설치해 컨트롤 플레인 연결과 쿠버네티스 기능에 문제가 났다
  2. IL-0324 External Storage 데이터베이스 클러스터에 과부하가 걸려 mw-api-int, mw-parsoid, mw-jobrunner 의 지연과 데이터베이스 오류가 늘었다
  3. IL-0467 Prow 빌드 클러스터의 노드 업그레이드 중 Boskos 파드가 크래시 루프에 빠져 GCP 프로젝트가 필요한 테스트 작업이 9시간 넘게 모두 실패했다
  4. IL-0466 Prow 가 테스트 작업을 서비스 클러스터에 스케줄해 작업이 뜨지 못하고 Prow 전체가 느려졌다

운영 실수2건

  1. IL-0244 EKS 서브넷의 라우팅 테이블 연결이 사라져 live 클러스터의 Cloud Platform 서비스에 접근할 수 없었다
  2. IL-0018 DockerHub 비밀번호를 바꾼 뒤 Concourse 와 EKS 클러스터 노드가 Docker Hub 에서 이미지를 받지 못했다

설정 변경1건

조직
  1. IL-0061 Terraform 상태 파일이 리뷰 빌드에서 바뀐 데다 권한 차이까지 겹쳐 Terraform 이 운영 GKE 클러스터 세 개 중 두 개를 삭제했다