[AEWS] 2-5. Amazon EKS Networking - ExternalDNS
사전 준비

위와 같이 사전 준비가 필요합니다.
저번 글에서 설명했듯이, 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/