Incident Library
적용된 필터 구성 요소노드 풀기여 요인기본 설정 방치모두 풀기검색어 없이 필터만 적용한 목록입니다. 최근 사례부터입니다.
추천 필터 검색하면 검색어에서 찾은 분류 값이 여기에 나옵니다.

그래프

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

사례7건

7건 중 1~5번째

  1. 증상

    프로덕션 EKS 클러스터에서 원인을 바로 알기 어려운 서비스 에러가 간헐적으로 났다. RDS 나 Redis 같은 외부 서비스를 호출할 때 연결이 가끔 실패했다. DNS 요청이 몰릴 때는 도메인 조회 응답이 늦어지거나 조회가 아예 실패했다.

    촉발

    모든 CoreDNS 파드가 같은 노드에 배치되었고, 그 노드의 메모리 사용률이 급증해 메모리가 고갈됐다.

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

    글은 전면 장애를 어떻게 알아챘는지 적지 않았다. 그 전의 DNS 문제는 원인을 알기 어려운 서비스 에러가 간헐적으로 나면서 드러났다. 팀은 RDS 와 Redis 호출이 가끔 실패하는 현상을 추적하다가 DNS 이름 해석 실패가 근본 원인이라는 것을 확인했다.

    조치
    • CoreDNS 앞에서 DNS 질의를 받아 노드마다 캐시하는 NodeLocalDNS Cache 를 데몬셋으로 배포해 CoreDNS 부하를 줄였다.
    • CoreDNS 에 maxUnavailable: 1 인 PodDisruptionBudget 과 topology.kubernetes.io/zone 기준의 topologySpreadConstraints 를 적용해 파드가 한 곳에 몰리지 않게 했다.
    • Deployment 의 dnsConfig 로 ndots 값을 5 에서 2 로 낮춰 불필요한 DNS 조회를 줄였다.
    교훈

    쿠버네티스의 ndots:5 기본값은 점이 적은 외부 도메인을 조회할 때마다 질의를 여러 번 만든다. 이 부하는 트래픽이 큰 프로덕션 환경에서야 드러난다. CoreDNS 를 파드 2개의 기본 구성으로 두면 클러스터 전체의 단일 장애점이 된다. CoreDNS 파드는 노드와 가용 영역에 흩어 둔다. 별도 노드 그룹이나 Fargate 로 분리하면 다른 워크로드와 자원을 다투지 않는다. Affinity 와 PriorityClassName 으로 우선순위를 주면 더 안정적이다. CoreDNS 의 캐시와 bufsize 조정은 증상을 잠깐 줄였을 뿐이다. ndots 값은 여러 자료가 1이나 2를 권하지만 각 환경에 맞춰 정해야 한다.

  2. 증상

    2025-03-18 09:36, 사용자들이 운영과 비운영 환경 모두에서 파드가 종료되고 자동으로 다시 뜨지 않는다고 알렸다. 자동 인프라 알림도 함께 울렸고, 운영 서비스에 장애가 났다.

    촉발

    EKS 1.30 업그레이드 중 디스케줄러가 cordon 된 노드의 파드를 모두 한꺼번에 다시 스케줄하려 했다.

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

    팀은 자동 인프라 알림과 사용자 보고로 장애를 알았다. 09:36 에 사용자들이 파드가 종료되고 다시 뜨지 않는다고 알렸다.

    조치
    • cordon 어노테이션을 지워 파드가 다시 스케줄되게 했다.
    • 멈춘 1.30 노드를 지워 새로 만들어지게 했다.
    • 1.30 노드 20대로 된 새 노드 그룹을 손으로 추가했다.
    • 예전 1.29 노드를 모두 cordon 하고 drain 해 워크로드를 새 1.30 노드로 옮겼다.
    후속 조치
    • AWS 에 Production System Down 지원 요청을 올려 추가 안내를 받았다. 요청 번호는 174229643100496 이다.
    • 비슷한 장애의 원인을 찾을 때 컨트롤 플레인 로그를 어떻게 조회하는지 AWS 지원팀에서 안내받았다.
    • 용량이 갑자기 모자랄 때 새 노드 그룹을 급히 늘리는 런북을 쓴다.
    • 오토스케일링 그룹과 쿠버네티스가 보는 노드가 어긋나면 울리는 알림을 만든다.
    • 디스케줄러가 왜 cordon 된 노드에서 파드를 쫓아내는지 설정을 검토하고, 가능하면 고친다.
    • Pending 파드 수가 갑자기 늘면 울리는 알림을 만든다.
    교훈

    이 글은 교훈 대신 후속 조치를 적었다. 조치를 보면 팀에는 비상용 노드 그룹을 급히 추가하는 문서화된 절차가 없었다. 오토스케일링 그룹과 쿠버네티스가 보는 노드가 어긋날 때 울리는 알림도, Pending 파드가 급증할 때 울리는 알림도 없었다. 팀은 디스케줄러가 cordon 된 노드를 어떻게 다루는지도 분명히 알지 못했다.

  3. 증상

    2023-02-14 09:33 UTC, 최종 사용자들이 CloudWatch 로그가 제대로 들어오지 않는다고 알려 왔다. 팀은 fluentd 를 조사하다가 컨테이너 런타임이 docker-shim 이 아니라 containerd 로 바뀌어 있다는 것을 찾았다. 전날 07:30 UTC 의 정기 노드 롤오버 때 containerd 가 실수로 기본 런타임으로 설정돼 있었다.

    촉발

    쿠버네티스 로그가 CloudWatch 로 가지 않는 문제를 고치려고 예정에 없던 노드 롤오버를 시작했다.

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

    로그 문제는 최종 사용자들이 CloudWatch 로그가 이상하다고 알려 오면서 드러났다. 노드가 사라진 장애는 사후 분석 기준으로 2분 만에 감지됐다.

    조치
    • 10:49 UTC 에 노드 롤오버 스크립트로 새 노드를 추가하려 했지만 Docker Hub 타임아웃으로 실패했다.
    • 10:52 UTC 에 노드 롤오버 스크립트를 다시 돌려 새 노드를 추가했고, 11:01 UTC 에 로드밸런서가 새 노드를 정상으로 판단해 트래픽을 다시 보냈다.
    후속 조치
    • 롤오버 절차를 문서로 남기고, 특히 롤오버가 잘못됐을 때 할 수 있는 일을 적는다.
    • 롤오버 절차를 개선할 방법을 찾는다.
    • QA 시험에 fluentd 로그 수집을 넣어 로그가 처음부터 끝까지 전달되는지 확인한다.
    • fluentd 가 보내는 로그 데이터가 부족하거나 없을 때 울리는 경보를 추가한다.
    • 스테이징 환경을 만든다.
    • 잘못된 컨테이너 런타임을 고르지 못하게 막는 장치를 넣었다.
    교훈

    상황이 심각해져도 침착해야 한다. 서둘러 고치다 피해를 키우기보다 알려진 정상 설정으로 롤백하는 편이 낫다. 새 워커 노드를 띄우는 일은 cloudinit 스크립트의 어느 단계도 실패하지 않는다는 전제에 크게 기대고 있다.

  4. 증상

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

  5. 증상

    동료가 슬랙으로 애플리케이션 배포가 오래 걸린다고 알려 왔다. 평소 몇 분이면 끝나는 배포가 한 시간째 새 파드 일부만 띄운 채 머물러 있었다. 새 파드의 절반쯤은 트래픽을 받고 있었고 나머지 절반은 Pending 상태였다.

    촉발

    클러스터의 노드 수가 256개에 이르렀다. GKE 는 노드당 최대 파드 수를 기본 110 으로 두고, 그 두 배 이상을 담을 수 있는 서브넷 마스크를 노드마다 미리 할당한다. 노드 하나가 IP 256개를 차지하므로 /16 보조 범위의 65,536개 주소가 노드 256개에서 바닥났다.

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

    동료가 슬랙으로 배포가 오래 걸린다고 알려 왔다. 확인해 보니 평소 몇 분이면 끝나는 배포가 한 시간째 새 파드 일부만 띄운 채 멈춰 있었다.

    조치
    • 파드가 많이 뜨지 않을 노드 풀에서 노드당 최대 파드 수를 줄여 전체 IP 사용량을 약 30% 줄였다.
    • 일부 노드 풀의 인스턴스 크기를 키워 노드당 더 많은 파드를 돌리게 했다.
    후속 조치
    • 상태 저장 애플리케이션, 캐시, 보안을 강화한 워크로드처럼 노드에 파드가 많이 뜨지 않는 노드 풀은 노드당 최대 파드 수를 낮춰 운영한다.
    • 일부 노드 풀에 더 큰 인스턴스를 쓴다.
    교훈

    GKE 는 기본으로 노드마다 IP 256개를 할당한다. /16 처럼 큰 범위도 노드가 256개면 바닥난다. 노드당 최대 파드 수가 파드 IP 소비량을 정하므로, 노드 풀마다 실제로 띄울 파드 수에 맞춰야 한다. 큰 노드를 쓰면 IP 를 효율적으로 쓰고 자원 활용도도 높아지지만, 노드 하나가 죽을 때 더 많은 파드가 함께 내려간다.

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

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

