Incident Library
적용된 필터 구성 요소쿠버네티스 API 서버증상서비스 중단모두 풀기검색어 없이 필터만 적용한 목록입니다. 최근 사례부터입니다.
추천 필터 검색하면 검색어에서 찾은 분류 값이 여기에 나옵니다.

그래프

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

사례9건

9건 중 6~9번째

  1. 증상

    Jetstack 은 europe-west1 에 있는 GKE 리전 클러스터의 마스터를 업그레이드하고 있었다. 이 개발 클러스터는 여러 팀이 낮 동안 앱을 시험하는 데 쓴다. GKE Terraform 파이프라인으로 업그레이드를 시작했는데, 마스터 업그레이드가 20분으로 잡아 둔 Terraform 타임아웃 안에 끝나지 않았다. GKE 콘솔에는 클러스터가 여전히 업그레이드 중으로 나왔다.

    촉발

    마스터 업그레이드 중 두 번째 마스터 인스턴스의 API 서버가 ca-registration PostStartHook 을 실행하면서 kube-system 의 extension-apiserver-authentication ConfigMap 을 갱신하려 했다. 이 요청은 설정해 둔 OPA 검증 웹훅의 백엔드가 응답하지 않아 타임아웃 났다.

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

    GKE Terraform 파이프라인으로 시작한 마스터 업그레이드가 20분으로 잡아 둔 Terraform 타임아웃 안에 끝나지 않은 것이 첫 신호였다. 파이프라인을 다시 돌리자 kube-apiserver 가 unhealthy 라는 오류가 났다. 원인은 Google Support 의 도움을 받아 찾았다.

    조치
    • API 서버에 간헐적으로 접근될 때를 이용해 OPA 의 ValidatingAdmissionWebhook 리소스를 지워 클러스터를 복구했다.
    후속 조치
    • OPA 의 ValidatingAdmissionWebhook 이 정책이 적용되고 개발 팀이 접근하는 네임스페이스만 보도록 범위를 좁혔다.
    • 웹훅을 정책이 실제로 검증하는 Ingress 와 Service 리소스에만 켰다.
    • OPA 가 응답하지 않으면 재시작되도록 liveness probe 를 더하고 문서를 고쳤다.
    • 이 동작을 개선하자는 쿠버네티스 업스트림 이슈가 아직 열려 있어, 그 진행을 지켜본다.
    교훈

    API 서버 응답 시간에 알림을 걸어 두었다면, OPA 웹훅을 처음 배포한 뒤 모든 CREATE 와 UPDATE 요청의 응답 시간이 늘어난 것을 알아챘을 수도 있다. 모든 워크로드에 프로브를 설정하는 것이 중요하다. 팀은 OPA 배포가 너무 간단해 보여서 Helm 차트를 쓰지 않았는데, 그 차트에는 어드미션 컨트롤러 컨테이너의 livenessProbe 를 포함해 튜토리얼 기본 설정에 없는 조정이 여럿 들어 있었다. 노드 자동 복구를 끄는 것도 검토했지만 끄지 않기로 했다. 같은 문제를 겪은 것은 Jetstack 이 처음이 아니며, 관련 업스트림 이슈는 아직 열려 있다.

  2. 증상

    2018년 12월 4일 아침 8시 회의 중 운영자가 NRE Labs의 일일 통계를 보다가 레슨 사용량이 떨어진 것을 알아챘다.

    촉발

    kubeadm이 etcd 정적 파드 매니페스트에 넣은 liveness probe가 실패하기 시작했다. 이 probe는 etcdctl로 foo 키를 조회한다. failureThreshold가 8, timeoutSeconds가 15라서 약 2분 동안 실패가 이어지면 kubelet이 etcd를 재시작한다. probe가 왜 실패하기 시작했는지는 끝내 밝히지 못했다.

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

    운영자가 아침 회의 중 NRE Labs 일일 통계를 보다가 레슨 사용량이 떨어진 것을 보고 알았다. 클러스터 모니터링은 갖추지 않은 상태였고, 원문은 모니터링이 우선순위에서 밀려 있었다고 적었다.

    조치
    • kubeadm이 만든 etcd 매니페스트에서 liveness probe 부분을 통째로 지우고, 다음 etcd 재시작 때 kubectl apply로 반영했다.
    후속 조치
    • 단일 마스터 클러스터에 모니터링을 갖춘다.
    • 장애가 나면 트위터를 보라고 안내하는 점검 페이지를 Google Cloud Functions에 만든다. 계획된 작업이든 아니든 일이 생기면 트래픽을 그 페이지로 돌린다.
    교훈

    모든 인프라를 코드로 관리한 덕에 클러스터를 금방 다시 만들 수 있었다. 하지만 원인을 모른 채 지우면 증거도 함께 사라진다. 단일 마스터로 운영한다면 모니터링이 더 중요하다. kubectl 출력에서 Running만 보지 말고 재시작 횟수까지 읽어야 한다. 복잡한 원인을 기대하기 전에 기본부터 의심하고, 장애의 급박함에 밀려 성급한 결정을 내리지 않는다. 사이트를 반쯤 망가진 채로 두지 말고 점검 페이지로 상황을 알려야 한다.

  3. 증상

    사용자가 파드가 떴다가 사라진다고 클러스터 운영 팀에 알렸다.

    촉발

    etcd 의 쓰기 지연이 크게 늘었다. 발표자는 정상인 etcd 의 쓰기 지연이 한 자릿수 밀리초이고, 데이터베이스 동기화 지연이 두 자릿수나 수백 밀리초를 넘으면 문제가 시작된다고 설명했다.

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

    팀은 사용자가 파드가 떴다가 사라진다고 알려 와서 장애를 알게 됐다. 팀이 kubectl 로 확인하자 같은 명령이 실행할 때마다 다른 결과를 냈다.

    조치
    • 새 클러스터를 만들어 애플리케이션을 다시 배포하고 서비스를 복구했다.
    • 볼륨을 옛 클러스터에서 하나씩 손으로 풀어 새 클러스터에서 바인딩했다.
    • 로드 밸런서를 쓰던 팀들이 DNS 레코드를 새 클러스터의 로드 밸런서 이름으로 손으로 바꿨다.
    후속 조치
    • API 서버가 etcd 에서 읽을 때 항상 쿼럼 읽기를 하도록 설정한다.
    교훈

    etcd 는 쿼럼 읽기를 요청하지 않으면 오래된 데이터로 응답할 수 있고, 이 동작은 문서에 적혀 있다. 쿠버네티스 1.9 부터는 쿼럼 읽기가 기본이므로, 그 전 버전을 쓰면서 API 서버 설정을 직접 관리한다면 설정을 확인해야 한다. 쿼럼 읽기는 성능 걱정 때문에 처음에는 권장되지 않았지만, etcd 3.1 에서는 읽기가 디스크를 거치지 않아 부담이 크게 줄었다. etcd 는 쓰기 지연에 매우 민감하므로 데이터베이스 동기화 지연을 지켜봐야 한다. 고가용성 문서처럼 계속 바뀌는 문서는 꾸준히 다시 읽어야 한다. 로드 밸런서 이름을 직접 가리키는 DNS 레코드와 한 노드에 묶이는 볼륨은 클러스터 교체를 느리게 만든다.

  4. 증상

    14:10 에 입출금 계좌 결제 처리에 필요한 서비스 하나를 배포하자 그 서비스로 가는 요청이 모두 실패했다. 이때부터 입출금 계좌 고객의 결제가 실패했다. 선불 카드는 이 서비스를 쓰지 않아 아직 영향이 없었다.

    촉발

    14:10 에 엔지니어가 입출금 계좌 결제 처리에 필요한 서비스에 변경을 배포했다. 2주 전 etcd 클러스터를 재구성한 뒤로 쿠버네티스와 etcd 클라이언트 버그가 요청 타임아웃을 낼 수 있는 상태였고, 이 때문에 linkerd 는 배포 뒤 새 파드의 위치를 받지 못했다.

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

    14:10 배포 직후 그 서비스로 가는 요청이 모두 실패했고 입출금 계좌 결제가 실패하기 시작했다. 14:12 롤백 뒤에도 오류가 계속되자 14:16 에 내부적으로 장애를 선언했다. 15:13 에 플랫폼 전체가 멈추자 자동 알림이 거의 모두 울렸다.

    조치
    • 14:12 에 배포한 변경을 롤백했지만 오류는 계속됐다.
    • 고객 영향을 줄이려고 장애 때 쓰는 내부 백업 절차를 가동해 대부분의 고객이 계속 카드를 쓸 수 있게 했다.
    • 14:26 에 linkerd 인스턴스 수백 개를 모두 재시작하기 시작했고, 이 조치가 장애를 키웠다.
    • 14:37 에 kubelet 이 apiserver 에서 설정을 받지 못하자 apiserver 프로세스 세 개를 재시작했다.
    • 15:27 에 플랫폼 팀이 새 linkerd 버전을 배포하기 시작했다. 이 버전에는 비호환 문제를 고친 코드가 들어 있었고, 스테이징에서 몇 주째 시험하던 버전이었다.
    • 15:31 에 엔드포인트가 없는 쿠버네티스 서비스를 지워 linkerd 가 서비스 디스커버리 정보를 읽게 했고, 플랫폼이 회복했다.
    후속 조치
    • 클러스터 재구성 뒤 타임아웃을 일으킬 수 있는 쿠버네티스 버그를 고친다.
    • 파싱 오류를 고친 새 linkerd 버전을 배포한다.
    • 영향을 받은 구성 요소에 더 나은 헬스 체크, 대시보드, 알림을 만들어 무엇이 잘못됐는지 더 분명한 신호를 주고 사람의 실수를 막는다.
    • 장애를 내부와 외부에 더 분명하고 빠르게 알리도록 절차를 개선한다.
    교훈

    분산 시스템의 대규모 장애는 이해하기 매우 어렵고, 사람이 좋은 뜻으로 한 조치가 오히려 문제를 키울 수 있다. 이번에는 linkerd 를 모두 재시작한 결정이 또 다른 버전 비호환 문제를 드러내 장애를 더 키웠다. 배포가 잦고 노드와 애플리케이션 장애에 자동으로 대응하는 백엔드에서는 네트워크가 매우 동적이다. 그래서 배포와 요청 라우팅 시스템을 믿을 수 있는 것이 무엇보다 중요하다. Monzo 는 인터페이스를 바꿀 때 앞뒤 버전과 호환되게 해서 롤백을 안전하게 할 수 있게 해 두었지만, 이번에는 롤백한 뒤에도 오류가 계속됐다.

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

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

