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

사례21건

21건 중 14~18번째

  1. 증상

    2022-03-31 07:53 UTC 에 GitLab.com 웹 서비스의 50x 오류가 늘기 시작했고, 1분 뒤 당직 엔지니어가 오류율 증가 페이지를 받았다. 사용자에게는 GitLab.com 이 느려졌고 간헐적으로 500 오류 페이지가 떴다.

    촉발

    gitlab-com/gl-infra/k8s-workloads/gitlab-com!1643 머지 요청을 배포하는 파이프라인이 07:49 UTC 에 gprd-cny 로 배포를 시작했다. 이 변경에는 GitLab 차트 버전 업그레이드가 들어 있었고, 새 차트는 Prometheus ServiceMonitor, PodMonitor 설정과 관련된 변경으로 Kubernetes Service 와 Deployment 의 포트 이름을 바꿨다.

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

    07:53 UTC 에 50x 오류가 늘기 시작했고 07:54 에 PagerDuty 알림이 당직 엔지니어를 호출했다. 변경을 배포하던 엔지니어가 오류를 보고 그 변경과 연결해 원인을 짚었다.

    조치
    • 08:05 UTC 에 당직 엔지니어가 카나리 환경을 트래픽에서 뺐다가 08:25 에 다시 넣었다.
    • 08:15 에 cluster c 와 cluster d 배포 작업을 시작 전에 취소했다.
    • 08:51 에 HAProxy 에서 gprd-us-east1-d 클러스터를 뺐다가 08:56 에 다시 넣었다.
    • 09:31 에 최소 레플리카 수를 100 넘게 올리는 변경 !1650 을 머지했다.
    • 09:53 에 HAProxy 에서 gprd-us-east1-c 클러스터를 빼고, 09:57 에 이 클러스터에 !1643 을 배포한 뒤 10:07 에 다시 넣었다.
    • 10:19 에 최소 레플리카 상향을 되돌리는 변경 !1652 를 머지했다.
    후속 조치
    • 리전 클러스터 하나에서 트래픽을 통째로 안전하게 빼는 graceful drain 기능을 만든다.
    • PagerDuty 를 유지보수 모드로 바꾸는 ChatOps 명령을 만든다.
    교훈

    알림은 정확하게 울렸다. 원인이 바로 직전에 배포한 변경이라는 것을 알았기 때문에, 그 변경을 배포하던 파이프라인을 멈추는 것이 자연스러운 첫 대응이었다.

  2. 증상

    2020년 12월 4일 00:00 UTC 무렵부터 Central India 에서 Azure CNI 로 새로 만든 AKS 클러스터에 터널 연결 문제가 생겼다. 진단 페이지에는 터널 exec 문제가 표시됐다.

    촉발

    Central India 의 VM 들이 평소처럼 00 으로 시작하는 MAC 주소가 아니라 06 으로 시작하는, 훨씬 높은 값의 MAC 주소를 받기 시작했다.

    원인
    구성 요소
    기여 요인
    –
    조치
    • VMSS 클러스터 사용자에게 노드 이미지 업그레이드나 패치 버전 업그레이드 같은 쿠버네티스 업그레이드로 bridge 를 쓰지 않는 Azure CNI 를 받으라고 안내했다.
    • VMAS 클러스터 사용자에게 클러스터를 늘린 뒤 MAC 주소 값이 높고 bridge 모드로 동작하는 VM 을 지우라고 안내했다.
    • 영향을 받은 클러스터가 막 만든 것이라면 다시 만들라고 안내했다.
    후속 조치
    • transparent 모드를 모든 리전의 기본값으로 만드는 핫픽스를 배포한다.
    교훈

    VM 에 배정되는 MAC 주소 범위처럼 플랫폼 쪽에서 바뀐 값 하나가 오래 드러나지 않던 CNI 버그를 드러낼 수 있다. 같은 증상이라도 노드의 MAC 주소와 CNI 모드를 함께 봐야 영향 여부를 가를 수 있다.

  3. 증상

    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 로 로그를 빠르게 뒤질 수 있어서 복구 시간이 줄었다.

  4. 증상

    Omio 는 6개월 동안 원인을 알 수 없는 멈춤을 겪었다. 애플리케이션이 멈추거나 헬스 체크에 응답하지 않았고, 네트워크 연결이 끊겼다.

    촉발

    쿠버네티스는 CPU limit 을 커널 CFS 의 쿼터로 구현한다. 주기는 100ms 이고, limit 2코어는 주기마다 CPU 시간 200ms 가 된다. 스레드 10개가 동시에 돌면 20ms 만에 쿼터를 다 쓰고, 남은 80ms 동안 파드의 모든 스레드가 멈춘다. 여기에 커널 CFS 스케줄러의 알려진 버그가 불필요한 스로틀링을 일으켜, 컨테이너가 허용된 쿼터를 다 쓰기도 전에 스로틀링됐다.

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

    팀은 6개월 동안 애플리케이션이 멈추거나 헬스 체크에 응답하지 않는 현상을 겪었지만, 쿠버네티스가 cgroup 지표를 내보내지 않아 스로틀링을 바로 알아채지 못했다. 파드 안에서 /sys/fs/cgroup/cpu/cpu.stat 의 nr_throttled 와 throttled_time 을 읽어 스로틀링 비율을 확인했다.

    조치
    • 버그를 고친 최신 커널이 모든 클러스터에 배포될 때까지 CPU limit 을 껐다.
    후속 조치
    • CFS 쿼터 버그를 고친 최신 커널을 모든 클러스터에 배포한다.
    • 사용률, 포화도, 오류를 보는 USE 지표와 함께 API 지연과 오류율을 지켜보며 결과가 기대한 대로인지 확인한다.
    교훈

    CFS 쿼터 버그가 고쳐지지 않은 커널을 쓴다면 쿠버네티스에서 CPU limit 을 없애거나 kubelet 에서 CFS 쿼터를 끄는 편이 낫다. CPU request 와 limit 은 설정이 비슷해 보여도 구현이 전혀 다르다. CPU 스로틀링은 쿠버네티스 기본 지표에 드러나지 않으므로 cpu.stat 을 직접 확인해야 한다. limit 을 끄면 최적화되지 않은 애플리케이션이 노드의 CPU 를 독차지할 수 있으니, JVM, Go, Node 런타임을 미리 튜닝해 둬야 한다.

  5. 증상

    한 서비스의 지연 시간 그래프에 5월 10일부터 스파이크가 보이기 시작했다. 처음에는 1초 안팎까지 튀었고, 이어서 5초, 다시 20초로 올라간 뒤 꽤 오랫동안 그 수준에 머물렀다.

    촉발

    여러 서비스가 외부 DNS 조회를 많이 보냈고, 그 질의가 모두 kube-dns 를 거쳤다.

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

    문제는 서비스의 지연 시간 그래프에서 처음 드러났다. 같은 모양이 여러 서비스에서 나타나자 팀은 공통점을 찾았고, kube-dns 파드별 질의량을 비교해 불균형을 찾아냈다.

    교훈

    기본 설정에서 파드는 클러스터 IP 로 DNS 서버를 찾고, dnsPolicy 기본값인 ClusterFirst 때문에 외부 이름 조회도 kube-dns 를 먼저 거친다. 쿠버네티스 DNS 해석이 필요 없는 파드는 dnsPolicy 를 Default 로 두거나, None 으로 두고 세부 값을 직접 정할 수 있다. iptables 는 로드 밸런서가 아니어서 클러스터 IP 뒤의 파드에 부하를 고르게 나누지 못한다. 발표자들은 DNS 정책을 초기부터 자주 확인하고 용도에 맞는 정책을 쓰라고 했다.

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

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

