CoreDNS를 통한 k8s 클러스터 내의 DNS 질의

Jaden Kim·2025년 5월 23일
post-thumbnail

CoreDNS는 k8s 파드에서의 도메인 질의를 담당하는 컴포넌트입니다.
CoreDNS는 내부 서비스 디스커버리를 담당하고, 외부 도메인 질의는 forward 하는 식으로 처리합니다.

Pod 에서의 DNS 질의

kubelet은 파드 생성 시 /etc/resolv.conf를 주입하여, DNS 질의와 관련된 설정을 수행합니다.
nameserver로는 CoreDNS 에 연결된 kube-dns 서비스의 IP가 정의되어있습니다.
search 에는 FQDN 도메인을 찾기 위한 DNS 검색 경로 리스트가 포함됩니다.

nameserver 10.100.0.10 
search <service>.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

ndots에는 5가 설정되어 있는데, 이는 점이 5개 이상 포함된 도메인에 대해서만 FQDN으로 간주하고 search 를 생략한다는 것을 의미합니다.
점이 5개 미만인 도메인의 경우 순차적으로 search에 포함된 도메인들을 차례대로 붙여 가며 질의가 이루어집니다.

1. ex-tetris -> ex-tetris.default.svc.cluster.local : FQDN 질의 성공
2. ex-tetris.default.svc -> ex-tetris.default.svc.default.svc.cluster.local 
                         -> ex-tetris.default.svc.svc.cluster.local
                         -> ex-tetris.default.svc.cluster.local : FQDN 질의 성공

search로 인한 불필요한 도메인 질의를 줄이려면 서비스 디스커버리에는 FQDN을 사용하는게 좋습니다.
외부 도메인의 경우 google.com. 와 같이 trailing dot를 명시해서 search 쿼리를 방지할 수 있습니다.

CoreDNS의 DNS 응답

파드에서 nameserver를 따로 설정하지 않는 이상, CoreDNS에서는 클러스터 내의 파드로부터 오는 모든 DNS 요청을 받게 됩니다.
CoreDNS는 configmap에 정의된 Corefile 설정에 따라 동작합니다.

.:53 {
    errors
    health {
      lameduck 5s
    }
    ready
    kubernetes cluster.local in-addr.arpa ip6.arpa {
      pods insecure
      fallthrough in-addr.arpa ip6.arpa
    }
    prometheus :9153
    forward . /etc/resolv.conf
    cache 30
    loop
    reload
    loadbalance
}

위 설정에 따라 도메인 영역이 cluster.local로 정의되며, cluster.local 도메인에 대해서는 직접 응답하고, 그 외의 요청에 대해서는 forward 설정에 따라 /etc/resolv.conf 파일 기반으로 외부 도메인 서버에 질의가 발생합니다.
kubelet에서는 노드의 /etc/resolv.conf 파일을 기반으로 CoreDNS 파드 내에 resolv.conf 파일을 주입하기 때문에, 노드와 동일한 네임 서버를 바라봅니다.
AWS 환경이라면 VPC의 DNS 서버 주소로 질의가 발생합니다.

# VPC의 DNS 서버
nameserver 192.168.0.2

CoreDNS가 cluster.local 도메인을 관리하는 방법

CoreDNS는 k8s 리소스를 기반으로 cluster.local 도메인 영역에 도메인 레코드를 생성합니다.
k8s API 서버를 통해 리소스 변경 사항을 watch 하고 있기 때문에, 실시간으로 도메인 레코드가 갱신됩니다.
다양한 리소스에 대해서 레코드를 생성할 수 있지만, 주로 Service, Headless Service에 대한 도메인이 사용됩니다.
서비스의 경우 서비스 이름과 서비스 ClusterIP를 기반으로 A 레코드를 생성하여 등록합니다.

▶ my-svc.default.svc.cluster.local. IN A 10.0.0.18

Headless Service의 경우 서비스 이름으로 도메인 질의 시 해당 서비스에 연결된 파드의 IP를 모두 반환니다.
또한 연결된 각 파드에 대해서 파드 이름을 기반으로 질의가 가능하도록 도메인 레코드가 등록됩니다.

▶ headless-svc.default.svc.cluster.local. IN A 192.168.51.10 
▶ headless-svc.default.svc.cluster.local. IN A 192.168.51.11

▶ pod-a.headless-svc.default.svc.cluster.local. IN A 192.168.51.10
▶ pod-b.headless-svc.default.svc.cluster.local. IN A 192.168.51.11

0개의 댓글