본문 바로가기
  • lakescript
스터디 이야기/AWS EKS

[AEWS] 2-5. Amazon EKS Networking - ExternalDNS

by lakescript 2024. 3. 14.

사전 준비

더보기

 

위와 같이 사전 준비가 필요합니다.

저번 글에서 설명했듯이, EKS를 배포하기 위한 VPC를 생성하고, Public Subnet, Private Subnet을 생성합니다. 그 후 EKS Cluster에 접근하기 위한 bastion EC2를 미리 생성합니다.

 

ExternalDNS

ChatGPT가 알려주는 ExternalDNS
Kubernetes 클러스터 내의 서비스나 Ingress 리소스가 변경될 때 자동으로 DNS 레코드를 생성하거나 업데이트하는 역할을 합니다.

 
즉, K8s Serivce나 Ingress 생성 시 도메인을 설정하면, AWS(Route 53), Azure(DNS), GCP(Cloud DNS)에 A 레코드(TXT 레코드)로 자동으로 생성 및 업데이트 해주는 service type입니다.
 
ExternalDNS Controller는 앞전에 봤던 Loadbalancer Contoller처럼 권한이 필요한데, Node IAM Role, Static credentials, IRSA의 3가지 방법이 있습니다.
 
이 실습은 AWS의 Route53 도메인을 생성했다는 전제하에 진행하며 사전에 설치를 할 때 Node IAM Role 옵션을 설정했다는 전제하에 진행하겠습니다.

배포 실습

실습하기 전에 퍼블릭 영역의 AWS Route53 호스팅 영역 AWS LoadBalancer Controller가 생성되어 있어야 합니다.

변수 설정

먼저 AWS Route53에서 생성해놓은 호스팅 영역의 도메인을 설정합니다.

AWS Route 53 도메인 변수 지정

MyDomain=<자신의 도메인>

AWS Route 53 도메인 ID 변수 지정

MyDnzHostedZoneId=$(aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text)

설정한 변수 확인

echo $MyDomain, $MyDnzHostedZoneId

 

ExternalDNS 배포

curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/aews/externaldns.yaml
sed -i "s/0.13.4/0.14.0/g" externaldns.yaml
cat externaldns.yaml | yh
MyDomain=$MyDomain MyDnzHostedZoneId=$MyDnzHostedZoneId envsubst < externaldns.yaml | kubectl apply -f -

 
위의 명령어는 github에서 externaldns.yaml 파일을 가져온 후 sed 명령어를 통해 버전 정보를  0.13.4에서 0.14.0으로 바꾸고 변수값을 지정하여 배포하는 명령어 입니다.

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

그 후 kubectl 명령어를 통해 배포되었는지 확인합니다.
 

참고

ExternalDNS 사용하여 A/TXT 레코드 생성 후 지우게 되면 생성된 record까지 지우게 되는데, policy 정책을 upsert-only 로 설정 후 사용하는 것이 좋아 실무에서 적극 권장되는 유용한 옵션입니다.

관련 링크 : https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/aws.md#deploy-externaldns

 
 
 

Service(NLB) + 도메인 연동(ExternalDNS)

저희는 테트리스 게임을 한번 배포해보도록 하겠습니다.
 

테트리스 Deployment 배포

cat <<EOF | kubectl create -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에 ExternanDNS 로 도메인 연결

kubectl annotate service tetris "external-dns.alpha.kubernetes.io/hostname=tetris.$MyDomain"

tetris service(NLB)에 external-dns 어노테이션을 설정합니다.
 

service 확인

kubectl get svc

 
위의 명령어를 통해 tetris service인 LB가 설정되었는지 확인합니다.

Route53에 A레코드 확인

aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq

 
위의 명령어를 통해 현재 AWS Route53 호스팅 영역에 A Type의 레코드들을 확인해보겠습니다.

 

AWS Route53 확인

이제 AWS Route53에서 직접 호스팅 영역을 확인해보겠습니다.

 
 

Domain 등록 확인하기

https://www.whatsmydns.net/#A/

 
위의 사이트에 들어가셔서 ExternanDNS을 통해 AWS Route53 레코드로 배포한 URL을 입력하면 전세계적으로 배포 현황을 확인하실 수 있습니다. 
 

 
 
 


Reference

- https://edgehog.blog/a-self-hosted-external-dns-resolver-for-kubernetes-111a27d6fc2c
- https://www.stacksimplify.com/aws-eks/aws-alb-ingress/install-externaldns-on-aws-eks/