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

사례4건

4건 중 1~4번째

  1. 증상

    2022-10-24 14:43 UTC 부터 15:03 UTC 까지 PyPI 백엔드에 HTTPS 로 접속할 수 없었다. CDN 이 페이지를 가져오지 못했고, uploads.pypi.org 로 올리기가 막혔으며, 옛 파일 리디렉션 서비스도 끊겼다.

    촉발

    업그레이드와 새 설정을 모든 노드에 나눠 주려고 쿠버네티스 클러스터의 모든 노드를 순차 재시작했다. 새 쿠버네티스 API 서버가 올라오면서 기존에 정의한 Ingress 설정을 다시 검증하고 갱신했다.

    원인
    구성 요소
    기여 요인
    조치
    • PyPI 관리자들이 Ingress 설정을 새 ACM TLS 인증서를 가리키도록 고쳤다. 쿠버네티스가 Ingress 가 관리하는 ELB 에 HTTPS 리스너를 되살렸고 모든 서비스에 다시 접속할 수 있게 됐다.
    후속 조치
    • PyPI Ingress 설정에 필요한 ACM TLS 인증서의 호스트 이름을 AWS 콘솔에서 손으로 관리하지 않고 쿠버네티스 자원으로 관리할 방법을 찾는다.
    교훈

    자원을 모두 쿠버네티스 API 로 관리하면 원하는 상태와 실제 상태가 어긋나는 일이 줄고, 그런 어긋남이 다음 유지 보수 때 장애로 드러날 가능성도 줄어든다고 PSF 인프라 팀은 정리했다.

  2. 증상

    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 상태로 남는 파드가 생긴다는 점도 알아야 한다.

  3. 증상

    새 PriorityClass 를 적용하고 low PriorityClass 파드의 선점을 확인한 직후 팀에 알림이 대량으로 왔다. 알림은 외부 모니터링에서 왔고, 클러스터 밖에서 들어오는 요청의 오류율이 급격히 올라가 있었다.

    촉발

    운영 중인 KEEL 클러스터에 globalDefault: true 이고 value: 1000 인 medium PriorityClass 를 배포했다.

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

    외부 모니터링에서 클러스터 밖 요청의 오류율이 급격히 올랐다는 알림이 팀에 대량으로 왔다.

    후속 조치
    • PriorityClass 를 여섯 개로 다시 정의했다. low 와 low-nonpreempting 은 value: -10, medium 과 medium-nonpreempting 은 value: 0, high 와 high-nonpreempting 은 value: 10 이고, nonpreempting 쪽에는 preemptionPolicy: Never 를 뒀다. globalDefault: true 는 value 가 0 인 medium 에 두어, 나중에 PriorityClass 를 설정해도 기존 파드가 선점되지 않게 했다. cluster-autoscaler 는 priority 가 --expendable-pods-priority-cutoff 기본값보다 낮은 파드를 무시하므로, 하한을 -10 으로 정했다.
    교훈

    운영 중인 클러스터에 PriorityClass 를 설정할 때는 조심해야 한다. 모든 파드의 기본 priority 는 0 이어서 PriorityClass 설정이 의도하지 않은 선점을 일으킬 수 있다. globalDefault: true 인 PriorityClass 의 값이 0 을 넘으면 도입 전의 모든 파드가 선점 대상이 된다. 멀티 테넌시 클러스터라면 사용자가 PriorityClass 를 마음대로 배포하지 못하게 권한을 좁히고, ResourceQuota 나 OPA Gatekeeper 로 쓸 수 있는 PriorityClass 를 세밀하게 통제해야 한다.

  4. 증상

    09:26 UTC 에 한 개발자가 HTTP 307 리다이렉트 응답이 유난히 많다고 알렸다. 특히 Okta 서비스에서 많았다. 6분 뒤인 09:32 UTC 에 온라인 예약 시스템이 다운됐다는 연락이 왔다.

    촉발

    Traefik v1 을 걷어 내는 마이그레이션 작업으로 08:22 UTC 에 AWS 로드밸런서가 새 Traefik v2 리버스 프록시로 요청을 보내도록 바뀌었다.

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

    09:26 UTC 에 한 개발자가 HTTP 307 리다이렉트가 많다고 보고하면서 문제가 드러났다. 특히 Okta 서비스에서 많았다. 변경 뒤 64분 만이었다. 09:32 UTC 에는 온라인 예약 시스템이 다운됐다는 연락을 받았다.

    조치
    • 조사보다 롤백을 먼저 하기로 하고 09:48 UTC 에 변경을 롤백했다.
    후속 조치
    • 중요한 공지가 더 잘 보이게 할 방법을 검토한다.
    • 시험에 쓴 ALB 를 각 팀에 알려 팀이 자기 시나리오를 직접 시험하게 했어야 하는지 검토한다. 이번에 멈춘 서비스는 ALB 앞에 CloudFront 가 있어서 그렇게 했어도 시험하기 어려웠을 수 있다.
    교훈

    Cloud Engineering 팀이 모든 시나리오를 시험할 수는 없었다. 팀은 자기 애플리케이션 몇 개로 몇 주 동안 시험했지만 Okta 로그인 흐름의 문제는 잡지 못했다. 마이그레이션 전후의 요청 헤더를 비교했다면 미리 알 수 있었을지도 모른다는 물음도 남았다.

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

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

원인별1