모험가

AEWS 2주차 - Networking(ExternalDNS, CoreDNS) 본문

쿠버네티스/AEWS

AEWS 2주차 - Networking(ExternalDNS, CoreDNS)

라리음 2025. 2. 13. 15:17
본 글은 가시다님이 진행하시는 AEWS(AWS EKS Workshop Study)를 참여하여 정리한 글입니다. 
모르는 부분이 많아서 틀린 내용이 있다면 말씀 부탁드리겠습니다!

 

 

 

 


ExternalDNS

 

 

https://edgehog.blog/a-self-hosted-external-dns-resolver-for-kubernetes-111a27d6fc2c

 

 

ExternalDNS란

ExternalDNS는 Kubernetes에서 자동으로 DNS 레코드를 관리할 수 있도록 도와주는 도구입니다.
보통 클러스터 외부에서 접근 가능한 서비스(예: LoadBalancer, Ingress)를 배포하면 수동으로 DNS를 설정해야 하지만,
ExternalDNS를 사용하면 이를 자동화할 수 있습니다.

 

 

기능

✅ AWS Route 53, Google Cloud DNS, Cloudflare 등의 여러 DNS 제공자와 연동 가능
✅ Ingress 또는 LoadBalancer Service의 변경 사항을 감지하여 DNS 레코드를 자동 생성 및 업데이트
✅ DNS 레코드 정리 및 삭제도 자동으로 수행

 

 

📌 ExternalDNS 작동 방식

ExternalDNS는 Kubernetes 클러스터 내에서 실행되며, 특정 리소스를 모니터링하면서

DNS 레코드를 자동으로 생성합니다.

 

🔹 ExternalDNS의 기본 흐름

1️⃣ Ingress 또는 LoadBalancer 타입의 Service에서 도메인 정보(hostname) 를 확인
2️⃣ Kubernetes API를 통해 리소스 상태 감지
3️⃣ 설정된 DNS 제공자(AWS Route 53, Cloudflare 등)에 레코드 추가 또는 수정
4️⃣ IP 또는 ALB 주소를 DNS 레코드로 매핑

 

 

 


ExternalDNS 실습

 

 

사전에 public 도메인 소유하며, AWS Route 53에 등록하셔야합니다!

 

 

변수 지정 및  Route 53 정보 확인

# 자신의 도메인 변수 지정 : 소유하고 있는 자신의 도메인을 입력하시면 됩니다
MyDomain=<자신의 도메인>
MyDomain=rhims.store

# 자신의 Route 53 도메인 ID 조회 및 변수 지정
aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." | jq
aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Name"
aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text
MyDnzHostedZoneId=`aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text`
echo $MyDnzHostedZoneId

# (옵션) NS 레코드 타입 첫번째 조회
aws route53 list-resource-record-sets --output json --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'NS']" | jq -r '.[0].ResourceRecords[].Value'
# (옵션) A 레코드 타입 모두 조회
aws route53 list-resource-record-sets --output json --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']"


# A 레코드 타입 조회
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq

# 자신의 Route 53 도메인 ID 조회 및 변수 지정
MyDnzHostedZoneId=$(aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text)

# 변수 확인
echo $MyDomain, $MyDnzHostedZoneId

 

 

변수 출력 화면

 

 

ExternalDNS 설치 및 모니터링

# ExternalDNS 배포
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/aews/externaldns.yaml
cat externaldns.yaml
MyDomain=$MyDomain MyDnzHostedZoneId=$MyDnzHostedZoneId envsubst < externaldns.yaml | kubectl apply -f -

# 확인 및 로그 모니터링
kubectl get pod -l app.kubernetes.io/name=external-dns -n kube-system
kubectl logs deploy/external-dns -n kube-system -f

 

출력 화면

 

 

 

 

NLB + External DNS 확인을 위한 Deplyment 배포

# 테트리스 디플로이먼트 배포
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tetris
  labels:
    app: tetris
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tetris
  template:
    metadata:
      labels:
        app: tetris
    spec:
      containers:
      - name: tetris
        image: bsord/tetris
---
apiVersion: v1
kind: Service
metadata:
  name: tetris
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
    service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
    #service.beta.kubernetes.io/aws-load-balancer-healthcheck-port: "80"
