들어가기 전에
쿠버네티스에서 여러 노드의 서비스에 접근하기 위해 coreDNS에 DNS 쿼리를 날려 레코드 조회를 할 수 있습니다.
DNS 이름에는 규칙이 존재하는데, 다음과 같은 A/AAAA 레코드를 따릅니다.
my-svc.my-namespace.svc.cluster-domain
예를 들어, newdeal이라는 네임스페이스에 속한 nginx 가 있다고 했을 때 이 서비스에 접근하는 도메인은 nginx.newdeal.svc.cluster.local입니다. 서비스와 네임스페이스를 연결한 다음에 마지막에 svc.cluster.local을 붙이면 됩니다.
하지만 다음과 같은 short-form 형식의 도메인으로도 서비스에 접근할 수 있습니다.
my-svc.my-namespace
my-svc.my-namespace.svc
The Question start with ...


처음 이 문제를 파게 된 계기는 다음과 같습니다.
파드에 쉘 접속하여 nslookup 명령을 실행했을 때, 서비스. 네임스페이스. 클러스터도메인으로 질의했을 때는 ip를 잘 가져오는데, 서비스.네임스페이스 로 질의했을 때는 실패를 반환합니다.

curl로 확인할 수 있는 애플리케이션단에서는 short DNS(서비스.네임스페이스)도 통신을 잘하는데 이상합니다. nslookup이 short DNS 쿼리를 실패하는 이유는 무엇일까요.
Pod에서 DNS를 조회하기 위해서

