NGINX Ingress Controller를 활용한 멀티 클러스터 DNS 자동화

NGINX | 2022년 10월 25일

사용자가 애플리케이션을 찾을 수 없다면 애플리케이션은 제 역할을 할 수 없습니다. 도메인 네임 시스템(DNS)은 도메인 이름을 IP 주소로 변환하여 앱과 웹사이트를 ‘찾아주는’ 인터넷 기술입니다. DNS는 매우 보편적이고 안정적이어서 평소에는 거의 의식하지 않습니다. 하지만 DNS에 문제가 생기면 모든 것이 멈춥니다. 특히 서비스가 끊임없이 생성되고 종료되는 마이크로서비스 아키텍처에서는 DNS가 제대로 작동하도록 보장하는 것이 최신 애플리케이션에 매우 중요합니다.

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

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

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

ExternalDNS와 NGINX Ingress Controller를 통합하면 표준 Kubernetes Ingress 리소스 또는 NGINX A 레코드를 관리하여, 표준 Kubernetes Ingress 리소스 또는 NGINX VirtualServer 사용자 정의 리소스에 선언된 호스트 이름에서 DNS 이름이 파생되도록 할 수 있습니다. 개발자와 DevOps 팀은 CI/CD 파이프라인에서 이 통합을 활용해 일반적으로 DNS를 담당하는 NetOps 팀의 개입 없이 여러 클러스터의 애플리케이션을 자동으로 검색할 수 있습니다.

이 게시물에서는 GitHub 리포지토리의 샘플 구성 파일을 사용하여 ExternalDNS를 NGINX Ingress Controller와 통합하는 방법을 설명합니다.

기본 아키텍처

NGINX Ingress Controller와 함께 ExternalDNS를 구현하기 위해, 먼저 개발자가 Kubernetes 앱을 외부에 노출하도록 Ingress 컨트롤러를 구성하는 기본 사례부터 살펴봅니다. 구성된 도메인 이름이 Kubernetes 클러스터의 공개 진입점으로 확인되기 전까지는 클라이언트가 앱에 연결할 수 없습니다.

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

ExternalDNS Kubernetes 배포가 NGINX Ingress Controller 및 DNS 공급자와 상호 작용하는 방식을 보여 주는 다이어그램

ExternalDNS와 NGINX Ingress Controller 통합

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

사전 요구 사항

  1. 등록된 도메인을 하나 이상 만드세요. 아래 단계에서 해당 도메인 이름을 <my‑domain> 대신 사용하세요. (도메인 등록 방법을 설명하는 글은 많이 있으며, 그중에는 PCMag의 가이드도 있습니다.)
  2. 다음을 사용하여 NGINX Ingress Controller를 배포합니다: 매니페스트 또는 Helm 차트. 배포 사양에 다음 명령줄 인수에 해당하는 항목을 추가합니다:
    • -enable-external-dns – ExternalDNS와의 통합을 활성화합니다.
    • -external-service=nginx-ingress – NGINX Ingress Controller가 공개 진입점을 알리도록 하여 DNS 공급자가 관리하는 A 레코드에 기록되게 합니다. 공개 진입점의 호스트 이름은 외부 서비스인 nginx-ingress로 확인됩니다.
  3. Kubernetes 클러스터를 온프레미스에 배포하는 경우 외부 로드 밸런서를 프로비저닝하세요. 무료 eBook인 Get Me to the Cluster에서 BGP를 사용하는 외부 로드 밸런서로 NGINX를 배포하는 방법을 안내합니다. 또는 F5 BIG‑IP이나 MetalLB를 사용할 수 있습니다.
  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"

