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

사례2건

2건 중 1~2번째

  1. 증상

    2020년 3월 16일 11:31 UTC에 SLO 기반 알림이 당직 엔지니어를 호출했다. 런던 리전 Hosted Prometheus 로 들어오는 쓰기의 약 20%가 실패하고 있었다. 문제는 이미 11분 전에 시작된 상태였다.

    촉발

    예약된 쿠버네티스 버전 업그레이드가 etcd 리더가 돌던 노드를 정상 종료 절차 없이 갑자기 종료했다.

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

    SLO 기반 알림이 11:31 UTC에 당직 엔지니어를 호출했다. 장애가 시작되고 11분이 지난 시점이었다. 오류율이 20% 수준이었기 때문에 이대로 두었다면 월간 SLA 를 넘기기까지 약 18시간이 걸렸을 것이다.

    조치
    • 11:32 UTC에 영향받은 distributor 를 재시작했고, 오류가 멈췄다.
    후속 조치
    • Cortex 의 etcd 클라이언트 설정에 gRPC keepalive 프로브를 켠다. DialKeepAliveTime 은 10초, DialKeepAliveTimeout 은 DialTimeout 의 두 배로 두고 PermitWithoutStream 을 true 로 한다.
    • 쿠버네티스 업그레이드 절차를 고쳐, etcd operator 가 관리하는 etcd 파드까지 포함해 파드와 머신을 정상 종료 절차로 내리게 한다.
    교훈

    노드가 죽으면 TCP 연결이 정상적으로 닫히지 않고 멈춘 채 남을 수 있다. etcd 클라이언트에 keepalive 를 설정하지 않으면 새 리더가 뽑힌 뒤에도 클라이언트는 죽은 연결을 계속 쓴다. 노드를 내리는 업그레이드 스크립트는 operator 가 관리하는 파드까지 정상 종료할 수 있어야 한다. 장애 대응과 복구, 사후 분석 동안 Grafana Loki 로 로그를 빠르게 뒤질 수 있어서 복구 시간이 줄었다.

  2. 증상

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

    촉발

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

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

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

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

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

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

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

원인별1