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

사례7건

7건 중 6~7번째

  1. 증상

    Zalando Fashion Store 의 모든 웹 상품 페이지와 코디 페이지가 한 시간 넘게 고객에게 오류를 많이 냈다. 오류는 쿠버네티스 클러스터 하나에서 도는 핵심 데이터 집계 계층 서비스에서 나왔다.

    촉발

    그리 중요하지 않은 하위 서비스 하나로 가는 호출이 타임아웃 나기 시작했다. 집계 계층이 이 호출에 404 로 응답하자 클라이언트가 재시도했고, 집계 계층으로 가는 요청과 그만큼의 DNS 쿼리가 갑자기 치솟았다.

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

    DNS 장애로 클러스터 내부 모니터링이 함께 멈춰 당직 호출이 자동으로 가지 않았다. 집계 계층 서비스 당직 엔지니어가 평소처럼 자동 호출에 기대지 못하고 쿠버네티스 담당 당직 엔지니어에게 직접 전화했다. 그래서 쿠버네티스 당직 엔지니어가 장애를 알기까지 예상보다 오래 걸렸다. 연락을 받은 엔지니어가 CoreDNS 파드가 OOM 으로 죽고 있는 것을 찾아냈다.

    조치
    • 쿠버네티스 당직 엔지니어가 CoreDNS 파드의 메모리 request 와 limit 을 100Mi 에서 2000Mi 로 직접 올렸다.
    후속 조치
    • 노드마다 dnsmasq 를 앞에 둔 CoreDNS 를 띄우는 방식으로 더 튼튼한 DNS 구성을 도입한다. 검토하고 시험한 다른 어떤 구성보다 이 방식의 성능이 좋았다.
    • 클러스터 바깥에서 클러스터 전체 상태를 보는 알림을 강화한다. 팀은 클러스터 안 애플리케이션이 영향을 받기 전에, 늦어도 같은 시점에는 클러스터 이상을 알아야 한다.
    • 장애 대응 절차와 도구를 개선한다. 자동 당직 호출이 실패해도 당직 엔지니어가 다른 도구로 옮겨 가지 않고 다른 팀에 바로 에스컬레이션할 수 있게 한다. 채팅 봇으로 에스컬레이션을 단순하게 만드는 방안을 추진하고 있다.
    교훈

    쿠버네티스 DNS 구성은 충분히 튼튼하지 않았다. 애플리케이션 하나가 DNS 를 사실상 서비스 거부 공격하듯 몰아붙여 클러스터 전체를 멈추게 할 수 있어서는 안 된다. DNS 쿼리를 늘린 애플리케이션의 영향 범위는 적어도 노드 하나, 가능하면 파드 하나 안에 갇혀야 한다. 팀은 conntrack 을 처리하는 리눅스 커널의 경쟁 상태나 ndots 5 문제 같은 쿠버네티스 DNS 문제를 대부분 알고 있었고, 일부는 완화책도 갖고 있었다. 하지만 이 문제들이 DNS 구성에 얼마나 크게 영향을 주는지는 제대로 알지 못했다. 모니터링도 충분히 튼튼하지 않았다. 일부 알림은 클러스터 밖에서 돌았지만 대부분은 클러스터 안에서 돌았다. 그래서 DNS 가 무너졌을 때 당직 엔지니어가 자동으로 호출되지 않았고 복구 시간이 필요 이상으로 길어졌다.

  2. 증상

    팀의 Redis 의존 라이브러리를 쓰는 서비스들이 시작하자마자 죽는다는 보고가 운영 담당자에게 들어왔다. Spring Boot 로그를 보니 빈 초기화 중에 Redis 호스트 이름을 해석하지 못하고 있었다.

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

    Redis 의존 라이브러리를 쓰는 서비스 팀들이 시작 중에 서비스가 죽는다고 운영 담당자에게 보고하면서 문제가 처음 드러났다. 문제가 다시 나타났을 때는 팀이 Kibana 에서 호스트 이름 해석 실패를 보고 알았다.

    조치
    • 배포 매니페스트에 dnsConfig 블록을 넣어 ndots 를 4 로 낮췄다.
    • 라이브러리에서 잘못 설정된 최대 연결 풀 크기를 고쳐 새 버전을 내고 Redis 연결 수를 약 70% 줄였다.
    후속 조치
    • 이미지 라이브러리에 추가한 glibc 기반 Debian 베이스 이미지가 DNS 문제를 해결하는지 시험한다.
    • 더 새로운 Netty 버전을 쓰도록 의존성을 올린다.
    교훈

    쿠버네티스 기본값 ndots:5 에서는 리졸버가 점이 다섯 개보다 적은 외부 호스트 이름에 검색 도메인을 먼저 붙여 조회한다. 이 동작이 musl 리졸버의 NXDOMAIN 처리나 라이브러리의 DNS 리졸버 결함과 만나면 간헐적인 해석 실패가 된다. ndots 를 낮추면 대부분 서비스가 살아나지만 오래가는 해법은 아니다. 글쓴이는 이런 실패를 잡는 알림을 원했지만, 한 번씩 나는 DNS 실패마다 울리는 알림은 원하지 않는다고 했다.

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

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

원인별3

용량 한계4건

  1. IL-0048 대형 EKS 클러스터에서 CoreDNS 가 VPC DNS 리졸버로 보내는 질의가 링크 로컬 트래픽의 초당 1024 패킷 한도에 걸려 DNS 조회가 간헐적으로 타임아웃됐다.
  2. IL-0027 CoreDNS 파드가 모두 한 노드에 몰린 채 그 노드의 메모리가 고갈되자 DNS 가 응답하지 못해 아이디어스 서비스 전체가 멈췄다
  3. IL-0033 kube-dns 파드 사이의 트래픽 불균형과 DNS 초당 패킷 한도 때문에 외부 DNS 조회가 많은 여러 서비스의 지연 시간이 20초까지 늘었다
    Airbnb2019
  4. IL-0001 CoreDNS 파드가 메모리 한도 100Mi 에 걸려 OOM 으로 계속 죽으면서 쿠버네티스 클러스터 전체의 DNS 가 멈췄다

DNS·네트워크 장애2건

  1. IL-0083 멀티 테넌트 쿠버네티스 클러스터에서 노드 로컬 dnsmasq 가 동시 질의 한도에 걸리고 cluster.local 응답을 캐시하지 못한 데다 ndots 검색 도메인 질의가 CoreDNS 로 몰려, 서비스 간 호출이 간헐적인 5xx 를 냈다.
  2. IL-0047 conntrack 경합으로 DNS 조회가 5초씩 늦어져 파드 사이 요청이 간헐적으로 5초, 10초, 15초씩 지연되었다.

소프트웨어 결함1건

  1. IL-0050 ndots:5, Alpine 의 musl 리졸버, Netty 4.1.30 의 DNS 처리 문제가 겹쳐 쿠버네티스 서비스가 클러스터 밖 Redis 호스트 이름을 반복해서 해석하지 못했다