NGINX Ingress Controller 및 ExternalDNS 배포

  1. 샘플 배포를 위한 GitHub 저장소를 복제하고 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
  1. ExternalDNS 배포 사양에서 다음 인수를 업데이트합니다(샘플 배포의 external-dns-gcloud.yaml 파일 59~62번째 줄): 참고: ExternalDNS 배포 사양에 포함해야 하는 인수는 선택한 DNS 공급자에 따라 달라질 수 있습니다. 다양한 DNS 공급자를 사용하여 클러스터에 ExternalDNS를 배포하는 방법에 대한 튜토리얼 목록은 ExternalDNS 설명서를 참조하세요.
    • --domain-filter – 이전 섹션의 4단계에서 생성한 도메인의 이름입니다(샘플 배포에서는 external-dns.<my-domain>). 이 도메인만 사용되도록 기존 값을 모두 제거합니다.
    • --provider – DNS 공급자(샘플 배포에서는 Google DNS용 google).
    • --google-project – 샘플 배포에 사용 중인 Google 프로젝트의 이름입니다(Google 프로젝트가 두 개 이상인 경우에만 필요).
    • --txt-owner-id – 사용자가 선택하는 ID입니다(샘플 배포에 고유해야 함).
  2. 클러스터에 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

NGINX Ingress Controller 구성

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

  1. In app-virtual-server.yaml에서 host 필드(6번째 줄)를 설정합니다:
 6    host: ingress.external-dns.<my-domain>
  1. 이 값과 domain-filter의 59번째 줄에 있는 값 간의 매핑을 통해 external-dns-gcloud.yaml(이전 섹션의 2단계에서 설정됨)에서 DNS 레코드를 자동으로 업데이트할 수 있습니다.
  2. Apply 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
  1. DNS 유형 A 레코드가 DNS 영역에 추가되었는지 확인합니다. 특히 DATA 필드의 IP 주소는 이전 단계에서 실행한 kubectl get vs 명령의 출력에 있는 IP 필드와 일치해야 합니다(NGINX Ingress Controller를 노출하는 LoadBalancer 유형 서비스의 외부 IP 주소 또는 온프레미스 배포 환경에서 이에 상응하는 주소).
$ gcloud dns record-sets list --zone external-dns-<my-domain> -name ingress.external-dns.<my-domain> --type ANAME                               TYPE     TTL     DATA
ingress.external-dns.<my-domain>.  A        300     34.168.X.Y
  1. VirtualServer 호스트 이름을 로컬 머신에서 확인할 수 있는지 검증하려면 DNS 영역에 할당된 네임 서버(이 경우 my-ns-domains)를 확인합니다.
$ gcloud dns record-sets list --zone external-dns.<my-domain> --name external-dns.<my-domain>. --type NSNAME                        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
  1. 이전 단계에서 검색한 DNS 레코드를 등록된 도메인의 전용 네임 서버로 사용합니다. 이렇게 하면 등록된 도메인이 4단계에서 생성한 DNS 영역의 상위 영역으로 설정됩니다. 자세한 내용은 기본 요건을 참조하세요.
  2. VirtualServer 호스트 이름이 이제 전 세계 인터넷에 공개되었으므로 해당 호스트 이름에 액세스할 수 있는지 확인합니다.
$ curl -i --insecure https://ingress.external-dns.<my-domain>/teaHTTP/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

여러 Kubernetes 클러스터 확장

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

외부 DNS 레코드 생성을 자동화하고 이를 새 클러스터 진입점으로 확인하는 다이어그램

CI/CD 파이프라인에서 코드형 인프라(Infrastructure-as-Code) 도구를 사용하여 새 클러스터를 생성하고, ExternalDNS와 NGINX Ingress Controller를 통해 외부 트래픽에 노출할 수도 있습니다. 또한 검색 기능의 활성화 방식에 따라 여러 DNS 영역은 물론 여러 DNS 공급자까지 관리할 수 있습니다.

결론

생산성과 보안 침해를 완화하는 보안 조치 사이에서 균형을 맞추는 일은 쉽지 않습니다. DevOps 팀에 제한을 적용하면 NetOps/SecOps 팀과 마찰이 발생하는 경우가 많습니다. 이상적인 균형은 조직마다 다르며, NGINX는 조직의 우선순위와 요구사항에 부합하는 균형을 확립할 수 있는 유연성을 제공합니다.

