지난주 화요일 새벽 3시 반, 옆에서 자던 폰이 미친듯이 진동했다. 우리 팀 결제 서비스 P99가 800ms를 찍고 있다는 알림. 평소엔 40ms 언저리인 놈이었다.
멘탈 반쯤 나간 채로 대시보드를 열었더니, 애플리케이션 지연은 오히려 낮은데 external HTTP 호출 지연만 튀고 있었다. 그리고 DNS 쿼리 카운트가 평소의 6배. CoreDNS 파드 CPU가 70%를 넘기고 있었다. 노드 12대 클러스터에 그리 크지도 않은 서비스인데 왜 이렇게.
범인은 ndots:5
/etc/resolv.conf를 파드에 들어가서 찍어보니 예상대로 options ndots:5. 쿠버네티스 기본값이다. 이게 뭘 하냐면, 점(.)이 5개 미만인 도메인은 절대 도메인으로 안 보고 search path를 전부 순회한다는 뜻이다.
우리 코드에서 호출하는 외부 API 주소가 api.some-vendor.io 였는데, 점이 2개니까 CoreDNS는 이 순서로 조회한다.
api.some-vendor.io.default.svc.cluster.local
api.some-vendor.io.svc.cluster.local
api.some-vendor.io.cluster.local
api.some-vendor.io.ap-northeast-2.compute.internal
api.some-vendor.io ← 여기서 드디어 성공
한 번의 외부 호출당 최소 4번의 NXDOMAIN을 먹고 5번째에 성공. IPv4/IPv6 둘 다 조회하니까 실질적으로 8번의 왕복. 트래픽이 살짝만 튀어도 CoreDNS가 못 버티는 이유가 여기 있었다.
시도 1: dnsPolicy 만지기 (실패)
처음엔 dnsPolicy: Default로 바꿔볼까 했다. 근데 이러면 클러스터 내부 서비스 디스커버리가 아예 안 된다. 우리 서비스는 다른 내부 API도 부르니까 사망 확정. 롤백.
시도 2: FQDN 뒤에 점 붙이기 (부분 성공)
api.some-vendor.io. — 뒤에 점을 붙이면 절대 도메인으로 처리돼서 search path를 건너뛴다. 근데 이걸 하려면 애플리케이션 코드를 다 뜯어고쳐야 한다. 새벽 3시 반에 할 짓이 아니었다.
시도 3: dnsConfig로 ndots 낮추기 (진짜 해결)
결국 파드 스펙에 dnsConfig를 박아서 ndots를 2로 낮췄다.
spec:
dnsPolicy: ClusterFirst
dnsConfig:
options:
- name: ndots
value: "2"
- name: single-request-reopen
배포하고 30초 뒤 DNS 쿼리가 원래대로 돌아왔다. P99도 정상화. 새벽 4시 반쯤 침대로 복귀.
왜 진작 안 낮췄나
쿠버네티스가 ndots:5를 기본으로 두는 이유는 있다. myservice처럼 짧은 이름으로 파드에서 서비스를 부를 수 있게 하려고. 근데 사실 우리 팀 코드에서 그런 짧은 이름을 쓰는 곳은 거의 없다. 다들 myservice.namespace.svc.cluster.local을 명시하거나 환경변수로 주입받는다.
ndots:2 정도로만 낮춰도 .svc.cluster.local 붙은 내부 호출은 여전히 search path 안 타고 바로 성공한다. 오히려 외부 도메인 호출이 훨씬 빨라진다.
그럼 왜 갑자기 그 새벽에 터졌나
이게 사실 미스터리였다. 트래픽 자체는 그렇게 안 튀었거든. 나중에 뜯어보니 그날 새로 배포된 결제 벤더 SDK가 헬스체크 목적으로 매 5초마다 외부 API를 새로 resolve하고 있었다. 캐싱 없이. 파드 200개가 동시에 5초마다 NXDOMAIN 4개씩 쏘니 CoreDNS 입장에선 재난.
벤더 SDK 옵션에 dns_cache_ttl 설정을 켜니 이것도 크게 완화됐다. 근본은 ndots:5 튜닝이지만.
남은 숙제
CoreDNS 자체에도 autopath 플러그인이라는 게 있다. 워크로드 코드나 dnsConfig 안 건드리고 CoreDNS 쪽에서 search path 순회를 스마트하게 처리해주는 건데, 우리 클러스터에는 아직 안 켜져 있다. 켜면 kubelet에서 파드 정보를 CoreDNS에게 알려줘야 해서 RBAC 조정이 필요하고, 리소스 사용량도 살짝 늘어난다고 한다.
다음 주에 스테이징에서 한 번 테스트해볼 예정. 결과 나오면 업데이트하겠다.
혹시 다른 팀에서는 CoreDNS + ndots 문제 어떻게 해결하시는지 궁금하다. NodeLocal DNSCache 쓰시는 분들도 있는 것 같던데.
'IT > 기타' 카테고리의 다른 글
| Backstage vs Port, 우리 팀은 뭘 골랐을까 (0) | 2026.09.07 |
|---|---|
| Envoy Gateway vs NGINX Gateway Fabric, 뭘 쓸까 (0) | 2026.08.30 |
| Cilium ClusterMesh vs Submariner, 뭘 쓸까 (0) | 2026.08.26 |
| Istio Ambient의 ztunnel 뜯어보기: HBONE 터널링과 노드 단위 L4 (0) | 2026.08.21 |
| CoreDNS NXDOMAIN 캐시가 만든 30초 지옥, ndots:5의 그림자 (0) | 2026.08.19 |