먼저 Pod내부 컨테이너에서 DNS 쿼리 하기 위해 어떤 과정을 거치는 지를 살펴볼까요?
브라우저에서 DNS 쿼리를 조회하는 것처럼, 파드에서도 로컬 DNS 설정을 먼저 확인합니다. etc/resolv.conf 설정을 확인해 보면,
# cat resolv.conf
nameserver 100.64.0.10
search newdeal.svc.cluster.local svc.cluster.local cluster.local ap-northeast-2.compute.internal
options ndots:5
다음과 같은 설정을 띄고 있는데, 다음 쿠버네티스 문서에서 자세한 설명을 볼 수 있습니다.
기본적으로 Kubelet에서 제공하는 /etc/resolv.conf 파일은 모든 DNS 쿼리를 클러스터의 DNS 서버로 전달합니다. Kubelet은 또 search domain과 ndots DNS 쿼리 옵션을 정의합니다.
search domain은 short DNS이 제공될 때 추가해서 검색해야 하는 도메인 접미사를 지정합니다.
ndots옵션은 먼저 search domain을 추가할지, absolute domain에 대한 쿼리를 바로 수행할지를 결정합니다. absolute domain이란 사용자가 질의한 원래의 도메인 이름을 말합니다.
예를 들어, short DNS (서비스.네임스페이스 , ex: nginx.newdeal )로 DNS 조회를 수행한다고 가정할 때, ndots옵션이 5(기본값)로 설정되어 있으면 resolver는 도메인의 점 수를 계산합니다.
점이 5개 미만이면 DNS 서버에서 DNS 조회가 수행되기 전에 search domain이 추가됩니다. 점이 5개 이상인 경우 search domain을 추가하지 않고 있는 그대로 도메인을 쿼리 합니다. nginx.newdeal 는 점이 5개 미만이므로 DNS 조회가 수행되기 전에 검색 도메인이 추가됩니다.
시뮬레이션해보자면,
nginx.newdeal.newdeal.svc.cluster.local 로 DNS 조회하지만 실패합니다.
nginx.newdeal.svc.cluster.local DNS 조회 성공으로 ip를 가져옵니다. yay!
다음과 같이 동작하는 것이죠.
nslookup의 동작과정은 다르다
short domain을 쓰지 않고 풀 도메인 네임을 사용하면 coreDNS는 잘 응답할 수 있습니다.
하지만 short domain을 사용하면 resolver가 search domain을 추가하고, 순서대로 수행하다가 DNS 쿼리가 성공하면 ip를 가져오게 되겠죠?
중요한 점은 coreDNS는 short domain을 전혀 모른다는 점이고, 여기서 nslookup이 동작을 실패한다고 볼 수 있습니다.
만약 short domain을 바로 쿼리 한다면,
1. 클라이언트는 short domain를 coreDNS에 보냅니다.
2. coreDNS는 그것에 대해 아무것도 모르고 외부 DNS 네임 서버로 전달합니다.
3. 외부 DNS 네임 서버가 short domain에 대해 ERROR를 반환합니다. (nginx.newdeal? 이건 뭐지)
4. coreDNS는 실패를 클라이언트에 전달합니다.
결국 nslookup 동작 과정 중 DNS resolver가 개입하지 않으니(search domain을 추가하지 못함.) short domain에 대해 클라이언트는 NXDOMAIN 응답(살패)만 받는 것입니다.
정리
추후에 DNS 쿼리 network latency를 줄이기 위해서는 resolv.conf를 coreDNS나 localDNS 설정에서 직접 적절하게 수정한다면, resolver는 순서대로 search domain을 추가하니 불필요한 홉 과정을 줄일 수 있습니다.
참조
The life of a DNS query in Kubernetes — NsLookup learning
short-form dns query *nslookup kubernetes.default* not working
'🏋️♀️ DevOps, SRE' 카테고리의 다른 글
쿠버네티스의 4가지 설계 원칙 : Understand the "Why?" (1) | 2023.06.04 |
---|---|
신입 데브옵스 (DevOps) 엔지니어 되기 - (2) Drone CI 마이그레이션 하기 (2) | 2023.04.16 |
신입 데브옵스 (DevOps) 엔지니어 되기 - (1) (27) | 2023.02.06 |
[k8s] Kubernetes CronJob 뜯어보기 - 구현 원리, best practices (4) | 2022.11.15 |
주니어 DevOps 엔지니어가 바라 본 CPU 아키텍처 (docker pull이 안 된다!) (1) | 2022.10.21 |
들어가기 전에
쿠버네티스에서 여러 노드의 서비스에 접근하기 위해 coreDNS에 DNS 쿼리를 날려 레코드 조회를 할 수 있습니다.
DNS 이름에는 규칙이 존재하는데, 다음과 같은 A/AAAA 레코드를 따릅니다.
my-svc.my-namespace.svc.cluster-domain
예를 들어, newdeal이라는 네임스페이스에 속한 nginx 가 있다고 했을 때 이 서비스에 접근하는 도메인은 nginx.newdeal.svc.cluster.local입니다. 서비스와 네임스페이스를 연결한 다음에 마지막에 svc.cluster.local을 붙이면 됩니다.
하지만 다음과 같은 short-form 형식의 도메인으로도 서비스에 접근할 수 있습니다.
my-svc.my-namespace
my-svc.my-namespace.svc
The Question start with ...


처음 이 문제를 파게 된 계기는 다음과 같습니다.
파드에 쉘 접속하여 nslookup 명령을 실행했을 때, 서비스. 네임스페이스. 클러스터도메인으로 질의했을 때는 ip를 잘 가져오는데, 서비스.네임스페이스 로 질의했을 때는 실패를 반환합니다.

curl로 확인할 수 있는 애플리케이션단에서는 short DNS(서비스.네임스페이스)도 통신을 잘하는데 이상합니다. nslookup이 short DNS 쿼리를 실패하는 이유는 무엇일까요.
Pod에서 DNS를 조회하기 위해서

