IL-0048 unknown · 2025-08-12 (게시일)kubernetesawsnetworking
글쓴이의 팀은 아주 큰 AWS EKS 클러스터를 운영한다. CI 가 간헐적으로 실패한다는 보고를 따라가 보니 DNS 조회 실패였다. CoreDNS 로그에는 VPC 의 Route 53 리졸버로 보낸 UDP 질의가 i/o timeout 으로 끝난 기록이 남아 있었다.
AWS 지원 케이스로 첫 번째 원인을 찾았다. 링크 로컬 주소를 쓰는 서비스에는 ENI 마다 초당 1024 패킷의 한도가 있다. CoreDNS 는 UDP 로 질의를 링크 로컬 주소의 Route 53 리졸버에 보낸다. 한도를 넘은 패킷은 버려지고, UDP 는 연결이 없는 프로토콜이라 보낸 쪽은 패킷이 버려진 줄 모른 채 타임아웃을 맞는다. 영향을 받은 노드에서 linklocal_allowance_exceeded 값이 0 이 아니었다.
CoreDNS 가 도는 노드에서 tcpdump 로 DNS 트래픽을 잡아 많이 나온 이름을 세어 보니, 호스트 이름처럼 생긴 질의가 롱테일을 이루고 있었다. 이름마다 검색 도메인이 붙은 질의가 다섯 번씩 나왔다. 파드의 /etc/resolv.conf 에는 검색 도메인 네 개와 options ndots:5 가 있었다. 점이 다섯 개보다 적은 이름은 FQDN 이 아닌 것으로 보고 검색 도메인을 하나씩 붙여 물어보므로, 질의 하나가 다섯 번이 되고 A 와 AAAA 를 합치면 열 번이 된다. 이런 질의는 CoreDNS 캐시에 걸리지 않아 그대로 VPC DNS 리졸버로 나갔다.
질의에 붙은 검색 도메인으로 요청한 파드의 네임스페이스가 app-namespace 라는 것을 알았다. EC2 호스트 이름을 묻는 것으로 보아 호스트 네트워크를 쓰는 파드라고 짐작했다. 그 파드에서 tcpdump 를 돌리자 몇 초마다 노드 자신의 호스트 이름을 묻는 A 와 AAAA 질의가 나왔다. 파드의 주 루프 코드를 절반씩 잘라 내는 이진 탐색으로 원인을 sudo 호출 몇 개로 좁혔다. 같은 명령을 sudo 없이 실행하면 DNS 트래픽이 없었다. ltrace 로 보니 sudoers.so 가 getaddrinfo 로 호스트 이름을 조회하고 있었다. DNS 질의를 만든 쪽은 실행된 명령이 아니라 sudo 자신이었다.
컨테이너 이미지에 Defaults !fqdn 을 넣어 sudo 의 호스트 이름 조회를 껐다. 그 뒤 캐시에 걸리지 않는 DNS 질의가 거의 모두 사라졌다.
처음 들어온 보고는 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 이었다.
실패는 여러 인스턴스에서 일정하지 않게 났다. curl 의 CURLE_COULDNT_RESOLVE_HOST 는 너무 일반적인 오류여서 DNS 조회 로그를 직접 봐야 했다.
CoreDNS 파드 로그에는 [ERROR] plugin/errors: 2 company-bucket.s3.amazonaws.com. A: read udp 10.1.2.3:44211->10.0.0.2:53: i/o timeout 같은 오류가 있었다. 10.1.2.3 은 CoreDNS 파드이고 10.0.0.2 는 VPC 의 Route 53 리졸버다. 실패한 조회는 대부분 ip-10-8-1-3.us-east-2.compute.internal 같은 내부 호스트 이름이었고, IPv6 주소를 묻는 AAAA 질의가 많았다. 보통은 IPv4 응답만 필요한데 A 와 AAAA 를 둘 다 물어서 트래픽이 두 배가 됐다.
AWS 지원 케이스에서 링크 로컬 주소를 쓰는 서비스에는 초당 1024 패킷의 한도가 있고 이 한도는 올릴 수 없다는 답을 받았다. 영향을 받은 노드에서 AWS 가 알려 준 명령 ethtool -S eth0 | grep linklocal_allowance_exceeded 를 돌리자 0 이 아닌 값이 나왔다.
원인 ? 용량 한계
CI 가 간헐적으로 실패한다는 보고가 시작이었다. tensorstore 가 company-bucket.s3.amazonaws.com 의 DNS 조회에 실패했다는 오류를 냈다. 글쓴이는 kubectl logs 로 CoreDNS 파드 로그를 뒤져 i/o timeout 오류를 찾았다.
–
EC2 에서 링크 로컬 주소로 가는 VPC DNS 질의에는 초당 1024 패킷의 한도가 있다. 한도를 넘은 UDP 패킷은 버려지는데, 보낸 쪽은 이를 알 수 없다. 노드에서 ethtool -S eth0 | grep linklocal_allowance_exceeded 로 이 한도에 걸렸는지 볼 수 있다. ndots:5 와 검색 도메인 때문에 FQDN 이 아닌 이름 하나가 질의 다섯 번이 되고, AAAA 까지 물으면 열 번이 된다. sudo 는 기본 설정에서 실행할 때마다 호스트 이름을 조회하므로, sudo 를 자주 부르는 파드는 DNS 트래픽을 많이 만든다.
같은 원인 · 공통 클라이언트 쪽 DNS 리졸버와 캐시, CoreDNS
같은 원인 · 공통 클라이언트 쪽 DNS 리졸버와 캐시, CoreDNS
같은 원인 · 공통 CoreDNS
같은 원인 · 공통 CoreDNS
같은 원인 · 공통 CoreDNS
같은 원인 · 공통 CoreDNS
같은 원인 · 공통 CoreDNS
같은 원인 · 공통 클라이언트 쪽 DNS 리졸버와 캐시