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

그래프

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

사례9건

9건 중 4~8번째

  1. 증상

    2023년 3월 14일 19시 UTC 직후 엔지니어가 Old Reddit 이라 불리는 레거시 스택을 돌리는 클러스터의 업그레이드를 시작했다. 2분쯤은 괜찮아 보였지만 곧 사이트 전체가 갑자기 멈췄다. CDN 엣지의 상태 코드별 RPS 그래프가 이를 보여 주었다. 사용자는 오류 페이지나 글이 하나도 없는 홈페이지를 보았다.

    촉발

    Reddit 에서 가장 중요한 클러스터 가운데 하나인 레거시 클러스터를 쿠버네티스 1.23 에서 1.24 로 업그레이드했다.

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

    업그레이드를 시작하고 2분쯤 뒤 CDN 엣지의 상태 코드별 RPS 그래프에서 사이트가 멈춘 것이 보였다. 팀은 곧바로 장애를 선언했고 3분 안에 대응 인원이 통화에 모였다. 엣지 지표는 일부러 클러스터와 분리되어 있어 살아 있었지만, 클러스터 자체의 지표는 모두 사라졌다.

    조치
    • API 서버에서 타임아웃을 내던 Open Policy Agent 의 웹훅 설정을 지웠다.
    • 복원 뒤 어차피 쓸 수 없게 될 워커 노드를 모두 종료했다.
    • 컨트롤 플레인 노드 두 대를 종료하고, 남은 한 대의 구성 요소를 다운그레이드한 뒤 그 노드에 백업 데이터를 복원했다.
    • 단일 노드 컨트롤 플레인이 부하에 무너지지 않도록 클러스터 오토스케일러를 껐다.
    • 새 컨트롤 플레인 노드를 띄우고, 호스트명이 맞지 않던 TLS 인증서를 새로 만들어 노드들을 합류시켰다.
    • 트래픽을 1% 에서 시작해 5%, 10%, 20%, 35%, 55%, 80%, 100% 로 조금씩 늘렸다.
    • 트래픽이 돌아올 때 문제를 일으키지 않도록 손으로 멈춰 두었던 민감한 레거시 서비스를 조심스럽게 다시 켰다.
    후속 조치
    • 클러스터 구성을 코드로 관리해 모든 선택에 기록이 남게 하고, 코드로 만들 수 없는 것은 자세히 문서로 남긴다.
    • 클러스터마다 다른 맞춤형 구성을 걷어 내고 모든 클러스터의 구성 요소를 표준화한다.
    • 모든 클러스터를 최대한 같은 모습으로 유지하고 필요하면 다시 만들거나 복제할 수 있도록 클러스터 전체의 수명 주기를 관리하는 도구를 만든다.
    • 믿고 테스트에 쓸 수 있는 프리프로덕션 클러스터를 더 둔다.
    • 백업 복원 절차를 개선하고 클러스터 업그레이드를 안전하게 만든다.
    교훈

    쿠버네티스 버전과 구성 요소 업그레이드는 여전히 위험하다. 미리 테스트하고 검증해도 이번처럼 처음 보는 방식으로 깨질 수 있다. 쿠버네티스에는 공식 다운그레이드 절차가 없어, 롤백하는 방법은 백업에서 복원하는 것뿐이다. 복원 절차가 환경 변화를 따라가지 못하면 실제 장애 때 그 자리에서 고쳐 써야 하고, 복원을 결정하기까지 오래 망설이게 된다. 이번 복원은 결국 성공했지만 절차는 개선해야 한다. 코드로 남기지 않은 설정은 아는 사람이 떠나면 아무 기록도 남지 않는다. 라우트 리플렉터 설정이 어디에도 커밋되어 있지 않아 장애 중에 누구도 의심하지 못했다. 지표가 클러스터 안에서만 수집되면 클러스터가 망가질 때 함께 사라진다. 이번에는 로그 수집 에이전트가 영향을 받지 않아 원인을 추적할 수 있었다. 클러스터마다 다른 맞춤형 구성이 쌓이면 장애가 잦아진다. 직접 원인은 노드 레이블이었지만 근본 원인은 일관성 부족이었다.

  2. 증상

    2020-11-04 14:41 CET 에 사용자들이 쿠버네티스 클러스터 Hellman 에 배포할 때 타임아웃이 난다고 알려 왔다.

    촉발

    Alcide 워크숍 중 13:13 CET 에 운영 클러스터에 Alcide admission 컨트롤러를 적용했다. 팀은 이미 있던 것을 다시 적용하는 일이라 영향이 없을 거라고 여겼다.

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

    팀은 적용 1시간 28분 뒤인 14:41 CET 에 사용자들이 Hellman 에 배포할 때 타임아웃이 난다고 알려 와서 문제를 알았다. 이어 15:04 에 타임아웃을 확인했다.

    조치
    • Alcide admission 컨트롤러를 껐다 켜 보며 이 컨트롤러가 원인인지 확인했다.
    • Alcide admission 컨트롤러를 영구히 지웠다.
    후속 조치
    • 쿠버네티스 Deployment 의 타임아웃을 모니터링한다.
    • kube-apiserver 의 5xx 응답 코드를 모니터링한다.
    교훈

    새로 들이는 구성 요소는 샌드박스 클러스터에 적용한다. Alcide 를 완전히 걷어낼 때까지 팀은 이를 유지할 수 있는 지식을 갖춰야 한다.

  3. 증상

    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 이 처음이 아니며, 관련 업스트림 이슈는 아직 열려 있다.

  4. 증상

    스크립트 실행 기반을 쿠버네티스로 옮긴 Croquet 를 사내에 공개한 뒤, 개발자들은 kubectl 명령이 느리다고 했다. 사용자들은 노트북과 서비스가 가끔 시작되지 않는다고 알렸다.

    촉발

    자체 인프라 Bocce 에서 쿠버네티스로 옮긴 스크립트 실행 기반 Croquet 를 2018년 9월 사내에 공개했다. 대량의 스크립트가 몰리면서 클러스터가 EC2 인스턴스 약 290대로 커졌고, 노드마다 도는 Datadog 에이전트가 쿠버네티스 API 를 폴링하는 부하도 함께 늘었다.

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

    개발자들이 kubectl 명령이 느리다고 했고, 사용자들은 노트북과 서비스가 가끔 시작되지 않는다고 알렸다. 마스터 노드의 CPU 사용률이 높았고, 조사해 보니 API 서버 컨테이너 세 개가 CPU 를 꽉 채워 쓰고 있었다. 당시 팀이 볼 수 있던 지표는 마스터 노드 CPU 의 CloudWatch 지표와 Datadog 의 컨테이너별 CPU, 메모리 지표였다. API 요청 처리량과 5xx 오류율과 요청 지연은 볼 수 없었다.

    조치
    • 사내 사용자들을 예전 인프라로 되돌려 클러스터를 안정시켰다.
    • 마스터 노드를 m4.large 세 대에서 m4.4xlarge 세 대로 키웠다.
    • 노드마다 도는 Datadog 에이전트가 서비스 메타데이터를 얻으려고 API 서버를 폴링하지 않도록 Datadog 설정을 바꿨다.
    • 상태를 바꾸지 않는 요청의 max-requests-inflight 한도를 400 에서 1200 으로 올렸다.
    • etcd 의 EBS 볼륨을 20 GB 에서 100 GB 로 늘려 IOPS 를 100 에서 300 으로 올렸다.
    • 스크립트의 DNS 정책을 ClusterFirst 에서 Default 로 바꿔 DNS 타임아웃을 줄였다.
    후속 조치
    • Kops 가 안전한 이전을 지원하면 etcd 를 2.2.1 에서 3.x 로 올린다.
    • 스크립트가 클러스터 안의 다른 워크로드와 통신할 수 있도록 DNS 타임아웃 문제를 근본적으로 해결한다.
    교훈

    가장 큰 실수는 쿠버네티스가 모든 것을 알아서 해 준다고 가정한 것이었다. 쿠버네티스는 노드 5,000대와 파드 100,000개를 지원한다고 하지만, 그 규모에 이르려면 손봐야 할 설정이 많다. 클러스터에 넣는 서드파티 도구, 특히 DaemonSet 을 조심해야 한다. 많은 도구가 보통 규모에 맞춰 만들어졌고 큰 규모에서는 시험되지 않았다. 클러스터 상태를 watch 하는 서비스가 데이터를 지나치게 많이 가져가도록 설계되면 규모 문제가 생긴다. kube2iam 은 모든 파드의 메타데이터를 메모리에 들고 있다가 메모리가 바닥났고, Fluentd Kubernetes Metadata Filter 플러그인도 같은 문제가 있다. 대개 설정 하나로 고칠 수 있지만, 부하 테스트를 해 보기 전에는 잘 드러나지 않는다.

  5. 증상

    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만 보지 말고 재시작 횟수까지 읽어야 한다. 복잡한 원인을 기대하기 전에 기본부터 의심하고, 장애의 급박함에 밀려 성급한 결정을 내리지 않는다. 사이트를 반쯤 망가진 채로 두지 말고 점검 페이지로 상황을 알려야 한다.

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

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

