1. ExternalDNS 란?

- external-dns는 Kubernetes 클러스터에서 생성되는 service나 ingress 리소스를 기반으로 외부 DNS 레코드를 자동으로 생성 및 관리해주는 도구이다.
- 즉, Kubernetes 클러스터가 실행 중인 환경에서 DNS를 자동화하는 역할을 한다.
- 이 도구를 사용하면 Kubernetes 애플리케이션을 배포할 때 외부 DNS 서비스(ex. Route53)에 수동으로 레코드를 추가할 필요 없이, DNS 레코드가 자동으로 업데이트된다.
2. ExternalDNS의 주요 기능
- 자동화된 DNS 관리: Kubernetes 클러스터에 새로운 서비스나 인그레스 리소스를 배포할 때 해당 리소스에 대한 DNS 레코드를 자동으로 생성하고 관리한다.
- 다양한 DNS 제공자 지원: AWS Route 53, Google Cloud DNS, Azure DNS, Cloudflare 등 여러 DNS 제공자와 통합이 가능하여 다양한 클라우드 환경에서 유연하게 사용할 수 있다.
- 이벤트 기반 업데이트: Kubernetes 내에서 리소스 변경이 감지되면 external-dns가 이를 기반으로 DNS 레코드를 업데이트하여 DNS와 클러스터 상태의 일관성을 유지한다.
3. EKS에서 ExternalDNS 구성하기
3-1. IAM 권한 설정
1) IAM 정책 생성
- AWS IAM 권한을 사용하여 EKS에 Route 53과 상호 작용하는 데 필요한 액세스 권한을 부여한다.
- 하기 Json 코드를 통해 Route 53 레코드를 생성, 업데이트 및 삭제할 수 있는 권한을 ExternalDNS pod에 부여하는 IAM 정책을 생성한다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets"
],
"Resource": [
"arn:aws:route53:::hostedzone/*"
]
},
{
"Effect": "Allow",
"Action": [
"route53:ListHostedZones",
"route53:ListResourceRecordSets",
"route53:ListTagsForResource"
],
"Resource": [
"*"
]
}
]
}
2) IAM 역할 및 k8s service account 생성
- 하기 명령어를 통해 총 2개의 리소스가 생성된다.
- 위에서 만든 IAM 정책을 사용하여 service account에 대한 IAM 역할 생성
- IAM 역할과 연결된 service account 생성
- EKS 클러스터에서 Kubernetes 서비스 계정과 AWS IAM 역할을 결합하여 Kubernetes 워크로드가 AWS 리소스에 접근할 수 있도록 설정하는 데 사용된다.
eksctl create iamserviceaccount \
--name <SERVICE_ACCOUNT_NAME> \
--namespace <SERVICE_ACCOUNT_NAME_NAMESPACE> \
--cluster <CLUSTER_NAME> \
--attach-policy-arn <IAM_POLICY_ARN> \ ## 위에서 생성한 IAM 정책의 ARN
--approve \
--override-existing-serviceaccounts
- 배포가 완료되면 생성된 IAM 역할을 확인한다.
- 신뢰할 수 있는 엔터티로 OIDC 공급자가 설정되어 있고, 함께 생성된 service account만 해당 역할을 사용할 수 있게끔 설정되어 있는 것을 확인할 수 있다.


