Incident Library
적용된 필터 증상지연 시간 증가기여 요인미검증 가정모두 풀기검색어 없이 필터만 적용한 목록입니다. 최근 사례부터입니다.
추천 필터 검색하면 검색어에서 찾은 분류 값이 여기에 나옵니다.

그래프

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

사례8건

8건 중 1~5번째

  1. 증상

    8:10 UTC 에 팀은 Redis 스테이트풀셋을 고아 삭제했다. 고아 삭제는 파드와 디스크는 그대로 두고 스테이트풀셋 객체만 지우는 방식이다. 스테이트풀셋을 다시 만들자 쿠버네티스가 8:10 부터 8:15 UTC 사이에 스테이트풀셋 전체를 빠르게 재시작했다. 처음에는 백엔드 서비스가 Redis 연결 오류를 냈지만 서비스 전체가 곧바로 무너지지는 않았다.

    촉발

    팀은 디스크를 온라인으로 늘린 뒤 Git 의 선언적 설정을 실제 상태와 맞추려고 Redis 스테이트풀셋을 고아 삭제했다. 고아 삭제는 파드와 디스크는 남기고 스테이트풀셋 객체만 지우는 방식이다. 그다음 늘린 크기를 적은 저장소 템플릿으로 스테이트풀셋을 다시 만들었다.

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

    Redis 클러스터 여러 인스턴스의 디스크 여유 공간이 바닥나고 있다는 알림이 시작이었다. 그 뒤의 장애는 스테이트풀셋을 다시 만든 직후 백엔드 서비스가 Redis 연결 오류를 내면서 드러났다.

    조치
    • 망가진 Redis 클러스터를 손으로 복구했다. 마스터에서 쓸모없어진 노드 ID 를 지우고, 해당 레플리카를 리셋한 뒤 클러스터에 다시 붙이고 복제가 따라잡기를 기다렸다.
    • 실제로 메모리가 바닥난 구성 요소를 찾아낸 뒤, 백엔드 서비스를 확장하고 그 구성 요소의 메모리 한도를 올렸다.
    • 프로브를 잠시 느슨하게 해, 백엔드 인스턴스가 ready 와 not ready 를 오가지 않고 바로 트래픽을 받게 했다.
    • 10:00 UTC 에 임시 조치를 되돌렸다.
    후속 조치
    • 빠져 있던 스타트업 프로브를 넣는다. 데이터셋을 다 읽기 전에는 파드를 ready 로 표시하지 않는다.
    • 재시작한 파드가 옛 마스터 IP 주소에 묶여 있을 때 쓸 수 있도록 Redis 용 자체 컨트롤 플레인을 만든다.
    • 서비스 전체의 단일 장애점이 된 이 Redis 클러스터 의존을 줄인다. 중요한 정보 일부를 서버마다 따로 둔 Redis 클러스터 같은 다른 데이터 저장소로 옮기고, 백엔드 일부 구성 요소에 Kafka 를 쓰기 시작한다.
    교훈

    장애를 일으킨 것은 디스크 확장이 아니라 상태를 맞추려고 컨트롤러 객체를 다시 만든 단계였다. 고칠 수 없는 필드가 있으면 객체를 통째로 바꾸는 위험한 방법을 쓰게 된다. 그렇게 바꾸면 쿠버네티스가 워크로드를 넓은 범위에서 다시 조정할 수 있다. 스타트업 프로브와 엄격한 레디니스 프로브가 있어야 롤링 재시작이 현재 파드가 정말 준비될 때까지 기다린다. 이번 장애에서 가장 뼈아픈 것은 프로브가 없었다는 점이다. 분산 클러스터가 다시 붙고 복제를 따라잡는 데는 시간이 걸리므로, 의존하는 서비스는 그동안 기능을 줄여서라도 버티도록 설계해야 한다.

  2. 증상

    어느 금요일 오후, 고객 한 곳이 SCHIP 에서 돌리는 일부 서비스에서 HTTP 5xx 오류가 튄다고 알려 왔다. 팀은 바로 장애를 선언했다.

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

    고객이 SCHIP 에서 돌리는 일부 서비스의 HTTP 5xx 가 튄다고 알려 와서 알았다. DNS 와의 관계는 한참 뒤에야 드러났고, 그때 보니 그동안 무시해 온 이 클러스터의 DNS Latency SLI 가 다른 클러스터보다 낮아져 있었다.

    조치
    • dnsmasq 의 노드당 동시 DNS 질의 한도를 150에서 Google 권장값인 1500으로 올렸다.
    • CoreDNS 가 응답에 RA 비트를 항상 넣도록 header 설정에 set ra aa, clear rd 를 넣어 dnsmasq 가 cluster.local 응답을 캐시하게 했다.
    • 노드 로컬 dnsmasq 에서 ndots 때문에 생긴 풀 수 없는 도메인 질의를 가로채 NXDOMAIN 으로 응답하도록 설정해 CoreDNS 로 넘어가지 않게 했다.
    • fluent-bit 가 로그 라우터에 접속할 때 쓰는 호스트 이름을 서비스 이름에서 FQDN 으로 바꿨다.
    • 영향받은 고객에게 앱의 내부 이름 해석을 FQDN 으로 바꾸도록 요청했다.
    교훈

    SLO 를 보기 좋은 지표로만 두지 말고 안전장치로 써야 한다. 이번에는 나빠진 DNS Latency SLI 를 오래 무시한 탓에 원인을 늦게 찾았다. SLO 를 안전장치로 쓰려면 믿을 수 있는 SLI 가 먼저 있어야 한다. 조사가 여러 당직자에게 흩어져 있었고, 관찰 결과와 가설을 한곳에 모으지 않아 같은 가설이나 이미 버린 가설을 다시 붙잡기도 했다. 가설 하나를 버린 뒤에 다음 가설로 넘어가야 한다. 기존 지표에 없는 데이터는 DNStop 처럼 직접 모아야 한다. 멀티 테넌트 환경에서는 DNS 를 한 번 개선하면 모든 고객이 그 효과를 본다.

  3. 증상

    LINE 의 messaging-hub 는 일본 음식 배달 서비스 Demaecan 의 Merchant 앱과 Driver 앱에 웹소켓으로 메시지를 보낸다. 어느 날 최대 트래픽 시간이 아닌데도 웹소켓 연결 수 그래프가 순간적으로 크게 떨어졌다. 이 현상은 한 번으로 끝나지 않고 불규칙하게 계속 일어났다.

    촉발

    같은 L7 로드밸런서를 공유하는 다른 서비스 담당자가 자기 LB 설정을 배포하면 HAProxy 가 재로드됐다. hard-stop-after 로 정한 30분이 지나 이전 프로세스가 종료되면서 거기 붙어 있던 웹소켓 연결이 모두 끊겼다.

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

    웹소켓 연결 수 그래프에서 최대 트래픽 시간이 아닌데도 연결 수가 순간적으로 뚝 떨어지는 것을 보고 알았다. Nginx 패킷 드롭은 네트워크 모니터링으로 원인을 찾았다.

    조치
    • Merchant 팀이 토큰 발급 API 를 따로 떼어 배포해 토큰 요청이 몰려도 다른 Merchant API 가 지연되지 않게 했다.
    • Nginx 를 늘리고 파드 안티 어피니티와 레이블 셀렉터로 Nginx 파드가 서로 다른 노드에 뜨게 해서 NF_CONNTRACK 테이블 포화로 생기던 패킷 드롭을 없앴다.
    • Ingress Nginx 의 proxy-read-timeout 과 proxy-send-timeout 을 300s 에서 3600s 로, LB timeout 도 3600s 로 올렸지만 웹소켓 드롭은 멈추지 않았다.
    • 공유하던 L7 LB 를 L4 LB 로 바꿔 웹소켓 드롭을 없앴다.
    교훈

    문제의 범위를 미리 단정해 스스로 제한하면 안 된다. 인프라 팀과 네트워크 팀이 문제없다고 답했다는 이유로 직접 다룰 수 있는 영역만 뒤지다가 공유 L7 LB 를 늦게 의심했다. LB 같은 기술 리소스를 다른 서비스와 공유하면 다른 팀의 배포가 내 서비스의 연결을 끊을 수 있다. Nginx 를 늘려 NF_CONNTRACK 부담을 나눌 때는 파드가 서로 다른 노드에 뜨게 해야 하고, 노드 수보다 많이 늘리면 Pending 상태로 남는 파드가 생긴다는 점도 알아야 한다.

  4. 증상

    2021년 8월 24일 07:30 UTC에 웹 서비스의 지연 SLO 가 깨졌다. 웹 서비스의 Apdex 가 떨어졌고, 웹 프런트엔드로 가는 요청 일부가 잠시 느려졌다. Apdex 는 응답 시간이 목표 안에 든 요청의 비율로 계산하는 만족도 점수다.

    촉발

    웹 서비스를 VM 에서 쿠버네티스로 옮기면서 트래픽을 쿠버네티스 웹 파드로 넘겼다.

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

    07:30 UTC에 웹 지연 SLO 가 깨졌고, 10분 뒤인 07:40에 엔지니어가 Slack 에서 장애를 선언했다.

    조치
    • 웹 파드의 targetCPU 를 더 보수적인 값으로 낮추는 머지 요청 gitlab-com/gl-infra/k8s-workloads/gitlab-com!1149 를 머지했다.
    후속 조치
    • 목표 사용률을 조정하는 머지 요청 gitlab-com/gl-infra/k8s-workloads/gitlab-com!1149 를 재발 방지 조치로 올려 머지했다.
    교훈

    트래픽을 새 파드로 넘길 때 HPA 의 CPU 목표값이 너무 높으면 부하가 늘어도 파드가 제때 늘지 않는다. 팀은 목표값을 보수적으로 낮춰 이 문제를 풀었다.

  5. 증상

    Buffer 엔지니어가 컨테이너의 스로틀링 지표를 살펴보니, CPU 사용량이 한도 근처에도 가지 않은 컨테이너가 많이 스로틀링되고 있었다.

    촉발

    Buffer 는 노드를 지키려고 컨테이너에 CPU 한도를 걸어 두었는데, 노드 커널에는 CPU 한도가 걸린 컨테이너를 필요 없이 스로틀링하는 버그가 남아 있었다.

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

    엔지니어가 컨테이너의 스로틀링 지표를 살피다가, CPU 사용량이 한도보다 훨씬 낮은 컨테이너도 많이 스로틀링되는 것을 보고 알았다.

    조치
    • 사용자에게 직접 또는 간접으로 닿는 경로에 있는 모든 서비스에서 CPU 한도를 없앴다.
    • 한도를 없앤 서비스에 톨러레이션을 더해 테인트를 건 노드에서만 돌게 하고, 한도가 있는 서비스와 떼어 놓았다.
    • 서비스마다 몇 달 치 사용량을 분석해 최대 CPU 사용량에 20% 넘는 여유를 더한 값을 CPU 요청값으로 정했고, 메모리 요청값도 같은 방식으로 정했다.
    후속 조치
    • 커널 수정이 들어간 노드 이미지로 올린다. Buffer 는 kops 1.18 이상에서 기본 이미지가 되는 Ubuntu 20.04 를 기다리고 있다.
    • 수정된 커널로 올린 뒤 스로틀링이 정말 사라졌는지 확인하고, 그 결과로 글을 고친다.
    교훈

    리눅스에서 컨테이너를 돌리면 쿠버네티스든 Mesos 든 Swarm 이든 스로틀링 때문에 컨테이너가 제 성능을 내지 못할 수 있다. 먼저 커널을 수정된 버전으로 올리고 스로틀링 지표를 지켜보는 편이 낫다. CPU 한도를 없애면 지연 시간은 줄지만 위험하다. 한도를 없앤다면 CPU 요청값을 제대로 잡고, 노드의 CPU 와 메모리 사용량을 꼼꼼히 모니터링한다. 사용량이 높으면 Horizontal Pod Autoscaler 로 파드를 늘려 여유 있는 노드에 배치되게 한다. 클러스터에 여유가 없으면 알림을 받거나 노드 오토스케일러로 노드를 늘린다.

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

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