원인별7

설정 변경3건

  1. IL-0179 DEBUG 로그가 쏟아지자 동기 로깅을 하던 요청 스레드들이 가득 찬 stdout 파이프에서 멈춘 채 DB 커넥션을 쥐고 있어, HikariCP 커넥션 풀이 고갈되고 요청이 30초 주기로 한꺼번에 실패했다.
  2. IL-0208 GitLab Helm 차트 업그레이드가 Service 와 Deployment 의 포트 이름을 바꿔 GCP 로드 밸런서가 다시 구성되는 동안 GitLab.com 요청이 느려지고 50x 오류가 났다
    GitLab2022
  3. IL-0035 ElastAlert 에 새로 넣은 알림 규칙 때문에 ElastAlert 파드가 메모리를 끝없이 써서 노드가 잇달아 NotReady 가 되었고, 같은 클러스터의 도구와 Grafana, Prometheus 가 함께 흔들렸다.
    NU.nl2019

배포 결함1건

  1. IL-0136 Sweden Central 리전에서 내부 서비스 배포가 캐시를 비워 메타데이터 백엔드에 평소 20배의 트래픽이 몰렸고, 데이터베이스 연결에 기대는 헬스 체크가 인스턴스를 계속 재시작시켜 Azure OpenAI 요청이 6시간 가까이 실패했다

