Incident Library
적용된 필터 구성 요소CoreDNS도메인쿠버네티스모두 풀기검색어 없이 필터만 적용한 목록입니다. 최근 사례부터입니다.
추천 필터 검색하면 검색어에서 찾은 분류 값이 여기에 나옵니다.

그래프

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

사례17건

17건 중 11~15번째

  1. 증상

    어느 금요일 오후, 고객 한 곳이 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 를 한 번 개선하면 모든 고객이 그 효과를 본다.

  2. 증상

    2023-03-14 18:00 UTC 쯤 한 서비스에서 통신 오류가 늘기 시작했다. 곧 모든 고객의 파이프라인이 늦게 시작하다가 끝내 작업이 돌지 않았고, 18:19 UTC 에 상태 페이지에 작업 시작 지연이 올라왔다.

    촉발

    3월 14일 17:40 UTC 쯤 인프라 팀이 전날 되돌렸던 구성 요소들을 다른 방식으로 다시 업그레이드했다. 전날 kube-proxy 를 되돌린 뒤로 iptables 동기화가 조금씩 실패하던 상태에서 업그레이드를 이어 가자 동기화 오류가 한꺼번에 치솟았다.

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

    팀은 3월 14일 18:00 UTC 에 한 서비스의 통신 오류가 늘어나는 것을 보고 장애를 알아챘다. 장애 통화에 사람이 더 들어오면서 영향이 여러 서비스로 퍼진 것을 확인했다. 3월 13일 롤백 뒤에 로그에 나온 소수의 Sync 실패 오류는 그때 알아채지 못했다.

    조치
    • 모든 노드를 차례로 재시작해 노드마다 iptables 규칙 집합을 새로 만들었고, 23:00 까지 모든 노드 교체를 마쳤다.
    • contexts 나 machine executor 를 쓰는 작업이 회복되지 않아 별도의 의존성 풀을 재시작했고, 3월 15일 01:15 UTC 에 모든 작업이 정상으로 돌았다.
    • 작업이 다시 돌기 시작하자 쌓인 작업을 처리하려고 용량을 늘렸다.
    • 망가진 큐 몇 개를 고치려고 RabbitMQ 노드를 재시작했다.
    후속 조치
    • 앞으로의 업그레이드에서 이런 위험을 크게 줄이도록 쿠버네티스 업그레이드 절차를 고친다.
    • 이번 장애 때 kube-proxy 가 낸 동기화 오류를 잡는 지표와 알림을 더했다.
    • RabbitMQ 인프라의 복원력을 높일 방법을 검토한다.
    교훈

    이번 장애를 촉발한 원인은 하나가 아니었다. 네트워크는 모든 것의 바탕이어서 쿠버네티스 업그레이드는 본래 위험하다. 여러 사건이 맞물려 터진 이번 경우에는 팀이 세워 둔 위험 완화 방법이 듣지 않았다.

  3. 증상

    2021년 9월부터 메트릭 질의 서비스의 업데이트를 롤아웃할 때마다 오류가 늘었다. 서비스 로그에는 DNS 오류 때문에 메트릭 데이터 저장소에 연결하지 못했다는 내용이 찍혔다. 클라이언트가 실패한 질의를 자동으로 재시도해 사용자에게 보이는 오류는 적었지만, 재시도 때문에 대시보드와 모니터의 지연이 늘었다.

    촉발

    2021년 8월 메트릭 질의 클라이언트의 업데이트를 롤아웃하면서 새 기본값인 gRPC round_robin 부하 분산 정책이 처음 적용됐다. round_robin 은 끊긴 채널을 자동으로 다시 연결하는데, 오래전에 넣어 둔 매우 공격적인 gRPC 재연결 타임아웃과 겹쳐 서비스 롤아웃 때마다 사라진 파드 IP 로 SYN 이 쏟아졌다.

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

    2021년 9월부터 메트릭 질의 서비스 롤아웃 때 오류가 늘어나는 것을 보았고, 서비스 로그에서 DNS 오류가 데이터 저장소 연결을 막는 것을 확인했다.

    조치
    • node-local-dns 파드의 메모리를 64 MB 에서 256 MB 로 올렸다. OOM 오류는 멈췄지만 DNS 오류는 계속됐다.
    • AWS 가 더 많은 연결을 추적할 수 있다고 한 더 큰 인스턴스 유형으로 서비스 인프라를 올려 보았고, 그것만으로 문제가 사라지는 것을 확인했다.
    • SYN 폭주를 일으킨 사용자 지정 gRPC 재연결 파라미터를 지우고 기본값으로 되돌리는 PR 을 만들었다. 다음 롤아웃에서는 오류가 나지 않았다.
    후속 조치
    • Cilium 프로젝트에 PR 을 기여한다. 이 PR 은 옛 파드 IP 에 unreachable 경로를 더해, 지워진 파드로 가는 요청이 martian 패킷이 되지 않게 한다. 그러면 역경로 필터가 SYN 을 버리지 않고, 클라이언트는 분명한 ICMP 오류를 받는다.
    교훈

    gRPC, 쿠버네티스, AWS 같은 강력한 추상화도 엣지 케이스에서는 평소에 숨어 있던 복잡함이 오류로 드러난다. 몇 달을 조사한 끝에, 이번 장애의 뿌리가 팀이 직접 한 변경에 있다는 것을 찾았다. 의존성의 버그를 피해 가려던 변경, 이전 장애를 고치려던 변경, 기본 재연결 파라미터를 덮어쓴 변경이었다. 이 변경들은 당시에는 안전해 보였지만 한참 뒤에 상관관계를 찾기 어려운 때에 뜻밖의 결과를 냈다. DNS 문제처럼 보여도 DNS 문제가 아닐 때가 있다. AWS ENA 지표와 VPC Flow Logs 는 연결 추적을 들여다보는 데 중요하다. DNS 전파 시간은 여러 요인에 좌우된다.

  4. 증상

    5.44pm UTC 쯤 Google Container Registry 에서 이미지를 받을 때 cannot get manifest 오류가 많이 났다. 약 10분 뒤 사용자들이 워크스페이스를 시작할 수 없다고 보고했고, 이미 돌던 워크스페이스는 데이터를 잃었다.

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

    5.44pm UTC 쯤 팀이 GCR 에서 이미지를 받을 때 cannot get manifest 오류율이 높아진 것을 알아챘다. 약 10분 뒤 사용자들이 워크스페이스를 시작할 수 없다고 보고했고, 당번 팀이 장애 대응을 시작했다.

    조치
    • GCR 연결 문제를 조사하는 동안 예방 조치로 werft 작업을 돌려 EU 와 US 에 새 워크스페이스 클러스터를 만들기 시작했다. 만드는 데 약 20분 걸렸다.
    • 새 클러스터에 문제가 없음을 확인하고 트래픽을 새 클러스터로 돌렸다. 곧 워크스페이스가 시작됐고 사용자들이 Discord 에서 시작된다고 알려 왔다.
    후속 조치
    • 노드와 클러스터가 실패해도 남는 클라우드 사업자의 영구 볼륨에 사용자 데이터를 저장한다.
    • 워크스페이스가 시작할 수 없는 상태가 되어도 사용자가 파일을 내려받을 수 있게 한다. 지금은 워크스페이스가 멈춰 있을 때만 내려받을 수 있다.
    • 백업 절차 개선을 우선으로 진행한다.
    • DNS 서버 하나에 기대지 않고 GCP 내부 DNS, Google 의 공개 DNS 8.8.8.8, Cloudflare 의 1.1.1.1 세 곳을 쓰도록 바꿨다. 하나에 문제가 나도 나머지에 연결할 수 있다.
    • DNS 복원력을 높이는 작업을 더 진행한다.
    • 여러 리전의 클러스터 지원을 늘린다. 지금은 US 와 EU 두 곳뿐이고, 나중에는 여러 클라우드를 쓰는 것도 계획한다.
  5. 증상

    Route53 가중치로 EC2 와 EKS 를 함께 돌리며 레거시 시스템을 옮기던 중, 일정 비율이 넘는 요청을 EKS 쪽으로 보내자 서비스가 갑자기 불안정해졌다. 일부 노드에서 conntrack 테이블이 한계를 넘어 애플리케이션으로 가는 연결이 드롭되고 있었다.

    촉발

    첫 번째 불안정은 Route53 가중치로 EKS 쪽에 보내는 요청 비율을 일정 이상으로 올리면서 시작됐다. 두 번째 불안정은 문서에 나온 매니페스트로 force_tcp 를 쓰는 node-local-dns 를 운영 환경에 apply 하면서 시작됐다.

    원인
    구성 요소
    기여 요인
    조치
    • conntrack 상한이 기본값과 다른 값으로 설정되어 있었고 그 값은 kube-proxy 가 정하고 있었다. 팀은 kube-proxy 설정에서 conntrack 의 maxPerCore 를 늘렸다.
    • EKS 에 빠져 있던 dns-autoscaler 를 넣었다. CoreDNS 파드가 어느 정도 늘자 서비스가 크게 안정됐다.
    • CoreDNS 파드가 축출될 때 나던 DNS 오류를 없애려고 각 노드에 DaemonSet 으로 실행되는 node-local-dns 를 넣었다.
    • node-local-dns 설정에서 force_tcp 를 빼고 prefer_udp 로 바꾸자 DNS 가 안정됐다.
    교훈

    EKS 에서 DNS 를 안정시킨 것은 dns-autoscaler 를 넣은 것과, force_tcp 없이 node-local-dns 를 넣은 것 두 가지였다. node-local-dns 를 쓸 때는 eksctl 로 kubelet 의 DNS 대상을 바꿀 필요가 없고, kube-dns 를 그대로 두면 된다. node-local-dns 를 업데이트하는 동안처럼 잠시 쓸 수 없을 때는 dummy device 덕에 애플리케이션의 DNS 요청이 CoreDNS 로 바로 가므로 클러스터 전체의 가용성이 오른다. DNS 가 불안정하면 조회가 막혀 파드가 쓸데없이 늘어나므로, 파드 수를 알맞게 유지하는 데도 DNS 안정이 중요하다.

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

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