원인별5

소프트웨어 결함2건

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

설정 변경4건

  1. IL-0005 새 텔레메트리 서비스가 모든 노드에서 무거운 쿠버네티스 API 요청을 보내 대형 클러스터의 컨트롤 플레인이 무너졌고, DNS 기반 서비스 디스커버리가 깨져 OpenAI 의 모든 서비스가 멈췄다
    OpenAI2024
  2. IL-0068 익명 요청을 허용한 쿠버네티스 API 서버로 공격자가 들어와 RBAC 로 백도어를 만들고, DaemonSet 으로 Monero 채굴기를 모든 노드에 띄웠다.
  3. IL-0108 워크숍 중 운영 클러스터에 적용한 Alcide admission 컨트롤러 때문에 Deployment 생성과 수정이 타임아웃되었다
    DFDS2020
  4. IL-0008 응답하지 않는 OPA 검증 웹훅 때문에 GKE 마스터 업그레이드가 멈추고 API 서버가 간헐적으로 끊기면서 노드가 끝없이 재생성됐다

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

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

용량 한계1건

  1. IL-0075 클러스터가 EC2 인스턴스 약 290대로 커지자 노드마다 도는 Datadog 에이전트가 쿠버네티스 API 를 폴링하면서 API 서버가 CPU 와 메모리를 다 써 쿠버네티스 컨트롤 플레인을 쓸 수 없게 됐다.

unknown1건

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