사례5건
5건 중 1~5번째
IL-0048대형 EKS 클러스터에서 CoreDNS 가 VPC DNS 리졸버로 보내는 질의가 링크 로컬 트래픽의 초당 1024 패킷 한도에 걸려 DNS 조회가 간헐적으로 타임아웃됐다.unknown2025- 증상
처음 들어온 보고는 CI 가 간헐적으로 실패한다는 것이었다. 실패는 tensorstore 안에서 났고, 오류는 ./tensorstore/util/result.h:420: Status not ok: status(): UNAVAILABLE: CURL error Could not resolve hostname: Could not resolve host: company-bucket.s3.amazonaws.com 이었다.
- 촉발
호스트 네트워크를 쓰는 시스템 관리용 파드가 몇 초마다 sudo 명령을 실행했다. sudo 는 기본 설정에서 실행할 때마다 노드 자신의 호스트 이름을 조회했다. 파드의 resolv.conf 에 있는 ndots:5 와 검색 도메인 네 개 때문에 이 조회 하나가 A 와 AAAA 를 합쳐 질의 열 번이 됐고, CoreDNS 캐시에 걸리지 않은 질의가 VPC DNS 리졸버로 몰렸다.
- 원인
- 구성 요소
- 기여 요인
- 감지
CI 가 간헐적으로 실패한다는 보고가 시작이었다. tensorstore 가 company-bucket.s3.amazonaws.com 의 DNS 조회에 실패했다는 오류를 냈다. 글쓴이는 kubectl logs 로 CoreDNS 파드 로그를 뒤져 i/o timeout 오류를 찾았다.
- 조치
- 컨테이너 이미지에 /etc/sudoers.d/00-no-fqdn 파일로 Defaults !fqdn 을 넣어 sudo 가 호스트 이름을 조회하지 않게 했다.
- 교훈
EC2 에서 링크 로컬 주소로 가는 VPC DNS 질의에는 초당 1024 패킷의 한도가 있다. 한도를 넘은 UDP 패킷은 버려지는데, 보낸 쪽은 이를 알 수 없다. 노드에서 ethtool -S eth0 | grep linklocal_allowance_exceeded 로 이 한도에 걸렸는지 볼 수 있다. ndots:5 와 검색 도메인 때문에 FQDN 이 아닌 이름 하나가 질의 다섯 번이 되고, AAAA 까지 물으면 열 번이 된다. sudo 는 기본 설정에서 실행할 때마다 호스트 이름을 조회하므로, sudo 를 자주 부르는 파드는 DNS 트래픽을 많이 만든다.
IL-0440파드가 보낸 DNS 쿼리 패킷이 노드에서 버려져 클러스터 내부 서비스의 이름 조회가 no such host 와 i/o timeout 으로 자주 실패했다Cybozu2024- 증상
파드 안의 애플리케이션이 초당 수백 건씩 클러스터 내부 서비스의 이름을 조회하자 no such host 와 i/o timeout 오류가 자주 났다. 쿠버네티스 플랫폼을 쓰는 팀은 클러스터의 DNS 서버에 성능 문제가 있다고 보고 Cloud Platform 팀에 문의했다.
- 촉발
MySQL 클러스터 감시 애플리케이션이 감시하는 클러스터 수가 늘어났고, 그 뒤부터 이름 조회 오류가 잦아졌다.
- 원인
- 구성 요소
- 기여 요인
- 감지
Cloud Platform 팀은 쿠버네티스 플랫폼을 쓰는 팀에게서 클러스터 DNS 서버에 성능 문제가 있다는 문의를 받고 알게 됐다.
- 조치
- 커널 파라미터 net.core.netdev_max_backlog 값을 늘렸다.
- softnet 지표에 알림을 설정했다.
- softnet 알림에 대응하는 런북을 마련했다.
- 후속 조치
- veth 인터페이스를 netkit 인터페이스로 바꿔 파드의 송신 패킷이 backlog 큐를 거치지 않고 물리 장치로 바로 가게 하는 방안을 검증한다. netkit 은 리눅스 커널 6.7 에 들어온 가상 네트워크 장치이고, Cilium 1.16 부터 쓸 수 있다.
- 교훈
netdev_max_backlog 를 늘리고 softnet 알림과 런북을 두면 같은 장애가 덜 나고, 나더라도 일찍 알아챌 수 있다. 다만 값을 늘리는 것은 근본 대책이 아니어서, 더 많은 패킷을 보내는 파드가 배포되면 backlog 큐가 다시 차고 패킷이 버려질 수 있다.
IL-0445EKS 로 옮기던 레거시 시스템에서 conntrack 테이블이 넘쳐 연결이 끊겼고, 이어 CoreDNS 파드가 축출될 때와 node-local-dns 를 넣은 뒤에 DNS 오류가 났다Chatwork2021- 증상
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 안정이 중요하다.
- 증상
한 서비스의 지연 시간 그래프에 5월 10일부터 스파이크가 보이기 시작했다. 처음에는 1초 안팎까지 튀었고, 이어서 5초, 다시 20초로 올라간 뒤 꽤 오랫동안 그 수준에 머물렀다.
- 촉발
여러 서비스가 외부 DNS 조회를 많이 보냈고, 그 질의가 모두 kube-dns 를 거쳤다.
- 원인
- 구성 요소
- 기여 요인
- 감지
문제는 서비스의 지연 시간 그래프에서 처음 드러났다. 같은 모양이 여러 서비스에서 나타나자 팀은 공통점을 찾았고, kube-dns 파드별 질의량을 비교해 불균형을 찾아냈다.
- 교훈
기본 설정에서 파드는 클러스터 IP 로 DNS 서버를 찾고, dnsPolicy 기본값인 ClusterFirst 때문에 외부 이름 조회도 kube-dns 를 먼저 거친다. 쿠버네티스 DNS 해석이 필요 없는 파드는 dnsPolicy 를 Default 로 두거나, None 으로 두고 세부 값을 직접 정할 수 있다. iptables 는 로드 밸런서가 아니어서 클러스터 IP 뒤의 파드에 부하를 고르게 나누지 못한다. 발표자들은 DNS 정책을 초기부터 자주 확인하고 용도에 맞는 정책을 쓰라고 했다.
- 증상
클러스터 전체 네트워크 장애를 겪은 뒤, 팀은 파드 사이 통신이 간헐적으로 늦어지고 웹 애플리케이션 전체가 이따금 느려지는 것을 알아챘다.
- 촉발
libc 리졸버가 A 레코드와 AAAA 레코드 조회를 같은 포트로 보냈고, DNAT 와 SNAT 변환이 일어나는 경로에서 conntrack 경합 조건 때문에 그중 하나가 응답을 받지 못했다.
- 원인
- 구성 요소
- 기여 요인
- 감지
웹 애플리케이션이 간헐적으로 느려지고 파드 사이 요청이 5초의 배수만큼 늦게 도착하는 것을 보고 알았다. 지연이 5초 단위라는 점에서 DNS 조회를 의심했고, tcpdump 로 확인했다.
- 조치
- 파드 스펙의 dnsConfig options 에 single-request-reopen 을 넣어 A 와 AAAA 조회가 서로 다른 포트로 나가게 했다.
- gRPC 애플리케이션의 Dockerfile 에 GRPC_DNS_RESOLVER=native 를 넣어 ares 대신 libc 리졸버를 쓰게 했다.
- `tcpdump port 53` 으로 A 와 AAAA 조회가 서로 다른 포트로 나가는 것을 확인했다.
- 교훈
지연이 5초, 10초, 15초처럼 5초의 배수로 나타나면 DNS 조회 재시도를 먼저 의심한다. 리눅스 이미지는 파드 dnsConfig 에 single-request-reopen 을 넣으면 된다. gRPC 는 기본 리졸버가 libc 를 쓰지 않을 수 있으므로 GRPC_DNS_RESOLVER=native 도 함께 설정해야 한다. 설정이 먹었는지는 tcpdump 로 A 와 AAAA 조회가 나가는 포트를 보고 확인한다.
이 5건에서 가장 많이 나오는 구성 요소: 클라이언트 쪽 DNS 리졸버와 캐시, conntrack 테이블. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.
원인별2
용량 한계4건
IL-0048대형 EKS 클러스터에서 CoreDNS 가 VPC DNS 리졸버로 보내는 질의가 링크 로컬 트래픽의 초당 1024 패킷 한도에 걸려 DNS 조회가 간헐적으로 타임아웃됐다.unknown2025IL-0440파드가 보낸 DNS 쿼리 패킷이 노드에서 버려져 클러스터 내부 서비스의 이름 조회가 no such host 와 i/o timeout 으로 자주 실패했다Cybozu2024IL-0445EKS 로 옮기던 레거시 시스템에서 conntrack 테이블이 넘쳐 연결이 끊겼고, 이어 CoreDNS 파드가 축출될 때와 node-local-dns 를 넣은 뒤에 DNS 오류가 났다Chatwork2021IL-0033kube-dns 파드 사이의 트래픽 불균형과 DNS 초당 패킷 한도 때문에 외부 DNS 조회가 많은 여러 서비스의 지연 시간이 20초까지 늘었다Airbnb2019
DNS·네트워크 장애1건
- 기여 요인