원인별6

소프트웨어 결함3건

  1. IL-0138 nvidia-dkms-390 드라이버 빌드 실패로 망가진 커널 헤더가 몇 주 동안 방치됐다가, 정전 뒤 재부팅하자 하나뿐인 마스터 노드가 커널 패닉에 빠져 홈랩 쿠버네티스 클러스터가 6일 동안 멈췄다.
  2. IL-0072 etcd 쓰기 지연으로 API 서버가 오래된 데이터를 읽어 클러스터 상태가 두 가지로 번갈아 보였고, 주 운영 클러스터 전체가 약 4시간 멈췄다
  3. IL-0003 etcd 클러스터 재구성 뒤 쿠버네티스 버그로 linkerd 가 서비스 위치 갱신을 받지 못했고, linkerd 를 모두 재시작하자 엔드포인트가 없는 서비스를 파싱하지 못하는 오류가 드러나 플랫폼 전체가 멈췄다
    Monzo2017

설정 변경2건

  1. IL-0005 새 텔레메트리 서비스가 모든 노드에서 무거운 쿠버네티스 API 요청을 보내 대형 클러스터의 컨트롤 플레인이 무너졌고, DNS 기반 서비스 디스커버리가 깨져 OpenAI 의 모든 서비스가 멈췄다
    OpenAI2024
  2. IL-0008 응답하지 않는 OPA 검증 웹훅 때문에 GKE 마스터 업그레이드가 멈추고 API 서버가 간헐적으로 끊기면서 노드가 끝없이 재생성됐다