먼저 Pod내부 컨테이너에서 DNS 쿼리 하기 위해 어떤 과정을 거치는 지를 살펴볼까요?
브라우저에서 DNS 쿼리를 조회하는 것처럼, 파드에서도 로컬 DNS 설정을 먼저 확인합니다. etc/resolv.conf 설정을 확인해 보면,
# cat resolv.conf
nameserver 100.64.0.10
search newdeal.svc.cluster.local svc.cluster.local cluster.local ap-northeast-2.compute.internal
options ndots:5
다음과 같은 설정을 띄고 있는데, 다음 쿠버네티스 문서에서 자세한 설명을 볼 수 있습니다.
기본적으로 Kubelet에서 제공하는 /etc/resolv.conf 파일은 모든 DNS 쿼리를 클러스터의 DNS 서버로 전달합니다. Kubelet은 또 search domain과 ndots DNS 쿼리 옵션을 정의합니다.
search domain은 short DNS이 제공될 때 추가해서 검색해야 하는 도메인 접미사를 지정합니다.
ndots옵션은 먼저 search domain을 추가할지, absolute domain에 대한 쿼리를 바로 수행할지를 결정합니다. absolute domain이란 사용자가 질의한 원래의 도메인 이름을 말합니다.
예를 들어, short DNS (서비스.네임스페이스 , ex: nginx.newdeal )로 DNS 조회를 수행한다고 가정할 때, ndots옵션이 5(기본값)로 설정되어 있으면 resolver는 도메인의 점 수를 계산합니다.
점이 5개 미만이면 DNS 서버에서 DNS 조회가 수행되기 전에 search domain이 추가됩니다. 점이 5개 이상인 경우 search domain을 추가하지 않고 있는 그대로 도메인을 쿼리 합니다. nginx.newdeal 는 점이 5개 미만이므로 DNS 조회가 수행되기 전에 검색 도메인이 추가됩니다.
시뮬레이션해보자면,
nginx.newdeal.newdeal.svc.cluster.local 로 DNS 조회하지만 실패합니다.
nginx.newdeal.svc.cluster.local DNS 조회 성공으로 ip를 가져옵니다. yay!
다음과 같이 동작하는 것이죠.
nslookup의 동작과정은 다르다
short domain을 쓰지 않고 풀 도메인 네임을 사용하면 coreDNS는 잘 응답할 수 있습니다.
하지만 short domain을 사용하면 resolver가 search domain을 추가하고, 순서대로 수행하다가 DNS 쿼리가 성공하면 ip를 가져오게 되겠죠?
중요한 점은 coreDNS는 short domain을 전혀 모른다는 점이고, 여기서 nslookup이 동작을 실패한다고 볼 수 있습니다.
만약 short domain을 바로 쿼리 한다면,
1. 클라이언트는 short domain를 coreDNS에 보냅니다.
2. coreDNS는 그것에 대해 아무것도 모르고 외부 DNS 네임 서버로 전달합니다.
3. 외부 DNS 네임 서버가 short domain에 대해 ERROR를 반환합니다. (nginx.newdeal? 이건 뭐지)
4. coreDNS는 실패를 클라이언트에 전달합니다.
결국 nslookup 동작 과정 중 DNS resolver가 개입하지 않으니(search domain을 추가하지 못함.) short domain에 대해 클라이언트는 NXDOMAIN 응답(살패)만 받는 것입니다.
정리
추후에 DNS 쿼리 network latency를 줄이기 위해서는 resolv.conf를 coreDNS나 localDNS 설정에서 직접 적절하게 수정한다면, resolver는 순서대로 search domain을 추가하니 불필요한 홉 과정을 줄일 수 있습니다.
참조
The life of a DNS query in Kubernetes — NsLookup learning
short-form dns query *nslookup kubernetes.default* not working
'🏋️♀️ DevOps, SRE' 카테고리의 다른 글
쿠버네티스의 4가지 설계 원칙 : Understand the "Why?" (1) | 2023.06.04 |
---|---|
신입 데브옵스 (DevOps) 엔지니어 되기 - (2) Drone CI 마이그레이션 하기 (2) | 2023.04.16 |
신입 데브옵스 (DevOps) 엔지니어 되기 - (1) (27) | 2023.02.06 |
[k8s] Kubernetes CronJob 뜯어보기 - 구현 원리, best practices (4) | 2022.11.15 |
주니어 DevOps 엔지니어가 바라 본 CPU 아키텍처 (docker pull이 안 된다!) (1) | 2022.10.21 |