- 하기 명령어로 생성된 service account를 확인한다.
- service account의 yaml를 확인해보면 IAM 역할이 연결되어 있는것을 확인할 수 있다.
$ kubectl get sa
NAME SECRETS AGE
external-dns 0 91m
$ k get sa -n external-dns external-dns -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::XXXX:role/eksctl-eks1-addon-iamserviceaccount-external--Role1-XXX
name: external-dns
namespace: external-dns
3-2. External DNS 배포
- 하기 yaml 파일을 사용하여 External DNS를 배포한다.
- eks.amazonaws.com/role-arn -> 위에 생성된 IAM 역할의 ARN으로 변경
- domain-filter -> 자신의 Route 53 host zone으로 변경
- policy -> Route53에서 레코드 업데이트를 제어하는 정책
- upsert-only: 생성, 업데이트
- sync: 생성, 업데이트, 삭제
- create-only: 생성
- aws-zone-type -> Route 53의 타입
- public: public zone
- private: private zone
- 공백: public, private zone 모두 사용
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: external-dns
labels:
app.kubernetes.io/name: external-dns
rules:
- apiGroups: [""]
resources: ["services","endpoints","pods","nodes"]
verbs: ["get","watch","list"]
- apiGroups: ["extensions","networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get","watch","list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: external-dns-viewer
labels:
app.kubernetes.io/name: external-dns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: external-dns
namespace: default # change to desired namespace: externaldns, kube-addons
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
labels:
app.kubernetes.io/name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: external-dns
template:
metadata:
labels:
app.kubernetes.io/name: external-dns
spec:
serviceAccountName: external-dns
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.14.0
args:
- --source=service
- --source=ingress
- --domain-filter=example.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
- --provider=aws
- --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization
- --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both)
- --registry=txt
- --txt-owner-id=external-dns
env:
- name: AWS_DEFAULT_REGION
value: eu-west-1 # change to region where EKS is installed
- 다음 명령을 실행하여 배포가 성공했는지 확인한다.
$ kubectl get deployments -n external-dns
NAME READY UP-TO-DATE AVAILABLE AGE
external-dns 1/1 1 1 118m
- 로그를 확인하여 레코드가 업데이트되었는지 확인한다.
$ k logs -n external-dns external-dns-54655fbff7-pwf8q
(예시)
time="2024-11-16T01:46:22Z" level=info msg="Applying provider record filter for domains: [test.com.]"
time="2024-11-16T01:46:22Z" level=info msg="All records are already up to date"
4. ExternalDNS 설정 확인
- ExternalDNS 설정 확인을 위해 service나 ingress 리소스를 생성한다.
- 본 실습에서는 AWS Load Balancer Controller를 사전에 설치하여 사용중임으로 ingress 리소스를 생성하여 ExternalDNS 설정을 확인할 예정이다.
- 하기 yaml 파일로 ingress를 생성한다. 이때 external-dns.alpha.kubernetes.io/hostname 주석을 사용하여 Route 53에서 호스팅되는 도메인 이름을 입력한다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
external-dns.alpha.kubernetes.io/hostname: myweb.test.com
name: ingress-2048
namespace: game-2048
spec:
ingressClassName: alb
rules:
- http:
paths:
- backend:
service:
name: service-2048
port:
number: 80
path: /
pathType: Prefix
- ingress가 정상적으로 배포 되었는지 확인한다.
$ k get ingress -A
NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE
game-2048 ingress-2048 alb * k8s-game2048-ingress2-7b9863991b-173978868.ap-northeast-2.elb.amazonaws.com 80 3h48m
- Route53 record가 자동으로 생성되었는지 확인한다.
$ kubectl logs external-dns-54655fbff7-pwf8q
(예시)
time="2024-11-16T01:45:22Z" level=info msg="Desired change: CREATE cname-myweb.test.com TXT" profile=default zoneID=/hostedzone/XXXX zoneName=test.com.
time="2024-11-16T01:45:22Z" level=info msg="Desired change: CREATE myweb.test.com A" profile=default zoneID=/hostedzone/XXXX zoneName=test.com.
time="2024-11-16T01:45:22Z" level=info msg="Desired change: CREATE myweb.test.com TXT" profile=default zoneID=/hostedzone/XXXX zoneName=test.com.
참고
1. https://repost.aws/ko/knowledge-center/eks-set-up-externaldns
2. https://github.com/kubernetes-sigs/external-dns
'Cloud > AWS' 카테고리의 다른 글
[AWS] DynamoDB를 활용하여 간단한 웹사이트 구성 (3) | 2024.10.12 |
---|---|
[AWS] EKS에서 Ingress 및 AWS Load Balancer Controller (0) | 2024.08.06 |
[AWS] IAM 기초 (0) | 2024.07.28 |