원인별5

용량 한계10건

  1. IL-0102 배포와 워커 오토스케일링 폭주가 겹치자 크기를 고정해 둔 CoreDNS 가 메모리 한도를 넘겨 재시작된 뒤 회복하지 못했고, Buildkite 사이트 전체가 약 30분 멈췄다.
  2. IL-0155 NYC1 의 일부 DOKS 클러스터에서 공유 CPU 노드 위의 CoreDNS 때문에 DNS 가 간헐적으로 실패하고 NodeNotReady 가 났다
  3. IL-0048 대형 EKS 클러스터에서 CoreDNS 가 VPC DNS 리졸버로 보내는 질의가 링크 로컬 트래픽의 초당 1024 패킷 한도에 걸려 DNS 조회가 간헐적으로 타임아웃됐다.
  4. IL-0082 EKS 노드 교체 중 CoreDNS 파드 하나가 종료되자 남은 CoreDNS 파드가 늘어난 부하를 버티지 못해 DNS 조회가 느려지고 타임아웃이 났다.
  5. IL-0027 CoreDNS 파드가 모두 한 노드에 몰린 채 그 노드의 메모리가 고갈되자 DNS 가 응답하지 못해 아이디어스 서비스 전체가 멈췄다
  6. IL-0204 Render 프랑크푸르트 클러스터에서 etcd 메모리 급증으로 컨트롤 플레인이 과부하에 걸렸고, 컨트롤 플레인 노드를 재부팅하자 그 위의 CoreDNS 가 다시 뜨지 못해 DNS 가 멈췄다.
    Render2024
  7. IL-0182 트래픽이 급변할 때 수가 모자란 CoreDNS 가 과부하로 지연과 간헐적 네트워크 끊김을 일으켰고, 나중에는 과하게 늘린 CoreDNS 파드가 Karpenter 의 노드 통합을 막았다
  8. IL-0433 EC2 에서 EKS on Fargate 로 트래픽을 옮기던 중 CoreDNS 과부하로 이름 해석 오류가 쏟아져 롤백했다
  9. IL-0445 EKS 로 옮기던 레거시 시스템에서 conntrack 테이블이 넘쳐 연결이 끊겼고, 이어 CoreDNS 파드가 축출될 때와 node-local-dns 를 넣은 뒤에 DNS 오류가 났다
  10. IL-0001 CoreDNS 파드가 메모리 한도 100Mi 에 걸려 OOM 으로 계속 죽으면서 쿠버네티스 클러스터 전체의 DNS 가 멈췄다