원인별4

설정 변경3건

  1. IL-0063 Redis 스테이트풀셋을 다시 만들자 Redis 클러스터가 한꺼번에 재시작되며 일부가 망가졌고, 재연결 폭주로 백엔드가 OOM 으로 죽어 AdGuard VPN 이 약 50분 멈췄다.
  2. IL-0177 다른 팀의 설정 배포로 공유 L7 HAProxy 가 재로드될 때마다 messaging-hub 의 웹소켓 연결이 한꺼번에 끊겼다.
    LINE+2022
  3. IL-0209 웹 파드의 HPA CPU 목표값이 너무 높아 트래픽을 넘겨받는 동안 파드가 늘지 않았고, GitLab.com 웹 지연 SLO 가 약 15분 동안 깨졌다.
    GitLab2021

DNS·네트워크 장애2건

  1. IL-0083 멀티 테넌트 쿠버네티스 클러스터에서 노드 로컬 dnsmasq 가 동시 질의 한도에 걸리고 cluster.local 응답을 캐시하지 못한 데다 ndots 검색 도메인 질의가 CoreDNS 로 몰려, 서비스 간 호출이 간헐적인 5xx 를 냈다.
  2. IL-0056 kops 에서 EKS 로 옮긴 뒤 AWS VPC CNI 의 SNAT 때문에 파드에서 다른 VPC 의 NLB 뒤 서비스로 가는 호출이 간헐적으로 실패했다

소프트웨어 결함2건

  1. IL-0029 CPU 한도를 건 컨테이너가 사용량이 한도에 한참 못 미치는데도 스로틀링되어 사용자 대면 서비스의 지연 시간이 늘었다.
    Buffer2020
  2. IL-0011 HAProxy 인그레스 템플릿이 백엔드 파드를 IP 순으로 정렬해 일부 파드에 요청이 몰리고 인그레스 컨테이너가 OOMKilled 됐다

용량 한계1건

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