쿠버네티스 클러스터 내 pod에서 어떤 도메인을 쿼리할 때 kube-system 네임스페이스에 있는 coreDNS가 네임서버로 사용됩니다.
기존에는 kube-DNS가 이 역할을 했는데 1.12 버전투버 coreDNS가 표준으로 채택되었다고 합니다.
CoreDNS는 쿠버네티스 클러스터의 DNS 역할을 수행할 수 있는, 유연하고 확장가능한 DNS 서버입니다.
클러스터 내에서 주로 내부의 도메인 질의 / 외부 도메인 질의를 할 때 사용됩니다.
$ kubectl get po -n kube-system -l k8s-app=kube-dns
NAME READY STATUS RESTARTS AGE
coredns-6955765f44-qmfm4 1/1 Running 0 15h
coredns-6955765f44-svftc 1/1 Running 0 15h
CoreDNS도 pod로 실행되기에 외부에서 요청을 받기위해 service 오브젝트가 존재합니다.
다른 애플리케이션과 마찬가지로 pod로 호스팅되며, deployment로 실행되어 service로 요청을 받습니다.
$ kubectl get svc -n kube-system -l k8s-app=kube-dns
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP
CoreDNS 서비스 오브젝트의 metadata.name이 kube-dns로 되어있는 이유는 예전부터 이 이름을 사용하던 리소스와의 호환성을 위해서라고 합니다.
CoreDNS라고 하여 다른 DNS와 다르게 동작하는 건 아닙니다.
도메인 기반 호출 시 발생하는 과정과 동일하게 질의 수행 및 ip 획득, ip 기반 요청이 이뤄집니다.
클러스터 외부에 질의하는 과정 또한 내부 DNS 서버에 질의 후 해당 도메인이 없을 경우 상위 DNS를 조회하여 ip를 획득하는 것과 유사합니다.
CoreDNS의 여러 가지 기능은 corefile이라고 하는 configmap 오브젝트에 저장하여 설정가능합니다.
$ kubectl describe cm -n kube-system coredns
Name: coredns
Namespace: kube-system
Labels: <none>
Annotations: <none>
Data
====
Corefile:
----
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
이제 파드 내부에 도메인 쿼리시 참조되는 conf 파일을 봅시다.
nameserver 10.96.0.10 # DNS 서버 -> coreDNS
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
- nameserver : DNS 쿼리를 보낼 곳. CoreDNS Service 오브젝트의 IP 주소
- search : DNS에 질의할 부분 도메인 주소 경로들을 표시
- ndots : FQDN으로 취급될 도메인에 포함될 .(점)의 최소 개수
FQDN은 위에서 살펴 본 /etc/resolv.conf 설정에서 options 값에 있는 ndots과 관련이 있다. ndots:5 라는 의미는 도메인에 포함된 점(.)의 개수가 5개부터 FQDN으로 취급한다는 의미이다.
만약 어떤 POD에서 test.default.svc.cluser.local.test 같은 도메인을 찾으려고 한다면, 이 도메인은 FQDN이기 때문에 클라이언트는test.default.svc.cluser.local.test 형태로 DNS 서버에 질의를 하게 된다.
Search 옵션은 부분적인 도메인 목록들을 지정한다.
즉, 클라이언트가 DNS 서버로부터 결과가 없다는 응답을 받으면, 이 부분 도메인 목록을 차례대로 붙여가며 추가로 DNS 서버를 호출한다.
이렇게 정의되어있는 /etc/resolv.conf 설정에 따라 궁극에 coreDNS에서 질의를 하게 됩니다.
## coreDNS 사용 이유
### 1. 서비스 디스커버리
CoreDNS는 Kubernetes 클러스터 내에서 서비스 디스커버리를 제공합니다.
컨테이너에서 실행되는 애플리케이션은 IP 주소 대신 DNS 이름을 사용하여 다른 서비스를 찾고 통신할 수 있습니다. 이를 통해 서비스의 확장 또는 마이그레이션 시에도 결합도가 낮아지고 유연성이 향상됩니다.
### 2. 사용자 정의 및 확장성
CoreDNS는 손쉽게 구성, 확장 가능한 서비스입니다.
위에서 본 것처럼 corefile 설정을 통해, 간편하게 플러그인을 추가하여 특정 요구 사항을 충족시킬 수 있습니다.
이러한 유연성은 DNS 캐싱, DNS 기반 보안 정책, 외부 DNS 공급자와의 통합 등의 기능을 가능하게 합니다.
### 3. Kubernetes API와의 통합
CoreDNS는 Kubernetes API 서버와 원활하게 통합됩니다.
Kubernetes API를 쿼리함으로써 클러스터 내의 서비스, 엔드포인트 및 기타 리소스를 자동으로 검색합니다.
# NodelocalDNS
K8S에서 더 나은 DNS 성능을 위해 제공하는 서비스입니다.
흔히 nodelocalDNS라고 부르는데 정식명칙은 NodeLocal DNSCache로 이름에서도 알 수 있지만 K8s DNS 쿼리의 성능을 향상시키기 위한 캐싱 서비스입니다.
DNS 질의에 대해, 동일한 요청을 캐시하여 앞단에 처리함으로서 추가적인 외부 DNS 쿼리를 수행하지않고도 빠른 응답을 제공할 수 있습니다.
> K8s의 coreDNS 서비스에 대한 부하를 줄이는 역할을 제공하고 있습니다.
NodelocalDNS는 pod에 대한 DNS 요청을 최적화하기 위해 설계되었기 때문에 모든 노드에 데몬셋으로 배포됩니다.
## NodelocalDNS configmap
1. 캐시 크기
: nodelocalDNS 캐시는 기본적으로 클러스터 노드의 메모리에 저장됩니다. (메모리 제한)
2. 캐싱 시간
: TTL 디폴트 30초
3. UpstreamDomain
4. StubStreamDomain
: 외부 DNS에 대한 처리, 하위/특정 도메인에 대한 처리를 정의하는 방식
위 4가지 설정이 가능합니다.
## 구조
![](https://velog.velcdn.com/images/baeyuna97/post/cce97c72-f17a-4424-9e41-d7efc28faa61/image.png)
DNS에 대한 요청을 메모리에 캐시하여 TTL 이내에 요청 시 cache hit하여 빠르게 리턴합니다.
위 사진에서 초록색 부분이 cache hit, 빨간색 부분이 cache miss 이며, coreDNS를 통해 업데이트 되는 과정입니다.