NGINX Ingress Controller로 Multi-Cluster DNS 자동화 구현하기

사용자가 애플리케이션을 찾을 수 없으면 애플리케이션은 목적을 달성할 수 없습니다. DNS(Domain Name System)는 도메인 이름을 IP 주소로 변환하여 애플리케이션과 웹사이트를 “찾는” 인터넷 기술입니다. DNS는 매우 보편적이고 신뢰할 수 있어서 대부분 문제에 대해 생각조차 하지 않습니다. 그러나 DNS 문제가 있으면 모든 것이 중지됩니다. DNS가 작동하는지 확인하는 것은 최신 애플리케이션, 특히 서비스가 지속적으로 가동 및 중지되는 마이크로서비스 아키텍처(MSA)에서 매우 중요합니다.

이전 게시물에서 동일한 클러스터(마케팅 애플리케이션의 경우 unit-demo.marketing.net 및 엔지니어링 애플리케이션의 경우 unit-demo.engineering.net)에서 실행되는 애플리케이션에 해당하는 두 개의 하위 도메인에 대한 DNS 레코드를 정의하고 동일한 클러스터 진입 지점(클러스터의 NGINX Ingress Controller의 외부 IP 주소)으로 해결하는 방법에 대해 설명했습니다. SNI(Server Name Indication) 라우팅은 NGINX Ingress Controller에서 구성되어 사용자가 요청한 도메인 이름을 기반으로 적절한 애플리케이션에 대한 연결을 인증하고 라우팅합니다.

그러나 많은 조직에서는 해당 사용 사례를 확장하고 여러 Kubernetes 클러스터에 애플리케이션을 배포해야 합니다. 이 클러스터는 클라우드 공급자 지역에 분산될 수 있습니다. 외부 트래픽이 새 클러스터 지역에 도달하려면 해당 지역으로 확인되는 DNS 영역을 생성해야 합니다.

이전에는 이 프로세스에서 도메인 Registry를 수동으로 생성하고 호스트 레코드를 적절하게 업데이트하기 위해 타사 공급자(예: GoDaddy 또는 DNSExit)를 사용해야 했습니다. 이제 ExternalDNS Kubernetes 프로젝트는 공용 DNS 서버를 통해 Kubernetes 리소스를 검색할 수 있도록 하여 프로세스를 자동화합니다. 즉, Kubernetes API를 사용하여 DNS 공급자 목록을 구성합니다.

ExternalDNS와 NGINX Ingress Controller 간의 통합을 통해 DNS 이름이 표준 Kubernetes Ingress 리소스 또는 NGINX VirtualServer 사용자 지정 리소스에 선언된 호스트 이름에서 파생되도록 DNS A 레코드를 관리할 수 있습니다. 개발자와 DevOps 팀은 CI/CD pipeline에서 이 통합을 활용하여 NetOps 팀(일반적으로 DNS를 소유함)을 개입시키지 않고도 다양한 클러스터에서 애플리케이션을 자동으로 검색할 수 있습니다.

이 포스트에서는 GitHub repo의 샘플 구성 파일을 사용하여 외부 DNS를 NGINX Ingress Controller와 통합하는 방법을 보여줍니다.

목차

1. 기본 아키텍처
2. ExternalDNS 및 NGINX Ingress Controller 통합
2-1. 필수 구성 요소
2-2. NGINX Ingress Controller 및 ExternalDNS 배포
2-3. NGINX Ingress Controller 구성
3. Scaling Out Multiple Kubernetes Clusters
4. 결론

1. 기본 아키텍처

NGINX Ingress Controller로 ExternalDNS를 구현하려면 개발자가 Kubernetes 애플리케이션을 외부에 노출하도록 Ingress Controller를 구성하는 기본 사례부터 시작합니다. 구성된 도메인 이름이 Kubernetes 클러스터의 public entry point로 확인될 때까지 클라이언트는 애플리케이션에 연결할 수 없습니다.

NGINX Ingress Controller는 중간 ExternalDNS Kubernetes 배포를 통해 DNS 공급자와 상호 작용하여 external DNS 레코드를 사용하여 Kubernetes 애플리케이션을 자동으로 검색할 수 있습니다. 다이어그램에서 검은색 선은 외부 사용자가 Kubernetes 클러스터의 애플리케이션에 액세스하는 데이터 경로를 나타냅니다. 보라색 선은 애플리케이션 소유자가 NGINX Ingress Controller 구성에서 VirtualServer 리소스를 사용하여 외부 DNS 레코드를 관리하고 외부 DNS가 DNS 공급자에 액세스하는 제어 경로를 나타냅니다.

