Incident Library

IL-0467 Kubernetes project · 2019-03-26kubernetesgcp

Prow 빌드 클러스터의 노드 업그레이드 중 Boskos 파드가 크래시 루프에 빠져 GCP 프로젝트가 필요한 테스트 작업이 9시간 넘게 모두 실패했다

Boskos 는 테스트 작업에 GCP 프로젝트를 나눠 주는 서비스이고, StatefulSet 이 띄운 파드 하나로 돌았다. 지난해 12월에 들어간 커밋에 Boskos 가 시작하지 못하게 만드는 버그가 있었다. 아무도 이 버전을 배포하지 않다가 2019-03-20 에 처음 배포를 시도했다. StatefulSet 스펙은 새 이미지로 바뀌었지만 파드를 교체하게 하는 설정이 없었다. 그래서 파드는 옛 이미지 gcr.io/k8s-testimages/boskos:v20180405-12e892d69 로 계속 돌았고, 아무것도 바뀌지 않았다는 사실을 아무도 알아채지 못했다.

장애 당일 오후 5시가 넘어 Prow 클러스터를 1.11 에서 1.13 으로 올리기 시작했다. 빌드 클러스터는 노드가 150개이고 노드 하나에 5분이 걸려서, 전체가 10시간쯤 걸리는 작업이었다. 그런데 당직자가 대응하는 시간은 오후 6시까지였다. 몇 시간 동안 이상이 없어 팀은 잠자리에 들었다. 23:04 PDT 에 Boskos 파드가 돌던 노드가 drain 됐다. 새 노드에서 다시 만들어진 파드는 StatefulSet 스펙에 적힌 버그 있는 이미지로 떴고, CRD 클라이언트를 만들지 못해 크래시 루프에 빠졌다. 그 뒤로 Boskos 에서 프로젝트를 받아야 하는 작업은 모두 실패했다.

사용자들이 GitHub 와 Slack 으로 알렸지만 아침까지 아무도 대응하지 못했다. 07:16 에 담당자가 Slack 의 보고를 보았고, 07:37 에 원인 커밋을 찾았다. 고친 이미지를 빌드해 배포하자 Boskos 는 곧바로 살아났고, 08:10 에 장애가 끝났다. 장애는 9시간을 조금 넘게 이어졌고, pull-kubernetes-e2e-gce 에서만 실패가 70번 났다. 감사 로그를 보니 파드는 StatefulSet 이 바뀐 뒤에도 전날까지 옛 이미지로 돌고 있었다. 지난주에 업데이트를 시도했을 때도 아무 일도 일어나지 않았다.

심각도
–
영향 범위
All Prow test jobs that needed a GCP project from Boskos failed for just over nine hours, including the required pull-kubernetes-e2e-gce job, so no kubernetes/kubernetes pull request could be merged; 70 failures on pull-kubernetes-e2e-gce alone, with similar effects on other projects
영향 사용자
Contributors to kubernetes/kubernetes and other projects whose test jobs used Boskos
지역
–
감지까지
3h 46m
복구까지
9h 6m

증상

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

e2e-gce 작업마다 "Something went wrong: failed to prepare test environment: --provider=gce boskos failed to acquire project: Post http://boskos.test-pods.svc.cluster.local./acquire?type=gce-project&state=free&dest=busy&owner=pull-kubernetes-e2e-gce" 오류가 났다. 같은 요청은 "dial tcp 10.63.250.132:80: i/o timeout" 로 끝났다.

Boskos 파드는 시작하자마자 다음 로그를 남기고 죽기를 되풀이했다. {"error":"CustomResourceDefinition.apiextensions.k8s.io \"resources.boskos.k8s.io\" is invalid: [spec.versions: Invalid value: []apiextensions.CustomResourceDefinitionVersion(nil): must have exactly one version marked as storage version, status.storedVersions: Invalid value: []string(nil): must have at least one stored version]","level":"fatal","msg":"unable to create a CRD client","time":"2019-03-26T09:44:13Z"}

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

처음에는 다른 원인을 의심했다. 한 엔지니어는 최근의 snowflake ID 변경과 관계가 있는지 물었지만 그 변경은 아직 하지 않은 상태였다. 담당자는 전날 저녁의 쿠버네티스 업그레이드를 의심했지만 시각이 맞지 않았고, 1.11 과 1.13 사이에 잘못된 CRD 를 다루는 방식이 바뀌었는지도 따져 보았다. 그러나 Boskos 가 만들려던 CRD 는 어느 버전에서도 유효하지 않았다. 07:37 에 원인이 된 커밋을 찾았다.

증상 컨테이너 재시작 반복서비스 중단

원인

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

감지

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

조치

후속 조치

교훈

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

출처

참고 문서

관련 사례

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

kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이 사례와 같은 상태를 점검합니다. 이 사례의 구성 요소: CI 시스템, 노드 풀. 점검 항목의 근거는 이 사례 같은 공개 보고서입니다.

AI 도구와 스크립트용

API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.