https://velog.io/@dhkim1522/Linux에서 DNS를 관리하는 방법
CoreDNS는 CNCF 재단에서 관리하는 프로젝트이다. CoreDNS는 v.1.12 이후로 kubernetes에서 사용을 권장하고 있는 도메인 서버 서비스이다. CoreDNS는 클러스터를 지속적으로 모니터링하며, 새로운 Service 혹은 Pod이 추가되는 경우, 도메인 서버에 이를 업데이트한다.
kubernetes 클러스터 설치 후 자동으로 kube-system이라는 네임스페이스에 해당 coredns 리소스들이 배포된다.
[root@cmp-kube-master ~]# kubectl get all -n kube-system | grep coredns
pod/coredns-8467766cc7-lr8tt 1/1 Running 0 16d
pod/coredns-8467766cc7-szdt5 1/1 Running 1 (46h ago) 16d
service/cmp-dev-infra-coredns ClusterIP None <none> 9153/TCP 2d2h
service/coredns ClusterIP 10.233.0.3 <none> 53/UDP,53/TCP,9153/TCP 31d
deployment.apps/coredns 2/2 2 2 31d
replicaset.apps/coredns-546484589d 0 0 0 31d
replicaset.apps/coredns-5b677c76cc 0 0 0 30d
replicaset.apps/coredns-74ff684f6 0 0 0 16d
replicaset.apps/coredns-8467766cc7 2 2 2 16d
kubelet은 새로운 Pod가 생성될 때에, Pod의 /etc/resolv.conf
파일에 clusterDNS 서버의 IP 주소를 추가하여
Pod에서 my-service.default.svc.cluster.local
과 같은 클러스터 내부의 DNS를 사용할 수 있도록 해준다.
$ kubectl exec -it my-pod -- cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5
/etc/resolv.conf 파일 내 구성 요소들의 의미는 아래와 같다.
FQDN : FQDN은 Fully Qualified Domain Name의 약자로 '절대 도메인 네임' 또는 '전체 도메인 네임' 이라고도 불리는. 도메인 전체 이름을 표기하는 방식을 의미한다.
다른 pod 내부로 접근하여 특정 Service DNS로 nslookup
명령어를 수행해보면 다음과 같이 출력된다.
$ kubectl exec -it my-pod -- /bin/sh
$ nslookup my-service
Server: 169.254.25.10
Address: 169.254.25.10:53
** server can't find my-pod.svc.cluster.local: NXDOMAIN
** server can't find my-pod.svc.cluster.local: NXDOMAIN
Name: my-pod.symphony.svc.cluster.local
Address: 10.233.49.158
위 와 같은 경우 다른 Pod 내부에서
my-pod.symphony.svc.cluster.local
와 같은 경로로 요청 시 dns service를 통해 해당 Pod로 요청이 전달된다.
ex) curl my-pod.symphony.svc.cluster.local:{port}/{api_endpoint}
FQDN은 위에서 살펴 본 /etc/resolv.conf 설정에서 options 값에 있는 ndots
과 관련이 있다. ndots:5 라는 의미는 도메인에 포함된 점(.)의 개수가 5개부터 FQDN으로 취급한다는 의미이다.
만약 어떤 POD에서 test.good.nice.awesome.jonnund.dev 같은 도메인을 찾으려고 한다면, 이 도메인은 FQDN이기 때문에 클라이언트는test.good.nice.awesome.jonnung.dev.형태로 DNS 서버에 질의를 하게 된다.
하지만 /etc/resolv.conf 에서 중 한가지 더 고려해야 중요한 옵션이 있다.
바로 search
옵션이다. 이 옵션에는 부분적인 도메인 목록들을 지정한다. 즉, 클라이언트가 DNS 서버로부터 결과가 없다는 응답을 받으면, 이 부분 도메인 목록을 차례대로 붙여가며 추가로 DNS 서버를 호출한다.
예를 들어 test.jonnung.dev라는 실제로 존재하지 않는 도메인을 DNS 서버에 조회하면 총 4번의 요청이 전달될 수 있다.
아래 결과는 실제 CoreDNS 서버에 남은 로그이다.
[INFO] 10.244.1.18:36652 - 7 "A IN test.jonnung.dev. udp 34 false 512" NXDOMAIN qr,rd,ra 118 0.198687028s
[INFO] 10.244.1.18:47210 - 8 "A IN test.jonnung.dev.testbed.svc.cluster.local. udp 60 false 512" NXDOMAIN qr,aa,rd 153 0.000158582s
[INFO] 10.244.1.18:33116 - 9 "A IN test.jonnung.dev.svc.cluster.local.
udp 52 false 512" NXDOMAIN qr,aa,rd 145 0.00014892s
[INFO] 10.244.1.18:59109 - 10 "A IN test.jonnung.dev.cluster.local. ud
p 48 false 512" NXDOMAIN qr,aa,rd 141 0.000122777s
이제야 제대로 이해되는 부분은 쿠버네티스 클러스터 상에서 test-pod라는 POD와 Service가 있을 때 http://test-pod:8080/ 같이 HTTP 요청을 보냈을 때 목적지 IP를 찾을 수 있었던 원리는 바로 search 옵션 때문이라고 할 수 있다.
이 원리를 이용해서 정확하게 FQDN을 조회할 수 있다면 DNS 조회 횟수를 줄일 수 있다.
예를 들어 test.dns.dev
같은 도메인을 찾는다고 한다면, 도메인 끝에 점(.)을 붙이지 않았더라도 요청하는 클라이언트가 자동으로 점(.)을 붙인 뒤 test.dns.dev.
형태로 요청을 할 것 이다.
하지만 실제로 저 도메인이 존재하지 않기 때문에 search
목록에 해당하는 default.svc.cluster.local
, svc.cluster.local
, cluster.local
을 모두 붙여가며 추가로 DNS를 질의하게 된다.
따라서 만약 조금이라도 CoreDNS 서버에 부하를 줄이고 싶다면, 외부 도메인을 호출할 때 마지막 점(.)을 추가하면 딱 1번만 DNS 서버에 질의할 수 있게 된다.
혹은, ndots 옵션 자체를 5가아닌 1~4로 적절히 적용하여 ndots 옵션에 지정된 개수에 따라 요청 개수가 늘어나는 방법 자체를 줄일 수 있다.
Kubernetes의 CoreDNS는 DNS 서버로서 클러스터 내부에서 DNS 조회를 처리합니다. CoreDNS는 다양한 DNS 형식을 지원합니다. 아래에는 CoreDNS가 제공하는 일반적인 Service DNS 형식의 예시를 제공합니다
service-name.namespace.svc.cluster.local
이 형식은 동일한 네임스페이스 내의 서비스에 대한 FQDN(Fully Qualified Domain Name)입니다. 예를 들어, my-service.default.svc.cluster.local와 같은 형태로 서비스를 참조할 수 있습니다.
service-name.namespace.svc: 이 형식은 동일한 네임스페이스 내의 서비스에 대한 짧은 FQDN입니다. my-service.default.svc와 같이 사용할 수 있습니다.
service-name.namespace: 이 형식은 네임스페이스 내에서 서비스에 대한 더 짧은 형태의 FQDN입니다. 예를 들어, my-service.default와 같이 사용할 수 있습니다.
service-name: 이 형식은 기본적으로 현재 네임스페이스 내에서 서비스를 참조합니다. 네임스페이스가 명시되지 않은 경우 현재 네임스페이스로 가정됩니다.
출처 : ChatGPT 질의