kubernetes/udemy

[udemy] Ingress - ExternalDNS

bbiyak2da 2025. 2. 22. 17:36

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