소프트웨어 결함1건

  1. IL-0104 Istio 의 공격적인 DNS 캐시 갱신과 클라이언트 포트 재사용, kube-proxy 가 종료된 파드의 conntrack 항목을 정리하지 않는 문제, 2분짜리 UDP conntrack 기본 타임아웃이 겹쳐 CoreDNS 파드가 OOMKilled 됐다.

설정 변경2건

  1. IL-0019 EKS 모듈 18 업그레이드로 새 노드의 디스크가 20Gb 로 줄어 이미지 풀이 no space left on device 로 실패했다
  2. IL-0461 메트릭 질의 서비스를 롤아웃할 때마다 DNS 오류가 나며 질의가 실패했다

DNS·네트워크 장애3건

  1. IL-0083 멀티 테넌트 쿠버네티스 클러스터에서 노드 로컬 dnsmasq 가 동시 질의 한도에 걸리고 cluster.local 응답을 캐시하지 못한 데다 ndots 검색 도메인 질의가 CoreDNS 로 몰려, 서비스 간 호출이 간헐적인 5xx 를 냈다.
  2. IL-0517 Gitpod 워크스페이스 클러스터의 CoreDNS 가 상위 DNS 서버에 닿지 못해 워크스페이스가 시작되지 않고 일부 데이터가 사라졌다
    Gitpod2022
  3. IL-0049 CoreDNS 파드가 줄어든 뒤 kube-proxy 가 conntrack 항목을 지우지 못해 일부 서비스의 DNS 요청이 없어진 파드로 가면서 5xx 가 쏟아졌다
    Preply2020

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

조직
  1. IL-0230 쿠버네티스 업그레이드 도중 메인 운영 클러스터의 서비스 간 통신이 끊겨 모든 고객의 작업이 시작되지 않았다