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

그래프

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

사례3건

3건 중 1~3번째

  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. 증상

    스크립트 실행 기반을 쿠버네티스로 옮긴 Croquet 를 사내에 공개한 뒤, 개발자들은 kubectl 명령이 느리다고 했다. 사용자들은 노트북과 서비스가 가끔 시작되지 않는다고 알렸다.

    촉발

    자체 인프라 Bocce 에서 쿠버네티스로 옮긴 스크립트 실행 기반 Croquet 를 2018년 9월 사내에 공개했다. 대량의 스크립트가 몰리면서 클러스터가 EC2 인스턴스 약 290대로 커졌고, 노드마다 도는 Datadog 에이전트가 쿠버네티스 API 를 폴링하는 부하도 함께 늘었다.

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

    개발자들이 kubectl 명령이 느리다고 했고, 사용자들은 노트북과 서비스가 가끔 시작되지 않는다고 알렸다. 마스터 노드의 CPU 사용률이 높았고, 조사해 보니 API 서버 컨테이너 세 개가 CPU 를 꽉 채워 쓰고 있었다. 당시 팀이 볼 수 있던 지표는 마스터 노드 CPU 의 CloudWatch 지표와 Datadog 의 컨테이너별 CPU, 메모리 지표였다. API 요청 처리량과 5xx 오류율과 요청 지연은 볼 수 없었다.

    조치
    • 사내 사용자들을 예전 인프라로 되돌려 클러스터를 안정시켰다.
    • 마스터 노드를 m4.large 세 대에서 m4.4xlarge 세 대로 키웠다.
    • 노드마다 도는 Datadog 에이전트가 서비스 메타데이터를 얻으려고 API 서버를 폴링하지 않도록 Datadog 설정을 바꿨다.
    • 상태를 바꾸지 않는 요청의 max-requests-inflight 한도를 400 에서 1200 으로 올렸다.
    • etcd 의 EBS 볼륨을 20 GB 에서 100 GB 로 늘려 IOPS 를 100 에서 300 으로 올렸다.
    • 스크립트의 DNS 정책을 ClusterFirst 에서 Default 로 바꿔 DNS 타임아웃을 줄였다.
    후속 조치
    • Kops 가 안전한 이전을 지원하면 etcd 를 2.2.1 에서 3.x 로 올린다.
    • 스크립트가 클러스터 안의 다른 워크로드와 통신할 수 있도록 DNS 타임아웃 문제를 근본적으로 해결한다.
    교훈

    가장 큰 실수는 쿠버네티스가 모든 것을 알아서 해 준다고 가정한 것이었다. 쿠버네티스는 노드 5,000대와 파드 100,000개를 지원한다고 하지만, 그 규모에 이르려면 손봐야 할 설정이 많다. 클러스터에 넣는 서드파티 도구, 특히 DaemonSet 을 조심해야 한다. 많은 도구가 보통 규모에 맞춰 만들어졌고 큰 규모에서는 시험되지 않았다. 클러스터 상태를 watch 하는 서비스가 데이터를 지나치게 많이 가져가도록 설계되면 규모 문제가 생긴다. kube2iam 은 모든 파드의 메타데이터를 메모리에 들고 있다가 메모리가 바닥났고, Fluentd Kubernetes Metadata Filter 플러그인도 같은 문제가 있다. 대개 설정 하나로 고칠 수 있지만, 부하 테스트를 해 보기 전에는 잘 드러나지 않는다.

  3. 증상

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

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

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

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

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

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

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

원인별3