[udemy] Ingress - ExternalDNS
ExternalDNS
Kubernetes 클러스터에 ExternalDNS를 배포하면, Azure DNS와 통합하여 DNS 레코드를 자동으로 관리할 수 있습니다.
주요 기능
- 자동 DNS 레코드 관리: Kubernetes 리소스(예: 서비스, 인그레스)가 생성되거나 삭제될 때, ExternalDNS는 해당 리소스에 대한 DNS 레코드를 자동으로 생성하거나 삭제합니다.
- 다양한 DNS 제공업체 지원: AWS, Google Cloud, Azure 등 여러 클라우드 제공업체의 DNS 서비스를 지원합니다.
- 정확한 DNS 레코드 업데이트: ExternalDNS는 클러스터의 상태를 주기적으로 확인하여 DNS 레코드가 항상 최신 상태를 유지하도록 합니다.
- 유연한 구성: 다양한 설정 옵션을 통해 DNS 레코드의 생성 및 업데이트 방식을 세밀하게 조정할 수 있습니다.
관리 ID 생성
# 관리 ID 생성
관리 ID를 생성한 뒤, Azure DNS Zone이 위치한 리소스 그룹에 대해 "기여자" 역할을 부여한다.
내 AKS의 VMSS > 사용자 할당 항목 > 관리 ID를 추가해준다.
즉 해당 작업으로 Azure DNS Zone - 관리 ID - VMSS를 연결하였고,
Kubernetes 리소스(예: 서비스, 인그레스)가 생성되거나 삭제될 때,
ExternalDNS는 해당 리소스에 대한 DNS 레코드를 자동으로 생성하거나 삭제한다.
Secret 생성
# azure.json 파일 생성
{
"tenantId": "테넌트 ID",
"subscriptionId": "구독 ID",
"resourceGroup": "Azure DNS Zone이 위치한 리소스 그룹명",
"useManagedIdentityExtension": true,
"userAssignedIdentityID": "위에서 생성한 관리 ID"
}
external-dns.yaml 파일에서 참조할 secret 파일을 생성한다.
참고로 userAssignedIdentityID는 위에서 생성한 클라이언트 ID를 복사하면 된다.
# 생성 및 확인
kubectl create secret generic azure-config-file --from-file=azure.json
kubectl get secrets
---
NAME TYPE DATA AGE
azure-config-file Opaque 1 10s
ExternalDNS 생성
# external-dns.yaml 파일 작성
apiVersion: v1
kind: ServiceAccount
metadata:
name: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
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
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: external-dns
namespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: 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 # (optional) limit to only example.com domains; change to match the zone created above.
- --provider=azure
#- --azure-resource-group=MyDnsResourceGroup # (optional) use the DNS zones from the tutorial's resource group
- --txt-prefix=externaldns-
volumeMounts:
- name: azure-config-file
mountPath: /etc/kubernetes
readOnly: true
volumes:
- name: azure-config-file
secret:
secretName: azure-config-file
- ExternalDNS는 Kubernetes 클러스터 내에서 Pod 형태로 작동합니다. ExternalDNS는 Kubernetes API를 통해 서비스와 인그레스 리소스를 모니터링하고, 이들 리소스에 대한 DNS 레코드를 자동으로 생성 및 업데이트하는 역할을 합니다.
- ServiceAccount는 ExternalDNS가 Kubernetes API에 접근할 수 있도록 인증 정보를 제공합니다.
- ClusterRole은 ExternalDNS가 Kubernetes 리소스(서비스, 엔드포인트, 파드, 노드, 인그레스)에 대한 읽기 권한을 갖도록 정의합니다.
- ClusterRoleBinding은 ServiceAccount와 ClusterRole을 연결하여, external-dns 서비스 계정이 external-dns 역할을 수행할 수 있도록 합니다.
- Deployment은 ExternalDNS 애플리케이션을 배포합니다. 이 설정에서는 Azure DNS를 사용하도록 구성되어 있으며, 서비스와 인그레스 리소스에서 DNS 레코드를 생성합니다. azure-config-file이라는 비밀을 통해 Azure 인증 정보를 제공합니다.
# 생성
kubectl apply -f external-dns.yml
애플리케이션 생성
# 01-NginxApp1-Deployment.yml 파일 작성
apiVersion: apps/v1
kind: Deployment
metadata:
name: app1-nginx-deployment
labels:
app: app1-nginx
spec:
replicas: 1
selector:
matchLabels:
app: app1-nginx
template:
metadata:
labels:
app: app1-nginx
spec:
containers:
- name: app1-nginx
image: stacksimplify/kube-nginxapp1:1.0.0
ports:
- containerPort: 80
app1-nginx 애플리케이션의 Deployment 파일을 작성한다.
# 생성
kubectl apply -f 01-NginxApp1-Deployment.yml
# 02-NginxApp1-ClusterIP-Service.yml 파일 작성
apiVersion: v1
kind: Service
metadata:
name: app1-nginx-clusterip-service
labels:
app: app1-nginx
spec:
type: ClusterIP
selector:
app: app1-nginx
ports:
- port: 80
targetPort: 80
app1-nginx 애플리케이션의 Service 파일을 작성한다.
# 생성
kubectl apply -f 02-NginxApp1-ClusterIP-Service.yml
# 03-Ingress-with-ExternalDNS.yml 파일 작성
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginxapp1-ingress-service
#annotations:
#kubernetes.io/ingress.class: "nginx"
spec:
ingressClassName: nginx
rules:
- host: eapp1.bbiyak.shop
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app1-nginx-clusterip-service
port:
number: 80
Ingress 파일을 작성한다.
eapp1.bbiyak.shop으로 접근 시, app1-nginx-clusterip-service로 접근이 된다.
# 생성
kubectl apply -f 03-Ingress-with-ExternalDNS.yml
확인
# Azure DNS Zone 확인
리소스 생성과 동시에 자동으로 Azure DNS Zone에도 레코드가 반영되는 것을 확인할 수 있다.
# nslookup 조회
nslookup eapp1.bbiyak.shop
Server: 168.126.63.1
Address: 168.126.63.1#53
Non-authoritative answer:
Name: eapp1.bbiyak.shop
Address: 20.214.192.69
nslookup eapp1.bbiyak.shop 조회 시, Ingress의 External IP로 정상적으로 반환
# 웹 사이트 접근
Ingress에 따라, eaap1.bbiyak.shop/index.html 접근 시
정상적으로 애플리케이션에 접속되는 것을 확인 가능
[참고 영상]
Udemy - Azure Kubernetes Service with Azure DevOps and Terraform
섹션 13 : Ingress - ExternalDNS for Azure DNS on AKS
[참고 문서]
https://github.com/stacksimplify/azure-aks-kubernetes-masterclass/tree/master/12-ExternalDNS-for-AzureDNS-on-AKS