용량 한계5건

  1. IL-0155 NYC1 의 일부 DOKS 클러스터에서 공유 CPU 노드 위의 CoreDNS 때문에 DNS 가 간헐적으로 실패하고 NodeNotReady 가 났다
  2. IL-0048 대형 EKS 클러스터에서 CoreDNS 가 VPC DNS 리졸버로 보내는 질의가 링크 로컬 트래픽의 초당 1024 패킷 한도에 걸려 DNS 조회가 간헐적으로 타임아웃됐다.
  3. IL-0080 트래픽이 몰린 GKE 클러스터에서 kube-dns 가 DNS 질의를 감당하지 못해 여러 서비스의 이름 해석이 실패하고 운영 장애로 번졌다.
  4. IL-0169 FR-PAR 의 Scaleway Kubernetes API 가 메모리 부족으로 쓰러져 노드 인증이 막히고 Kapsule 노드가 NotReady 가 됐다.
  5. IL-0033 kube-dns 파드 사이의 트래픽 불균형과 DNS 초당 패킷 한도 때문에 외부 DNS 조회가 많은 여러 서비스의 지연 시간이 20초까지 늘었다
    Airbnb2019

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

구성 요소
기여 요인
–
조직
  1. IL-0201 프레임워크 업그레이드가 쿠버네티스 인프라에서 커널 패닉을 일으켜 GitHub.com 의 웹과 API 요청이 15시간 넘게 간헐적으로 실패했다
    GitHub2025

소프트웨어 결함7건

  1. IL-0081 ingress-nginx 의 enable-serial-reloads 옵션이 NGINX 리로드 중에 엔드포인트 동적 갱신을 막아, 배포 중 트래픽이 이미 없는 파드로 가면서 API 요청이 타임아웃됐다.
    Cresta2025
  2. IL-0131 새로운 형태의 GenerateContent 요청이 Vertex AI 예측 API 서버에 세그폴트를 일으켰고, 동시에 재시작하는 서버가 늘자 서빙 용량이 모자라 여러 리전에서 오류가 치솟았다.
  3. IL-0161 앞선 API 업데이트가 의도대로 동작하지 않아 토론토 데이터센터에서 새 LKE 클러스터 프로비저닝이 타임아웃으로 사흘 넘게 실패했다.
    Linode2024
  4. IL-0112 나중에 회수된 EKS 노드 AMI 로 노드를 교체한 뒤 노드가 PLEG is not healthy 를 보고하며 NotReady 를 오갔고 파드 네트워크 타임아웃이 났다
    DFDS2022
  5. IL-0146 Central India 에서 새로 만든 Azure CNI 클러스터의 VM 이 높은 값의 MAC 주소를 받으면서 bridge 모드 Azure CNI 의 오래된 버그가 드러나 터널 연결이 끊기고 kubectl exec 와 파드 간 통신이 타임아웃됐다.
  6. IL-0190 쿠버네티스 업그레이드로 etcd 리더가 있던 노드가 갑자기 종료된 뒤, Cortex distributor 두 개가 옛 리더와 맺은 TCP 연결이 멈춘 채 그 연결을 계속 써서 런던 리전 Hosted Prometheus 쓰기가 12분 동안 일부 실패했다.
  7. IL-0012 CPU limit 과 커널 CFS 쿼터 버그로 파드가 과하게 스로틀링돼 헬스 체크가 실패하고 애플리케이션이 멈췄다
    Omio2020

DNS·네트워크 장애3건

  1. IL-0178 EKS 에서 HPA 가 파드를 줄일 때 엔드포인트 제거보다 컨테이너 종료가 먼저 끝나 502 가 났고, 블루/그린 전환 뒤에는 conntrack 에 남은 연결이 삭제된 파드로 가서 클라이언트가 타임아웃을 받았다.
  2. IL-0057 EKS 노드의 SNAT 과정에서 conntrack 경합으로 바깥으로 나가는 TCP 연결이 1초나 3초씩 늦어져, 서비스 간 호출이 많은 서비스의 p99 지연이 늘었다.
    Prezi2019
  3. IL-0047 conntrack 경합으로 DNS 조회가 5초씩 늦어져 파드 사이 요청이 간헐적으로 5초, 10초, 15초씩 지연되었다.

운영 실수1건

조직
  1. IL-0115 OpenAI 의 운영 AKS 클러스터 세 개 중 하나가 사람의 실수로 통째로 내려가 Codex, Embeddings, 구형 GPT 모델과 파인튜닝 모델이 최대 12시간 동안 제대로 응답하지 못했다
    OpenAI2022