[EKS] ExternalDNS 구성하기

vinca·2024년 2월 13일
0

🦓 EKS

목록 보기
11/23
post-thumbnail

ExternalDNS란 무엇일까?

ExternalName과 헷갈릴 수 있으니 잠깐 집고 넘어가자면..

ExternalName VS. ExternalDNS

ExternalName

ExternalName은 클러스터 내부에서 외부 서비스의 DNS 이름을 통해 접속할 수 있도록 하는 서비스이다.

예를 들어, 외부 RDS에 접근할 때 ExternalName을 통해서 마치 내부의 서비스에 접근하듯이 외부 RDS에 접근할 수 있다.

apiVersion: v1
kind: Service
metadata:
  name: my-rds-svc
spec:
  type: ExternalName
  externalName: my-database.aws.rds.com
  ports:
  - port: 3306

ExternalName 서비스는 실제로 트래픽을 프록시하거나 포워딩하지 않고, 단지 DNS 수준에서의 리다이렉션만을 수행한다.

ExternalDNS

쿠버네티스 클러스터 내부 리소스에 대해 외부 DNS 레코드로 접근하도록 만들어주는 도구이다.

쉽게 생각하면 퍼블릭 도메인을 사용하여 kubernetes의 자원에 접근하는 Route53을 만드는 도구🔧이다.
💡 즉, 쿠버네티스 내에서 Route53을 생성하고 업데이트할 수 있는 도구인 것!

퍼블릭 도메인으로는 흔히 쓰이는 Route53부터 다양한 퍼블릭 도메인 공급자와 연계해서 사용할 수 있다.

사용 형태

ExternalDNS를 사용하기 위해서는 ExternalDNS Controller가 파드 형태로 배포되어 Route53과 연결되게 된다.

💡 AWS 서비스 접근 권한
물론,이러한 ExternalDNS Controller또한 AWS 서비스인 Route53에 접근해야 하므로 AWS LB Controller와 마찬가지로 IAM Role이 필요로 하다.
✔️ 해결 방안
eksctl create cluster 명령에서 –-external-dns-access 옵션을 추가해 노드의 IAM 역할에 ExternalDNS 권한을 부여하면 된다.

도메인 설치

// 도메인 주소 변수 지정
MyDomain=<자신의 도메인>

echo "export MyDomain=$MyDomain" >> /etc/profile

echo $MyDomain

// 도메인의 Hosted Zone 정보 확인
aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." | jq

// 도메인 ID 변수 지정
MyDnsHostedZoneId=`aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text`

echo "export MyDnsHostedZoneId=$MyDnsHostedZoneId" >> /etc/profile

echo $MyDnsHostedZoneId

가비아에서 도메인을 산 뒤, Route53에 등록한 NS로 가비아 쪽을 교체해 주었다.

ExternalDNS 설치

// yaml 파일 다운로드 및 확인
curl -s -O https://raw.githubusercontent.com/cloudneta/cnaeblab/master/_data/externaldns.yaml

cat externaldns.yaml | yh

// yaml 파일에 변수 치환 후 배포
MyDomain=$MyDomain MyDnsHostedZoneId=$MyDnsHostedZoneId envsubst < externaldns.yaml | kubectl apply -f -

// ExternalDNS 확인
kubectl get pod -l app.kubernetes.io/name=external-dns -n kube-system

파드 배포 및 서비스(NLB) 생성

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tetris
  labels:
    app: tetris
spec:
  replicas: 2
  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

디플로이먼트와 서비스를 배포해 주자

// 디플로이먼트 & 서비스 배포
kubectl apply -f tetris.yaml

NLB에 ExternalDNS로 연결

NLB에 ExternalDNS를 통해서 Route53의 도메인 주소를 연결한다.
연결하고자 하는 서비스(NLB)에 다음과 같은 어노테이션을 추가해주면 된다.

// NLB에 ExternalDNS 연결
kubectl annotate service tetris "external-dns.alpha.kubernetes.io/hostname=www.$MyDomain"

www.내도메인 주소.com으로 접속해본다면?
다음과 같이 테스리스 게임화면이 나오는 것을 확인할 수 있다!

AWS 콘솔에서 확인

AWS 콘솔에서 확인해보면 다음과 같이 실제로 A 레코드가 생성된 것을 확인할 수 있다.

즉, ExternalDNS란 Route53에서 직접 수동으로 연결할 필요없이, k8s내에서 Route53과 같은 외부 호스팅 업체를 통해 내 서비스를 빠르고 간편하게 외부 도메인에 연결하는 방법이다.


Reference📎 | CloudNet@와 함께하는 Amazon EKS 기본 강의

profile
붉은 배 오색 딱다구리 개발자 🦃Cloud & DevOps

0개의 댓글