spec:
  selector:
    app: tetris
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  type: LoadBalancer
  loadBalancerClass: service.k8s.aws/nlb
EOF

# 배포 확인
kubectl get deploy,svc,ep tetris

 

출력 화면

 

 

NLB에 ExternalDNS로 도메인 연결 및 확인

# NLB에 ExternanDNS 로 도메인 연결
kubectl annotate service tetris "external-dns.alpha.kubernetes.io/hostname=tetris.$MyDomain"
while true; do aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq ; date ; echo ; sleep 1; done

# Route53에 A레코드 확인
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq

# 확인
dig +short tetris.$MyDomain @8.8.8.8
dig +short tetris.$MyDomain

# 도메인 체크
echo -e "My Domain Checker Site1 = https://www.whatsmydns.net/#A/tetris.$MyDomain"
echo -e "My Domain Checker Site2 = https://dnschecker.org/#A/tetris.$MyDomain"

 

 

콘솔에서 A레코드가 생성되었음을 확인 가능합니다.

 

 

 

 

애플리케이션 도메인 접속 확인

# 웹 접속 주소 확인 및 접속
echo -e "Tetris Game URL = http://tetris.$MyDomain"

 

 

애플리케이션 화면

 

 

 


CoreDNS

 

https://edgehog.blog/a-self-hosted-external-dns-resolver-for-kubernetes-111a27d6fc2c

 

 

CoreDNS란

CoreDNS는 Kubernetes의 기본 DNS 서버로, 클러스터 내부에서 서비스 간 DNS 조회를 담당하는 핵심 구성 요소입니다.
기존의 kube-dns를 대체하며, 빠르고 확장성이 뛰어난 플러그인 기반 DNS 서버입니다.

 

 

기능

Kubernetes 클러스터 내부에서 서비스 간 DNS 이름 해석 수행
가벼운 구조와 플러그인 기반으로 커스터마이징 가능
기본적으로 ClusterIP를 통해 실행되며 kube-proxy와 함께 동작
Service Discovery를 자동으로 제공하여 내부 네트워크 연결을 간소화

 

 

📌 ExternalDNS 작동 방식

CoreDNS는 Kubernetes 내에서 DNS 이름을 해석하여 서비스 및 Pod 간의 통신을 가능하게 합니다.

 

🔹 CoreDNS의 기본 흐름

1️⃣ Pod에서 DNS 조회 요청 예: curl my-service.default.svc.cluster.local

2️⃣ 클러스터 내의 DNS 서버 (CoreDNS)로 요청 전달

3️⃣ CoreDNS가 ConfigMap 설정을 기반으로 도메인 검색

4️⃣ IP 주소를 반환하여 통신 가능하도록 처리

 

 

 

EKS 클러스터를 생성하면 기본 2개의 coredns 파드가 올라오는 것을 확인하였습니다.

 

기본 고가용성 및 성능을 위해 2개의 replicaset을 지니며 대규모 워크로드에서는 추가될 수 있습니다.

* 기본 CoreDNS의 설정 파일은 Corefile에서 확인이 가능합니다.

 

 

Corefile 확인

# CoreDNS 기본 정보 확인 : volumes - configMap - Corefile - coredns
kubectl get deploy coredns -n kube-system -o yaml | kubectl neat 
kubectl get cm -n kube-system coredns -o yaml | kubectl neat
data: 
  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
    }

 

출력 화면

 

 

 

이렇게 ExternalDNS와 CoreDNS에 대해 알아보았습니다.

 

 

 


출처

 

가시다님 스터디 노션

 

https://edgehog.blog/a-self-hosted-external-dns-resolver-for-kubernetes-111a27d6fc2c

 

A Self-hosted external DNS resolver for Kubernetes.

Understanding solutions for external DNS resolution in Kubernetes and introducing our k8s_gateway plugin.

edgehog.blog

 

 

https://www.nslookup.io/learning/the-life-of-a-dns-query-in-kubernetes/

 

The life of a DNS query in Kubernetes

In Kubernetes, DNS queries follow a specific path to resolve the IP address of a hostname. Here are all the steps and components it goes through.

www.nslookup.io