과거에는 애플리케이션 소유자가 애플리케이션을 외부 시스템에 연결하기 위해 NetOps 팀에 의존했습니다. NGINX와 ExternalDNS의 통합을 활용하면 개발자와 DevOps 팀이 검색 가능한 애플리케이션을 직접 배포할 수 있어 혁신적인 서비스를 시장에 출시하는 데 걸리는 시간을 단축할 수 있습니다.

Kubernetes에서 NGINX를 시작하는 방법을 자세히 알아보려면 무료 eBook F5 NGINX를 활용한 Kubernetes 트래픽 관리: 실용 가이드를 다운로드하세요.

또한 지금 바로 30일 무료 평가판을 신청하여 NGINX App Protect WAF 및 DoS가 포함된 NGINX Ingress Controller를 시작하거나, 사용 사례에 대해 논의하려면 문의해 주세요.


공유

작성자 소개

관련 블로그 게시물

시청하기: KubeCon North America 2023에서의 NGINX Gateway Fabric
NGINX | 2023. 11. 30.

시청하기: KubeCon North America 2023에서의 NGINX Gateway Fabric

이 영상에서는 KubeCon의 NGINX 부스를 찾아가, 저희가 공개한 Kubernetes Gateway API 구현을 살펴봅니다.

F5 NGINX로 대규모 WAF 플릿을 확인하고 관리하는 2가지 방법
NGINX | 2023. 03. 23.

F5 NGINX로 대규모 WAF 플릿을 확인하고 관리하는 2가지 방법

앱 보안을 강화하는 두 가지 방법을 소개합니다. NGINX Management Suite를 통해 WAF 운영에 대한 가시성을 높이고, NGINX App Protect WAF를 활용해 코드형 보안을 구현하는 것입니다.

Ingress 컨트롤러 선택 가이드, 4부: NGINX Ingress Controller 옵션
NGINX | 2021. 09. 27.

Ingress 컨트롤러 선택 가이드, 4부: NGINX Ingress Controller 옵션

개발 주체, 개발 철학, 프로덕션 환경 준비도, 보안 및 지원을 기준으로 어떤 NGINX Ingress 컨트롤러가 가장 적합한지 알아보세요.

진화하는 공격 환경에 NGINX App Protect Denial of Service가 적응하는 방법
NGINX | 2021. 07. 06.

진화하는 공격 환경에 NGINX App Protect Denial of Service가 적응하는 방법

NGINX App Protect Denial of Service(DoS)가 계층 7 DoS 공격을 방어하기 위해 완화 방법을 실시간으로 조정하는 방식을 설명합니다. 정상적인 사용자 행동과 서버 상태에 대한 모델을 생성하여 공격을 나타내는 이상 징후를 감지하고 맞춤형 완화 시그니처를 적용할 수 있습니다.

NGINX Instance Manager를 활용한 대규모 구성 업데이트 및 인증서 관리
NGINX | 2021. 06. 30.

NGINX Instance Manager를 활용한 대규모 구성 업데이트 및 인증서 관리

NGINX Instance Manager 버전 1.0에는 두 가지 새로운 기능이 도입되었습니다. NGINX 인스턴스에 태그와 사용자 역할을 지정하면 전체 그룹에 구성을 한 번에 적용할 수 있습니다. 인증서 검사는 만료 예정인 인증서를 감지하여 서비스 중단을 방지할 수 있도록 인증서를 교체할 수 있게 해줍니다.

Netflix가 자사 CDN의 핵심으로 NGINX를 선택한 이유
NGINX | 2015. 03. 25.

Netflix가 자사 CDN의 핵심으로 NGINX를 선택한 이유

Netflix가 글로벌 콘텐츠 전송 네트워크인 Open Connect의 스트리밍 미디어 기술로 NGINX를 선택한 이유를 NGINX 개발자 Gleb Smirnoff에게서 알아보세요.