클라우드 제공자 장애1건

조직
  1. IL-0084 베어메탈 업체 vSwitch 의 패킷 드롭으로 Namespace 의 fra3 리전이 빠져 전 세계 용량이 모자랐고, 다음 날에는 컨트롤 플레인 노드의 느린 NVMe 쓰기로 쿠버네티스 API 서버 CPU 가 치솟아 zrh1 이 멈췄다.

업그레이드로 깨진 호환성1건

조직
  1. IL-0060 쿠버네티스 1.24 업그레이드로 node-role.kubernetes.io/master 레이블이 사라지자 이 레이블에 기대던 Calico 라우트 리플렉터가 동작을 멈춰 레거시 클러스터의 네트워크가 모두 끊기고 Reddit 이 314분 동안 멈췄다
    Reddit2023

인증서·자격 증명 만료1건

  1. IL-0113 한 번도 교체되지 않은 GKE API 서버 인증서 때문에 메인 클러스터의 컨트롤 플레인이 망가져 EU 리전의 백엔드 API, 프런트엔드, 터널이 모두 멈췄다

unknown1건

조직
  1. IL-0059 kubeadm이 만든 etcd 정적 파드의 liveness probe가 실패해 kubelet이 약 2분마다 etcd를 재시작했고, 단일 마스터 클러스터의 API 서버가 계속 끊겼다