본문 바로가기
K8S

쿠버네티스 내부에서는 어떻게 DNS 질의를 할까?

by HH_g 2024. 10. 10.

DNS 란?

인터넷에서 사용자가 도메인을 통해 웹페이지를 접속하거나 특정 서비스와 통신을 할때,  네임서버에 질의를 하여 설정된 값을 찾아 통신을 하게 됩니다. 이때, 네임서버에 설정된 항목들을 레코드라고 부릅니다.

 

DNS 질의

DNS 질의는 DNS를 통해 특정 도메인 이름에 대한 정보를 요청하는 과정을 말합니다. 사람이 읽을 수 있는 도메인 이름을 IP 주소로 변환하는 과정이지요. 웹 브라우저나 애플리케이션이 특정 서버에 연결하고 싶을 때, 해당 서버의 IP 주소를 알아야하기 때문입니다.

 

일반적인 DNS 질의 과정은 아래와 같습니다.

 

1. 클라이언트 요청 (DNS Resolver 호출)

  • 사용자가 웹 브라우저에 www.google.com 을 입력하면 컴퓨터는 도메인 이름에 대한 IP 주소를 알아내기 위해 DNS Resolver 를 호출합니다.
  • 먼저 로컬 캐시에서 이미 변환된 IP 주소가 있는지 확인합니다. 캐시에 IP 주소가 없다면 클라이언트는 DNS 서버에 요청을 보냅니다.

2. DNS Resolver

  • 클라이언트의 네트워크는 DNS Resolver(로컬 DNS 서버, ISP 의 DNS 서버) 로 도메인 이름을 IP 주소로 변환해 달라는 요청을 보냅니다.
  • DNS Resolver 는 클라이언트의 대리인 역할을 하며, 여러 DNS 서버에 질의를 보내 IP 주소를 찾습니다.

3. Root DNS Server

  • 리졸버는 캐시에 IP 정보가 없으면 root DNS 서버에 첫 번째 질의를 보냅니다. 루트 DNS 서버는 도메인 이름의 최상위인 .com, .net, .org 등과 같은 최상위 도메인을 관리하는 DNS 서버로 연결하는 역할을 합니다.

4. TLD DNS 서버 (Top Level Domain DNS Server)

  • 리졸버는 TLD DNS 서버(.com, .org 등)에 다시 질의를 보내 example.com과 같은 두 번째 수준의 도메인 이름을 관리하는 권한 있는 DNS 서버의 주소를 요청합니다.
  • TLD DNS 서버는 example.com을 담당하는 **권한 있는 DNS 서버(Authoritative DNS Server)**의 주소를 반환합니다.

5. 권한 있는 DNS 서버 (Authoritative DNS Server)

  • 리졸버는 권한 있는 DNS 서버에 최종적으로 질의를 보내고, 해당 서버는 www.example.com에 대한 정확한 IP 주소를 리졸버에 반환합니다.

6. IP 주소 반환 및 캐싱

  • 리졸버는 해당 IP 주소를 받아 클라이언트에게 전달하며, 그 IP 주소는 로컬 캐시에 저장됩니다. 이후 동일한 요청이 들어올 경우, 캐시된 IP 주소를 사용하여 빠르게 응답할 수 있습니다.

7. 통신 시작

  • 클라이언트는 IP 주소를 사용하여 해당 서버에 요청을 보내고, 그에 따라 네트워크 통신이 이루어집니다.

 

 

쿠버네티스(Kubernetes)에서의 DNS 질의 과정

그렇다면 쿠버네티스에서는 어떻게 DNS 질의를 처리할까요?

쿠버네티스 클러스터 내의 특정 리소스에는 일정한 규칙을 가지고 고유한 도메인이 부여됩니다.

 