원인별5

용량 한계2건

  1. IL-0027 CoreDNS 파드가 모두 한 노드에 몰린 채 그 노드의 메모리가 고갈되자 DNS 가 응답하지 못해 아이디어스 서비스 전체가 멈췄다
  2. IL-0015 GKE 가 노드마다 IP 256개를 미리 잡아 /16 파드 주소 범위가 바닥나고 노드 증설과 배포가 멈췄다

배포 결함1건

  1. IL-0020 EKS 1.30 업그레이드 중 디스케줄러가 cordon 된 노드의 파드를 한꺼번에 쫓아내 운영 서비스가 멈췄다

설정 변경2건

  1. IL-0109 로그 수집을 고치려던 EKS 노드 롤오버가 꼬이면서 Auto Scaling 그룹이 정상 워커 노드를 모두 종료해 클러스터에 노드가 하나도 남지 않았다.
    DFDS2023
  2. IL-0055 실패하는 CronJob 이 기본 concurrencyPolicy 때문에 겹겹이 쌓여 재시작하는 파드가 수천 개로 늘었고 클러스터가 내려갔다
    Target2018

소프트웨어 결함1건

구성 요소
  1. IL-0190 쿠버네티스 업그레이드로 etcd 리더가 있던 노드가 갑자기 종료된 뒤, Cortex distributor 두 개가 옛 리더와 맺은 TCP 연결이 멈춘 채 그 연결을 계속 써서 런던 리전 Hosted Prometheus 쓰기가 12분 동안 일부 실패했다.

운영 실수1건

  1. IL-0054 GKE 에서 옛 노드 풀을 드레인하자 로드밸런서가 ingress-nginx 파드가 없는 새 노드만 가리켜 클러스터의 모든 인그레스 트래픽이 끊겼다