본문 바로가기
칼럼 이야기/영상

Kubernetes에서 DNS 다루는 방법 - 도메인을 찾아서

by lakescript 2024. 7. 26.

https://tv.naver.com/v/56456809

 

NAVER D2

Kubernetes에서 DNS 다루는 방법 - 도메인을 찾아서

tv.naver.com

 

naver D2에서 소개된 Kubernetes에서 DNS 다루는 방법에 대한 영상 내용이 너무 좋아 블로그에 따로 정리하려고 합니다.


Kubernetes DNS를 알아보게 된 계기

K8s를 운영하던 중 클러스터 일부 노드들에서 특정 도메인에 대해 도메인 lookup이 되지 않는 현상이 발생했습니다. 원인을 살펴보니 해당 노드들의 네트워크 망 구성이 달라 서로 다른 nameserver를 이용하고 있었고 그로인해 특정 도메인을 찾지 못했습니다.  노드들의 nameserver는 변경할 수 없는 상황이에서 어떻게 특정 도메인에 대한 namespace만 다르게 설정할 수 있을까 고민했습니다.  그러던 중

Kubernetes로 운영되는 노드들이니 DNS 관련 설정으로 이를 해결할 수 있지 않을까? 하여 찾아보았습니다.

Kubernetes의 간단한 배경 지식

Pod들은 고유한 IP를 가진다.

Pod들은 언제든 삭제될 수 있다.

Pod들은 동적으로 생성/삭제되는 리소스이다보니 언제든지 Cluster 내부에서 삭제될 수 있습니다.

이때, 다시 생성된 Pod의 IP는 변경됩니다.

 

Service를 사용하여 여러 Pod들에 대한 단일 Endpoint를 설정할 수 있습니다.

여러 Pod들에 대한 IP를 단일 엔드포인트로 연결해주는 Service라는 리소스도 있습니다.

 

 

이렇게 무수히 많은 Pod와 Service의 IP를 직접 다루는 것은 불편합니다. 그렇기에 Kubernetes에서는 Domain Name을 통해 Pod 또는 Service에 접근할 수 있습니다.

 

도메인 네임을 통해 Pod 또는 Service 접근

kubernetes는 클러스터 내부의 DNS 서버를 활용하여 Pod와 Service에 대한 DNS 레코드를 자동으로 생성 및 관리합니다.

공식문서에 따르면 Pod, Service에 대한 A/AAAA Record 구성은 아래와 같습니다.

Service

<service>.<ns>.svc.<zone>

Pod

<pod-ip>.<ns>.pod.<zone>
<hostname>.<service>.<ns>.svc.<zone>

 

 

Pod에서 도메인 룩업 살펴보기

Pod에서 직접 Domain lookup을 해보며 DNS 구성에 대해 살펴보겠습니다.

 

 

Pod에서 외부 도메인 접속

#Pod 내부
nslookup leehosu.tistory.com

 

foo라는 pod가 있고, 외부 도메인인 leehosu.tistory.com에 대한 질의를 한다면 어떻게 될까요?

오른쪽 도식처럼 Pod내부에서 외부 도메인에 대한 질의를 할 시에는 내부 파드의 DNS Resolver가 호출되고 도메인 룩업 설정이 있는 /etc/resolv.conf 파일을 참고하여 도메인 룩업이 진행됩니다.

 

 

이떄, 도메인 룩업을 위한 nameserver는 169.254.20.10을 사용하고 있습니다.

 

Node에서 외부 도메인 접속

그럼 해당 Pod가 실행되고 있는 Node에서 동일한 외부 도메인(leehosu.tistory.com)에 대한 도메인 룩업을 진행했을 때를 보겠습니다. 질의하는 과정은 위와 동일하게 내부의 /etc/resolv.conf 파일의 도메인 룩업 설정 토대로 도메인 룩업이 진행됩니다.

 

여기서는 위의 사진처럼 192.168.65.254의 DNS Server를 이용하고 있습니다.

 

Pod와 Node의 NameServer

 

Pod와 Node의 Nameserver가 다른데요. 그럼 Pod의 NameServer는 어디서 설정된 것인지 Node에서 찾아 보겠습니다.

 

 

Pod가 실행중인 Node에서 확인

ip address

 

 

위 명령어를 통해 Pod가 띄어져있는 Node에서 확인해본 결과, Pod가 NameServer로 사용하는 주소는 nodelocaldns 라는 인터페이스의 주소로 확인할 수 있습니다.

 

nodelocaldns

nodelocal DNSCache라는 Kubernetes Daemonset로 부터 생성된 임시 인터페이스입니다. 

 

Nodelocal DNSCache

Kubernetes Daemonset을 통해 실행되며 각 Pod들은 각 노드에서 CoreDNS를 Cache 모드로 실행합니다. 노드의 Host Network Namespace에서 동작하며, nodelocaldns 임시 인터페이스를 생성합니다. 이때 임시 인터페이스는 실제로 네트워크 트래픽을 전송하지 않고 패킷 라우팅 역할만 수행합니다. Listen상태로 대기하며 Domain Resolver 요청을 대기합니다.

 

Nodelocal DNSCache 구성

kube-system 네임스페이스에 damonset nodelocaldns을 실행하는데, daemonset 특성상 모든 노드에서 Pod가 배포됩니다.

각 노드에서 DNS 쿼리를 로컬에서 처리하도록 하기 위해 kube-system 네임스페이스에 nodelocaldns service를 생성합니다.

kube-system 네임스페이스에 nodelocaldns config 설정을 담고 있는 nodelocaldns ConfigMap을 생성합니다.

Nodelocal DNSCache Daemonset 

nodelocadns의 내용을 보기 위해 yaml 형태로 daemonset을 조회했을 때 출력 결과의 일부분입니다. 이때 위에서 보았던 localdns의  configmap이 /etc/coredns/Corefile로 마운트되어있는 것을 확인할 수 있었습니다.

 

Nodelocaldns의 Corefile 구성

 

즉, cluster.local외의 DNS 질의는 노드의 /etc/resolv.conf 설정을 따릅니다.

정리하자면,  Kubernetes(cluster.loacl)와 관련된 DNS 질의는 10,96.0.10으로 TCP를 통해 전송되며 Kubernetes 외의 DNS 질의는 노드의 /etc/resolv.conf의 설정에 따릅니다.

 

728x90