Diagram how ExternalDNS Kubernetes deployment interacts NGINX Ingress Controller with DNS provider

2. ExternalDNS 및 NGINX Ingress Controller 통합

ExternalDNS와 NGINX Ingress Controller를 통합하려면 다음 섹션의 단계를 수행하십시오.

2-1. 필수 구성 요소

1. 하나 이상의 등록된 도메인을 만듭니다. 아래 단계에서 해당 이름을 <my-domain>로 바꿉니다.

(PCMag의 가이드를 포함하여 도메인을 등록하는 방법에 대한 많은 문서를 사용할 수 있습니다.)

2. manifest 또는 Helm chart를 사용하여 NGINX Ingress Controller를 배포합니다. 배포 사양에 다음 command‑line arguments에 해당하는 항목을 추가합니다.

  • -enable-external-dns – ExternalDNS와의 통합을 활성화합니다.
  • -external-service=nginx-ingress – DNS 공급자가 관리하는 A 레코드에 기록하기 위해 public entry point을 알리도록 NGINX Ingress Controller에 지시합니다. public entry point의 호스트 이름은 외부 서비스 nginx-ingress로 확인됩니다.

3. Kubernetes 클러스터를 on premises에 배포하는 경우 외부 load balancer를 프로비저닝(provisioning)하십시오.

4. 필요한 경우 ExternalDNS에서 지원하는 공급자에 DNS 영역을 만듭니다. 이 명령어는 샘플 배포인 Google Cloud DNS에 사용되는 공급자를 위한 것입니다.

$ gcloud dns managed-zones create "external-dns-<my-domain>" --dns-name "external-dns.<my-domain>." --description "Zone automatically managed by ExternalDNS"

2-2. NGINX Ingress Controller 및 ExternalDNS 배포

1. 샘플 배포를 위한 GitHub repository를 복제하고 NGINX Ingress Controller를 배포합니다.

$ git clone https://github.com/nginxinc/NGINX-Demos.git && cd NGINX-Demos/external-dns-nginx-ingress/ 
$ kubectl apply -f nginx-ingress.yaml && kubectl apply -f loadbalancer.yaml

2. ExternalDNS 배포 사양에서 다음 인수를 업데이트합니다(샘플 배포의 경우 external-dns-gcloud.yaml의 행 59–62).

  • –domain-filter – 이전 섹션의 4단계에서 생성된 도메인의 이름입니다(샘플 배포에서는 external-dns.). 이 도메인만 사용되도록 기존 값을 제거하십시오.
  • –provider – DNS 공급자(샘플 배포에서 Google DNS의 경우 google).
  • –google-project – 샘플 배포에 사용 중인 Google 프로젝트의 이름입니다(둘 이상의 Google 프로젝트가 있는 경우에만 필요).
  • –txt-owner-id – 선택한 ID입니다(샘플 배포에 고유).

Note: ExternalDNS 배포 사양에 포함해야 하는 인수는 선택한 DNS 공급자에 따라 다를 수 있습니다. 서로 다른 DNS 공급자를 사용하여 클러스터에 ExternalDNS를 배포하는 방법에 대한 자습서 목록은 ExternalDNS 설명서를 참조하십시오.

3. 클러스터에 ExternalDNS를 배포하고 배포가 성공적으로 실행되는지 확인합니다(출력이 가독성을 위해 두 줄로 분산됨).

$ kubectl apply -f external-dns-gcloud.yaml
$ kubectl get pods -o wide
NAME                                READY  STATUS    ...
external-dns-4hrytf7f98f-ffuffjbf7  1/1    Running   ...
    ... RESTARTS   AGE
    ... 0          1m

2-3. NGINX Ingress Controller 구성

다음으로 외부 연결을 Kubernetes 애플리케이션으로 라우팅하는 Ingress load balancing 규칙을 사용하여 VirtualServer 리소스를 구성합니다.

1. app-virtual-server.yaml에서 호스트 필드(6행)를 설정합니다.

 6    host: ingress.external-dns.<my-domain>

이 값과 external-dns-gcloud.yaml의 59행에 있는 domain-filter 값 간의 매핑은 DNS 레코드의 자동 업데이트를 활성화하는 것입니다.