리소스 도메인 형식 설명
Pod 기본적으로 없음, Headless Service 사용 시 <파드 이름>.<서비스 이름>.<네임스페이스>.svc.cluster.local 파드 개별로는 도메인이 없지만, Headless Service와 연계 시 도메인 부여.
Service <서비스 이름>.<네임스페이스>.svc.cluster.local 클러스터 내에서 서비스 이름으로 접근 가능.
Headless Service <파드 이름>.<서비스 이름>.<네임스페이스>.svc.cluster.local ClusterIP가 없는 서비스로, 각 파드가 고유의 도메인 이름을 가짐.
StatefulSet <StatefulSet 이름>-<파드 인덱스>.<StatefulSet 이름>.<네임스페이스>.svc.cluster.local 상태를 가진 파드들이 고유의 도메인 이름을 가짐.
Ingress 사용자가 설정한 외부 도메인 이름 클러스터 외부에서 내부 서비스로 HTTP(S) 트래픽을 라우팅.
ExternalName <서비스 이름>.<네임스페이스>.svc.cluster.local (외부 DNS 이름과 연결) 외부 DNS 이름을 참조하는 서비스.
Endpoints 직접 도메인 부여 없음, 파드의 도메인 이름을 사용 서비스에 연결된 파드의 IP 주소를 관리.

 

쿠버네티스 클러스터 내부에서도 도메인 이름을 통해 해당 리소스들에 접근할 수 있습니다. 쿠버네티스에서의 DNS 질의는 기본적인 DNS 질의 과정과 비슷한 원리를 따르지만, 클러스터 내에서 CoreDNS를 통해 보다 효율적으로 내부 네트워크 통신을 관리합니다.

 

Kube-dns

  • kube-dns는 쿠버네티스에서 초기에 도입된 기본 DNS 서비스로, 클러스터 내에서 서비스와 파드 간 통신을 위해 도메인 이름을 IP 주소로 변환해 주는 역할을 합니다.
  • kube-dns는 클러스터 내에 배포된 파드 및 서비스들의 DNS 레코드를 관리하고, 이를 통해 클러스터 내 리소스들이 도메인 이름을 사용하여 서로 통신할 수 있게 해줍니다.
  • 다만 kube-dns 는 큰 규모의 클러스터에서 성능 이슈가 발생할 수 있습니다. 이에 k8s 1.11 버전부터는 CoreDNS 가 kube-dns 를 대체하는 쿠버네티스의 기본 DNS 서비스로 채택되었습니다.

 

CoreDNS 

파드 내부에서 /etc/resolv.conf 를 조회해보면 네임서버 주소가 10.100.0.10 으로 나오는 것을 확인할 수 있습니다.

해당 주소는 kube-dns 서비스의 clusterIP 주소입니다.

[root@grace-5136-0 /]# cat /etc/resolv.conf
search grace-5136.svc.cluster.local svc.cluster.local cluster.local ap-northeast-1.compute.internal
nameserver 10.100.0.10
options ndots:5
 
  • nameserver: 10.100.0.10 은 쿠버네티스 클러스터에서 kube-dns 서비스로 설정된 ClusterIP 주소입니다. 하지만 이 IP 주소는 사실 CoreDNS로 연결됩니다. kube-dns라는 이름을 쓰지만, 실제로 DNS 질의는 CoreDNS가 처리합니다.
  • search: DNS 이름 해석 시, 도메인 이름이 자동으로 완성되는 검색 도메인 목록입니다. 예를 들어 my-service라는 도메인 이름을 질의하면, 자동으로 my-service.default.svc.cluster.local로 확장됩니다.
  • options: ndots 옵션은 DNS 질의 시 몇 개의 점이 있어야 전체 도메인 이름으로 인식할지를 설정합니다.

 

kube-dns ClusterIP : 10.100.0.10

 

 

해당 서비스에 연결된 파드가 바로 CoreDNS 입니다.

쿠버네티스 1.11 버전 이후로 CoreDNS 가 기본 DNS 서버로 설정되었습니다.

kube-dns 라는 서비스 이름은 남아있지만, 해당 서비스를 처리하는 실제 DNS 서버는 CoreDNS 입니다.

 

kube-dns 서비스

 

kube-dns 서비스에 연결된 CoreDNS 파드

 

 

K8S 내부의 DNS 질의 과정

 

1. 파드의 DNS 요청

  • 쿠버네티스 클러스터에서 파드나 애플리케이션이 특정 서비스나 다른 파드로 통신을 시도할 때, 파드는 my-service.default.svc.cluster.local 과 같은 도메인 이름을 사용하여 해당 서비스의 IP 주소를 요청합니다.
  • 파드 안에 있는 DNS 클라이언트는 해당 도메인 이름을 IP 주소로 변환하기 위해 CoreDNS로 질의를 보냅니다.

