본문 바로가기

AWS

[EKS] CoreDNS 운영 시 소소한 팁 (Rcode, ndots)

반응형

1. 개요

필자의 회사는 모니터링 서비스로 Datadog을 이용하고 있는데 CoreDNS 쪽에서 특이사항을 발견했다.

바로 rcode 중 nxdomain 수치가 높다는 점이였다.

 

nxdomain는 non-existing domain name의 약자로 domain name이 존재하지 않다는 뜻이다. 즉, CoreDNS 에서 질의를 했을 때 domain name이 존재하지 않는 메트릭이 다소 발생한다는 뜻이다.

 

2. 원인

원인은 다음과 같다.

bash-4.2# cat /etc/resolv.conf
search testdemoapp-dev.svc.cluster.local svc.cluster.local cluster.local ap-northeast-2.compute.internal
nameserver 172.20.0.10
options ndots:5

 

[1] search

질의를 요청하는 Client Pod는 resolve.conf에 기입된 대로 search에 나열된 도메인 목록을 차례대로 붙여가며 추가로 DNS 서버 (정확히는 CoreDNS)를 호출한다.

 

질의 순서는 다음과 같다. ( /etc/resolve.conf )

{내가 질의 요청을 보낸 도메인 이름}.testdemoapp-dev.svc.cluster.local
{내가 질의 요청을 보낸 도메인 이름}.svc.cluster.local
{내가 질의 요청을 보낸 도메인 이름}.cluster.local
{내가 질의 요청을 보낸 도메인 이름}.ap-northeast-2.compute.internal

 

 

[2] ndots

nodts는 FQDN으로 취급될 도메인에 포함될 .(점)의 최소 개수이다.

 

DB는 대부분 RDS를 사용하는데 RDS는 보통 mydb.123456789012.ap-northeast-2.rds.amazonaws.com 와 같은 형태로 도메인 이름이 구성되어 있는데, .의 갯수가 5개이다.


이런 경우에는 .의 갯수가 5개이기 때문에 ndots의 범위 내에 포함되어 CoreDNS의 domain search list를 붙여가며 순차적으로 질의하고,
nxdomain를 모두 반환받을 경우 그제서야 외부 도메인 서버 (아마도 VPC 내 도메인 서버를 먼저 하고 그 다음에 Google 등등)이 되지 않을까 싶다.

 

 

3. 해결 방법

디버깅을 하기 위해 임시로 log 수집 수행 후 coredns 파드 rollout

 

 

[1] 만약 외부 FQDN 호출 시 맨 마지막에 .을 붙여준다면 딱 1번만 CoreDNS 서버에게 질의할 수 있게 된다.

-> CoreDNS가 불필요하게 search에 정의된 도메인을 계속 붙여가면서 질의하는 과정이 줄어든다.

 

하지만 각 서비스 Application 단에서 작업을 해줘야 하기 때문에 개발자들에게 요청을 해야 한다..

 

 

 

# 만약 nyyang.tistory.com. 처럼 맨 뒤에 .을 붙이면 딱 1번 질의를 수행한다.

단, 이 경우는 외부 FQDN일 경우에만 해야 함

 

# 없는 도메인에 접근할 경우

: 맨 뒤에 .을 붙이면 nxdomain 레코드가 있든 말든 도메인 질의를 딱 1번 수행한다. 만약 .을 붙이지 않았다면 search 리스트에 정의된 도메인 이름들을 붙여가면서 coredns의 부하만 가중시켰을 것이다.

 

bash-4.2# nslookup mydb.123456789012.ap-northeast-2.rds.amazonaws.com.

 

 

 

[2] ndots을 1 혹은 2로 설정

보통 외부 FQDN의 경우 blah.blah.blah.com 이런식으로 dot의 갯수가 많아진다.

 

고로 ndots을 설정하여 .의 갯수가 많을 경우 맨 처음에 질의할 때 CoreDNS의 search domain list을 붙여가며 질의하지 않도록 할 수 있다.

 

Pod dnsConfig에 ndots 옵션을 1로 설정해준다.
이는 Pod 개별 설정이고 kubelet 혹은 Managed nodegroup With Launch template일 경우 userdata에 설정하여 노드 단위로도 수행할 수 있으나 테스트이기 때문에 아래와 같이 Pod 단위로 설정하였다.

 

Pod를 재기동하면 아래와 같이 ndots 값이 변경된 것을 확인할 수 있다.

 

 

dot의 갯수가 2개이기 때문에 CoreDNS가 바로 FQDN으로 인식하여 nyyang.tistory.com. 을 질의 수행한다.

-> 맨 마지막에 .을 붙이지 않아도 CoreDNS가 FQDN으로 취급한다

 

 

- ndots : 1로 설정할 경우에 도메인에 포함된 점(.)의 개수가 1개부터 FQDN으로 취급한다는 의미

 

참고 : /etc/resolve.conf에 정의된 search domain list


{namespace}.svc.cluster.local
svc.cluster.local 
cluster.local 
ap-northeast-2.compute.internal

 

 

그럼 다양한 케이스들을 확인해보자

테스트는 ndots:1로 설정했을 때이다.

 

 

[1] dot 0개

 

Client 입장인 Pod는 testdemoapp-dev에 대한 질의 요청을 보냈다.
당연히 172.20.0.10은 CoreDNS 예약 주소이기 때문에 CoreDNS에게 질의를 수행한다.

 

dot이 0개이기 때문에 search에 정의된대로 {질의요청보낸도메인}.{namespace}.svc.cluster.local 으로 질의 수행

 

 

[2] dot 1개 :보통 다른 Namespace일 경우 {service}.{namespace}로 접근해야 하기 때문

 

원래같았으면 {질의요청보낸도메인}.{namespace}.svc.cluster.local 로 질의를 수행했겠지만 ndots을 1로 설정했기 때문에 FQDN으로 인식하여 {질의요청보낸도메인}으로 질의를 수행한다.

 

결과가 NXDOMAIN로 나왔기 때문에 {질의요청보낸도메인}.{namespace}.svc.cluster.local를 수행한다.

NOERROR가 반환되기 때문에 더이상 질의를 수행하지 않는다.

 

 

4.  결론

ndots을 1로 설정하면 {service}.{namespace}로 질의할 때 맨 처음은 무조건 실패한다.

 

ndots을 2로 설정하면 {service}.{namespace}로 질의해도 맨 처음 질의는 실패하겠지만 2번째가 svc.cluster.local 이기 때문에 

{service}.{namespace} + svc.cluster.local 에 대해 noerror 레코드가 반환되어 도메인 질의에 성공할 것이다.

 

또한 외부 도메인일 경우 보통 문자.dev.blah.com 이런식의 형태거나 회원정보.prod.blah.com 혹은 캐시.prod.blah.com 일텐데 이러한 도메인에 대해 ndots를 2로 설정하면 바로 외부 도메인 질의를 수행하기 때문에...

 

결론은 ndots를 2로 설정하는게 좋지 않을까 싶다.

 

NodeLocal DNS Cache도 리서치해봤지만 아직 시기상조인듯하여 이정도만 튜닝해두면 충분할 것 같다.

 

 

 

반응형