2. app-virtual-server.yaml을 적용하고 VirtualServer가 올바르게 구성되었는지 확인하십시오.

$ kubectl apply -f app-secret.yaml && kubectl apply -f app-virtual-server.yaml
$ kubectl get vs 
NAME   STATE   HOST                              IP            
cafe   Valid   ingress.external-dns.<my-domain>  34.168.X.Y

3. DNS 유형 A 레코드가 DNS 영역에 추가되었는지 확인합니다. 특히 DATA 필드의 IP 주소는 이전 단계에서 kubectl get vs 명령의 출력에 있는 IP 필드와 일치해야 합니다(NGINX Ingress Controller를 노출하는 LoadBalancer 유형 서비스의 외부 IP 주소 또는 on‑premises 배포 IP).

$ gcloud dns record-sets list --zone external-dns-<my-domain> -name ingress.external-dns.<my-domain> --type A
NAME                               TYPE     TTL     DATA
ingress.external-dns.<my-domain>.  A        300     34.168.X.Y

4. VirtualServer 호스트 이름을 로컬 시스템에서 확인할 수 있는지 확인하려면 DNS 영역(이 경우 my-ns-domains)에 할당된 이름 서버를 가져옵니다.

$ gcloud dns record-sets list --zone external-dns.<my-domain> --name external-dns.<my-domain>. --type NS
NAME                        TYPE      TTL     DATA
external-dns.<my-domain>.   NS        21600   my-ns-domains

$ dig +short @my-ns-domains ingress.external-dns.<my-domain>
34.168.X.Y

5. 이전 단계에서 검색한 DNS 레코드를 등록된 도메인의 전용 name server로 사용합니다. 이렇게 하면 등록된 도메인이 필수 구성 요소의 4단계에서 만든 DNS 영역의 상위 영역으로 설정됩니다.

6. 이제 VirtualServer 호스트 이름이 글로벌 인터넷에 노출되었으므로 액세스할 수 있는지 확인하십시오.

$ curl -i --insecure https://ingress.external-dns.<my-domain>/tea
HTTP/1.1 200 OK
Server: nginx/1.23.0
Date: Day, DD MM YYYY hh:mm:ss TZ
Content-Type: text/plain
Content-Length: 160
Connection: keep-alive
Expires: Day, DD MM YYYY hh:mm:ss TZ
Cache-Control: no-cache

3. Scaling Out Multiple Kubernetes Clusters

외부 DNS 레코드 생성을 자동화하고 다이어그램에서 새 클러스터 entry point(Kubernetes 클러스터 1 및 Kubernetes 클러스터 2)으로 해하여 아키텍처를 빠르게 확장하고 여러 클러스터를 자동으로 검색할 수 있습니다. NGINX Ingress Controller 및 ExternalDNS 배포NGINX Ingress Controller 구성의 지침을 반복합니다.

Diagram automating the creation of external DNS records and resolving them to new cluster entry points

또한 CI/CD pipeline에서 Infrastructure-as-Code 도구를 사용하여 ExternalDNS 및 NGINX Ingress Controller를 사용하여 새 클러스터를 생성하고 외부 트래픽에 노출할 수 있습니다. 또한 검색이 활성화된 방식에 따라 여러 DNS 영역 또는 여러 DNS 공급자를 관리할 수 있습니다.

4. 결론

침해를 완화하는 보안 조치와 생산성의 균형을 맞추는 것은 어려울 수 있습니다. DevOps 팀에 제한을 부과하면 종종 NetOps/SecOps 팀과 마찰이 발생합니다. 이상적인 균형은 조직마다 다르며 NGINX는 우선 순위와 요구 사항을 준수하는 균형을 설정할 수 있는 유연성을 제공합니다.

과거에는 애플리케이션 소유자가 NetOps 팀에 의존하여 애플리케이션을 외부 시스템에 연결했습니다. NGINX와 ExternalDNS 통합을 사용하여 개발자와 DevOps 팀은 자체적으로 검색 가능한 애플리케이션을 배포할 수 있는 권한을 부여받아 혁신을 위한 시장 출시 시간을 단축할 수 있습니다.

NGINX App Protect WAF 및 DoS가 포함된 NGINX Ingress Controller의 30일 무료 평가판을 신청하거나 사용 사례에 대해 최신 소식을 빠르게 전달받고 싶으시면 아래 뉴스레터를 구독하세요.