2. CoreDNS 서버

  • 쿠버네티스에서는 기본적으로 CoreDNS가 클러스터의 내부 DNS 서버로 설정되어 있습니다. CoreDNS는 클러스터 내부에서 서비스, 파드 등 여러 리소스에 대해 도메인 이름과 IP 주소 간의 매핑 정보를 관리합니다.
  • CoreDNS는 질의받은 도메인 이름에 대한 매핑 정보를 자신의 캐시에서 먼저 확인하고, 없으면 쿠버네티스 API 서버와 상호작용하여 클러스터 내부 리소스의 최신 정보를 가져옵니다.

3. 쿠버네티스 API 서버와 상호작용

  • 만약 CoreDNS가 요청된 도메인 이름에 대한 정보를 가지고 있지 않으면, Kubernetes API 서버로부터 서비스나 파드의 최신 정보를 요청합니다. API 서버는 클러스터 내부 리소스의 상태를 관리하며, 각 서비스와 파드의 IP 주소를 CoreDNS에 반환할 수 있습니다.
  • CoreDNS는 받은 정보를 사용해 질의된 도메인 이름에 해당하는 IP 주소를 클라이언트(파드)로 반환합니다.

4. IP 주소 반환

  • CoreDNS는 서비스나 파드의 IP 주소를 클라이언트 파드에 반환하며, 파드는 해당 IP 주소로 네트워크 통신을 시작합니다.

 

일반 DNS 질의와 쿠버네티스 내부 DNS 질의의 비교


클라이언트 요청 클라이언트가 DNS Resolver에 도메인 이름(IP 변환 요청)을 보냄 파드가 CoreDNS로 도메인 이름(IP 변환 요청)을 보냄
DNS 리졸버 DNS Resolver가 여러 DNS 서버(루트, TLD, 권한 있는 DNS 서버)를 통해 IP를 조회 CoreDNS가 직접 IP 주소를 캐시에서 조회하거나, 없는 경우 쿠버네티스 API 서버로 질의
루트/TLD/권한 있는 서버 루트, TLD, 권한 있는 DNS 서버를 차례로 질의하여 최종 IP 주소를 얻음 CoreDNS는 클러스터 내부 리소스(서비스, 파드)에 대한 정보를 관리하고, 필요할 경우 API 서버와 상호작용하여 최신 정보를 가져옴
IP 주소 반환 및 캐싱 최종 IP 주소를 리졸버가 반환하고, 이후 캐시를 통해 재사용함 CoreDNS가 IP 주소를 파드에 반환하며, 캐시를 사용하여 빠르게 처리 가능

 

CoreDNS 설정 - LoadBalance 

 

configmap 설정

 

 

실제로 nslookup 으로 서비스 주소를 조회하면, 레코드 순서가 바뀌는 것을 확인할 수 있습니다.

이는 CoreDNS default 설정인 loadbalance 설정 때문인데, 이 설정 때문에 DNS 응답에서 A, AAAA, MX 레코드의 순서를 무작위로 섞여서 레코드가 나열됩니다.

 

[root@grace-1318-0 /]# nslookup graceh-6310.graceh-6310.svc.cluster.local
Server:		10.100.0.10
Address:	10.100.0.10#53

Name:	graceh-6310.graceh-6310.svc.cluster.local
Address: 172.16.134.149
Name:	graceh-6310.graceh-6310.svc.cluster.local
Address: 172.16.131.4

[root@grace-1318-0 /]# nslookup graceh-6310.graceh-6310.svc.cluster.local
Server:		10.100.0.10
Address:	10.100.0.10#53

Name:	graceh-6310.graceh-6310.svc.cluster.local
Address: 172.16.131.4
Name:	graceh-6310.graceh-6310.svc.cluster.local
Address: 172.16.134.149

 

'K8S' 카테고리의 다른 글

Vector + Scalable Loki  (1) 2024.12.22
Headless Service  (0) 2024.12.08