[편집자 주 – 이 게시물은 원본에서 언급된 별도의 동적 구성 모듈을 대체하며 해당 모듈을 더 이상 사용하지 않도록 하는 NGINX Plus API를 참조하도록 업데이트되었습니다.]
One of the great advantages of a 마이크로서비스 아키텍처의 큰 장점 중 하나는 서비스 인스턴스를 빠르고 쉽게 확장할 수 있다는 것입니다. 서비스 인스턴스가 여러 개라면 로드 밸런서와 함께 사용 가능한 서비스 인스턴스 집합의 변경 사항을 로드 밸런서에 신속하게 알릴 방법이 필요합니다. 이를 서비스 디스커버리라고 합니다. NGINX Plus는 서비스 디스커버리 시스템과 통합할 수 있는 두 가지 옵션, 즉 NGINX Plus API와 도메인 이름 시스템(DNS) 재확인을 제공합니다. 이 블로그 게시물에서는 후자를 중점적으로 다룹니다.
가상 머신(VM)이나 컨테이너를 추가 또는 제거하여 서비스 인스턴스(이 블로그 게시물에서는 백엔드라고 부름)를 확장하거나 축소할 때는 백엔드 집합의 모든 변경 사항이 반영되도록 로드 밸런서 구성을 변경해야 합니다. 애플리케이션에 따라 확장 또는 축소가 하루에 여러 번, 시간당 여러 번, 심지어 분당 여러 번 발생할 수도 있습니다. 구성 변경이 매우 빈번하므로 이를 자동화해야 하며, 그 방법 중 하나가 DNS를 통한 서비스 디스커버리입니다.
현재 애플리케이션을 실행하는 많은 플랫폼(예: Kubernetes)은 DNS를 사용한 서비스 검색을 지원합니다. 이 블로그 게시물의 끝부분에는 NGINX Plus를 널리 사용되는 플랫폼 및 DNS 기반 서비스 검색 도구와 통합하는 방법을 설명하는 문서 링크가 제공되어 있습니다.
주요 DNS 기능 간단히 살펴보기
DNS를 통한 서비스 검색을 구성하는 방법을 설명하기에 앞서, 특히 관련성이 높거나 유용한 DNS 프로토콜의 몇 가지 기능을 간단히 살펴보겠습니다.
TTL(Time‑to‑Live)
DNS 클라이언트가 오래된 정보를 사용하지 않도록 DNS 레코드에는 클라이언트가 해당 레코드를 유효한 것으로 간주할 수 있는 기간을 정의하는 TTL(time-to-live) 필드가 포함됩니다. DNS 표준을 준수하려면 레코드의 TTL이 만료되었을 때 클라이언트가 DNS 서버에 업데이트를 요청해야 합니다. NGINX Plus는 기본적으로 TTL을 따르지만, 레코드의 “수명”을 더욱 세밀하게 제어할 수도 있습니다. 즉, NGINX Plus가 TTL을 무시하고 지정된 주기로 레코드를 업데이트하도록 구성할 수 있습니다. (NGINX Open Source가 TTL을 처리하는 방식은 이 게시물의 뒷부분에서 설명하겠습니다.)
TCP를 통한 DNS
기본적으로 DNS 클라이언트와 서버는 UDP를 통해 통신하지만, 도메인 이름이 다수의 백엔드 IP 주소로 확인되는 경우 전체 응답이 512 바이트로 제한된 단일 UDP 데이터그램에 들어가지 않을 수 있습니다. UDP 대신 TCP를 사용하면 이 문제를 해결할 수 있습니다. 전체 레코드 집합이 하나의 데이터그램에 들어가지 않으면 서버는 응답에 잘림 플래그를 설정하여, 모든 레코드를 가져오기 위해 TCP로 전환하도록 클라이언트에 알립니다. TCP를 통한 DNS는 NGINX 버전 1.9.11 이상 및 NGINX Plus R9 이상에서 지원됩니다. 자세한 내용은 블로그의 NGINX 및 NGINX Plus를 사용한 DNS 트래픽 부하 분산을 참조하세요.
SRV 레코드
DNS는 호스트 이름을 IP 주소로 확인하지만, 포트 번호는 어떻게 처리할까요? Docker 컨테이너의 부하를 분산하는 경우처럼 포트 번호가 동적으로 할당되기 때문에 잘 알려진 포트 번호를 사용할 수 없는 경우가 있습니다. DNS에는 포트 번호와 몇 가지 다른 매개변수를 포함하는 특수한 유형의 레코드인 서비스(SRV) 레코드가 있습니다. R9 이상에서 NGINX Plus는 SRV 레코드를 지원하므로 해당 레코드에서 포트 정보를 추출할 수 있습니다.
편집자 주 – NGINX Plus R9의 모든 새로운 기능에 대한 개요는 블로그의 NGINX Plus R9 발표를 참조하세요.
NGINX 및 NGINX Plus에서 DNS를 사용한 서비스 디스커버리 방법
이제 NGINX와 NGINX Plus에서 DNS를 서비스 디스커리에 활용하는 다섯 가지 방법을 고급 수준이 높아지는 순서대로 살펴보겠습니다. 처음 세 가지 방법은 NGINX와 NGINX Plus 모두에서 사용할 수 있으며, 마지막 두 가지 방법은 NGINX Plus에서만 사용할 수 있습니다.
In this survey of service‑discovery methods, we’ll assume we have an authoritative name server for the zone example.com, with IP address 10.0.0.2. There are three backend servers that correspond to the domain name backends.example.com, as shown in the following output from the nslookup utility. With the first four methods we’ll discuss, NGINX and NGINX Plus request standard A records from DNS; with the final method, NGINX Plus requests SRV records instead.
$ nslookup backends.example.com 10.0.0.2Server: 10.0.0.2
Address: 10.0.0.2#53
Name: backends.example.com
Address: 10.0.0.11
Name: backends.example.com
Address: 10.0.0.10
Name: backends.example.com
Address: 10.0.0.12NGINX에서 서비스 검색을 위해 DNS 사용
먼저 DNS를 사용하는 세 가지 방법을 살펴보겠습니다. 이 방법들은 NGINX Open Source에서 사용할 수 있으며, 앞서 언급했듯이 NGINX Plus에서도 사용할 수 있습니다.
도메인 이름을 proxy_pass 지시문에 사용하기
업스트림 서버(백엔드) 그룹을 정의하는 가장 간단한 방법은 도메인 이름을 proxy_pass 지시문의 매개변수로 지정하는 것입니다:
server { location / {
proxy_pass http://backends.example.com:8080;
}
}NGINX가 시작되거나 구성을 다시 로드할 때 DNS 서버에 질의하여 backends.example.com을 확인합니다. DNS 서버는 위에서 설명한 세 백엔드의 목록을 반환하며, NGINX는 기본 라운드 로빈 알고리즘을 사용하여 이들 간에 요청 부하를 분산합니다. NGINX는 OS 구성 파일인 /etc/resolv.conf에서 DNS 서버를 선택합니다.
이 방법은 서비스 검색 방식 중 유연성이 가장 떨어지며, 다음과 같은 추가적인 단점이 있습니다:
- 도메인 이름을 확인할 수 없으면 NGINX가 시작되지 않거나 구성을 다시 로드하지 못합니다.
- NGINX는 레코드의 TTL 값을 무시하고 다음 재시작 또는 구성 다시 로드 시점까지 DNS 레코드를 캐시합니다.
- 다른 부하 분산 알고리즘을 지정할 수 없으며, 수동 상태 확인이나
server지시문의 매개변수로 정의되는 기타 기능도 구성할 수 없습니다. 이에 대해서는 다음 섹션에서 설명하겠습니다.
업스트림 서버 그룹에서 도메인 이름 사용
NGINX에서 제공하는 부하 분산 옵션을 활용하려면 업스트림 서버 그룹을 upstream 구성 블록에 정의할 수 있습니다. 단, 개별 서버를 IP 주소로 식별하는 대신 도메인 이름을 server 지시문의 매개변수로 사용합니다.
As with the 첫 번째 방법과 마찬가지로 backends.example.com은 NGINX가 시작되거나 구성을 다시 로드할 때 세 개의 백엔드 서버로 확인됩니다. 하지만 이제 더 정교한 부하 분산 알고리즘인 최소 연결을 정의하고 max_fails 매개변수를 사용하여 수동 상태 확인을 활성화할 수 있습니다. 이때 요청이 세 번 연속 실패하면 NGINX가 해당 서버를 다운 상태로 표시하도록 지정합니다.
upstream backends { least_conn;
server backends.example.com:8080 max_fails=3;
}
server {
location / {
proxy_pass http://backends;
}
}이 방법을 사용하면 부하 분산 알고리즘을 선택하고 상태 확인을 구성할 수 있지만, 시작, 재로드 및 TTL 측면에서는 이전 방법과 동일한 단점이 있습니다.
변수에 도메인 이름 설정하기
이 방법은 첫 번째 방법의 변형이지만, NGINX가 도메인 이름을 다시 확인하는 빈도를 제어할 수 있습니다:
resolver 10.0.0.2 valid=10s;
server {
location / {
set $backend_servers backends.example.com;
proxy_pass http://$backend_servers:8080;
}
}변수를 사용하여 proxy_pass 지시문에 도메인 이름을 지정하면 NGINX는 해당 도메인 이름의 TTL이 만료될 때 이를 다시 확인합니다. 이름 서버를 명시적으로 지정하려면 resolver 지시문을 포함해야 합니다(NGINX는 앞의 두 방법과 달리 /etc/resolv.conf를 참조하지 않습니다). valid 매개변수를 resolver 지시문에 포함하면 NGINX가 TTL을 무시하고 지정된 주기로 이름을 다시 확인하도록 설정할 수 있습니다. 여기서는 NGINX가 10초마다 이름을 다시 확인하도록 설정합니다.
참고: TCP/UDP 부하 분산에서 proxy_pass 지시문에 변수를 사용하는 이 방법은 NGINX 1.11.3 이상 및 NGINX Plus R10 이상에서 지원됩니다.
이 방법은 첫 번째 방법의 두 가지 단점을 해결합니다. 즉, 도메인 이름을 확인할 수 없더라도 NGINX 시작 또는 재로드 작업이 실패하지 않으며, NGINX가 이름을 다시 확인하는 빈도를 제어할 수 있습니다. 하지만 업스트림 그룹을 사용하지 않으므로 server 지시문에 부하 분산 알고리즘이나 기타 매개변수를 지정할 수 없습니다(두 번째 방법에서는 지정했음).
NGINX Plus에서 DNS를 사용한 서비스 검색
이제 NGINX Plus에서만 사용할 수 있는 DNS 기반 서비스 디스커버리 방법 두 가지를 살펴보겠습니다.
NGINX Plus에서 A 레코드 사용
NGINX Plus를 사용하면 원하는 만큼 자주 DNS 이름을 다시 확인할 수 있으며, 앞서 설명한 세 가지 방법의 단점도 없습니다. 이 기능을 사용하려면 다음과 같이 해야 합니다:
- 이전 방법과 마찬가지로 네임 서버를 지정하려면
resolver지시어를 포함합니다. - 공유 메모리 영역을 할당하려면
zone지시어를upstream구성 블록에 포함합니다. - 도메인 이름을 사용하는
resolve지시어에server매개변수를 추가합니다.
다음 예시를 살펴보세요:
resolver 10.0.0.2 valid=10s;
upstream backends {
zone backends 64k;
server backends.example.com:8080 resolve;
}
server {
location / {
proxy_pass http://backends;
}
}기본적으로 NGINX Plus는 TTL을 준수하여 레코드가 만료되면 이름을 다시 확인합니다. NGINX Plus가 지정된 주기로 이름을 다시 확인하도록 하려면 valid 매개변수를 resolver 지시문에 포함하세요.
이 코드 조각에서 NGINX Plus는 10초마다 10.0.0.2의 네임 서버에 쿼리하여 backends.example.com을 확인합니다. 이름을 확인할 수 없더라도 NGINX Plus는 시작 시, 구성을 다시 로드할 때 또는 런타임 중에 실패하지 않습니다. 대신 클라이언트에는 표준 502 오류 페이지가 표시됩니다.
NGINX Plus에서 SRV 레코드 사용
NGINX Plus R9 이상에서는 DNS SRV 레코드를 지원합니다. 이를 통해 NGINX Plus는 네임 서버에서 IP 주소뿐만 아니라 포트 번호, 가중치 및 우선순위도 가져올 수 있습니다. 이는 서비스의 포트 번호가 동적으로 할당되는 경우가 많은 마이크로서비스 환경에서 매우 중요합니다.
편집자 주 – NGINX Plus R9의 모든 새로운 기능에 대한 개요는 블로그의 NGINX Plus R9 발표를 참조하세요.
SRV 레코드는 서비스 이름, 서비스와 통신하는 데 사용되는 프로토콜, 도메인 이름으로 구성된 세 요소로 정의됩니다. 네임 서버를 쿼리할 때는 이 세 가지를 모두 제공해야 합니다. 10.0.0.2 네임 서버에는 서비스 이름이 SRV인 레코드가 세 개 있으며, 이 레코드의 서비스 이름은 http, 프로토콜은 tcp, 도메인 이름은 backends.example.com입니다. 다음은 nslookup 유틸리티의 출력입니다.
$ nslookup -query=SRV _http._tcp.backends.example.com 10.0.0.2Server: 10.0.0.2
Address: 10.0.0.2#53
_http._tcp.backends.example.com service = 0 2 8090 backend-0.example.com.
_http._tcp.backends.example.com service = 0 1 8091 backend-1.example.com.
_http._tcp.backends.example.com service = 10 1 8092 backend-2.example.com.각 SRV 레코드의 호스트 이름을 조회하면 해당 IP 주소를 얻을 수 있습니다:
$ nslookup backend-0.example.com 10.0.0.2...
Name: backend-0.example.com
Address: 10.0.0.10
$ nslookup backend-1.example.com 10.0.0.2
...
Name: backend-1.example.com
Address: 10.0.0.11
$ nslookup backend-2.example.com 10.0.0.2
...
Name: backend-2.example.com
Address: 10.0.0.12첫 번째 SRV 레코드에서 반환된 정보를 좀 더 자세히 살펴보겠습니다. 이 레코드는 첫 번째 nslookup 명령으로 조회한 것입니다:
_http._tcp.backends.example.com service = 0 2 8090 backend-0.example.com._http._tcp.–SRV레코드의 이름과 프로토콜입니다. 이 값을 NGINX Plus 구성 파일의service매개변수 값으로server지시문에 지정합니다(아래 참조).0– 우선순위입니다. 값이 낮을수록 우선순위가 높습니다. NGINX Plus는 우선순위가 가장 높은 서버를 기본 서버로 지정하고, 나머지 서버를 백업 서버로 지정합니다. 이 레코드는 모든 레코드 중 값이 가장 낮아(우선순위가 가장 높아) NGINX Plus가 해당 백엔드를 기본 서버로 지정합니다.2– 가중치입니다. NGINX Plus는 백엔드를 업스트림 그룹에 추가할 때 백엔드의 가중치를 이 값으로 설정합니다(weight매개변수를server지시문에 지정하는 것과 동일).8090– 포트 번호입니다. NGINX Plus는 백엔드를 업스트림 그룹에 추가할 때 백엔드의 포트를 이 값으로 설정합니다.backend‑0.example.com– 백엔드 서버의 호스트 이름입니다. NGINX Plus는 이 이름을 확인하여 해당 백엔드를 업스트림 그룹에 추가합니다. 이름이 여러 레코드로 확인되면 NGINX Plus는 여러 서버를 추가합니다.
이제 NGINX Plus에서 SRV 레코드를 사용하도록 구성하는 방법을 살펴보겠습니다. 다음은 샘플 구성 파일입니다:
resolver 10.0.0.2 valid=10s;
upstream backends {
zone backends 64k;
server backends.example.com service=_http._tcp resolve;
}
server {
location / {
proxy_pass http://backends;
}
}Using the server 지시문의 service 매개변수를 사용하여 확인하려는 SRV 레코드의 이름과 프로토콜을 지정합니다. 여기서는 각각 _http와 _tcp입니다. service 매개변수를 사용하고 포트를 지정하지 않는다는 점을 제외하면 이전 섹션의 구성 예제와 동일합니다.
이 섹션의 첫 번째 nslookup 명령에서 반환된 값을 기반으로 NGINX Plus에 다음과 같은 세 개의 백엔드 서버가 구성됩니다:
- 10.0.0.10 – 포트 8090과 가중치 2가 설정된 기본 서버.
- 10.0.0.11 – 포트 8091, 가중치 1의 기본 서버.
- 10.0.0.12 – 포트 8092와 가중치 1을 사용하는 백업 서버.
NGINX Plus에 실시간 활동 모니터링을 구성하면 기본 제공 대시보드에서 해당 백엔드를 확인할 수 있습니다:

지정된 가중치에 따라 요청이 어떻게 분산되는지 확인해 보세요. 가중치가 1인 10.0.0.11:8091 서버는 요청의 3분의 1을 처리하고, 가중치가 2인 10.0.0.10:8090 서버는 요청의 3분의 2를 처리합니다. 백업 서버인 10.0.0.12:8092 서버는 다른 두 서버가 모두 중단되지 않는 한 요청을 받지 않습니다.
주의 사항
NGINX Plus에서 서비스 검색에 DNS를 사용할 때는 몇 가지 유의해야 할 사항이 있습니다:
- DNS 서버는 고가용성을 갖추거나 백업 서버를 두어야 합니다. DNS 서버를 사용할 수 없게 되면 NGINX Plus는 업데이트 수신을 중단합니다. 이 경우 해당 레코드의 TTL 값은 무시하고 기존 백엔드를 구성에 그대로 유지합니다(NGINX Plus를 다시 시작하거나 구성을 다시 로드하는 경우 제외).
- 여러 네임 서버를
resolver지시어로 지정할 수 있으므로, 그중 하나가 중단되면 NGINX Plus가 다른 서버를 시도합니다. - 소개에서 언급했듯이, NGINX Plus에서 서비스 검색에 DNS 대신 사용할 수 있는 방법으로는 NGINX Plus API가 있으며, 이를 통해 간단한 HTTP 요청으로 업스트림 그룹에 서버를 추가하거나 제거할 수 있습니다.
예시
전체 예제를 자세히 살펴보려면 NGINX 및 NGINX Plus를 DNS 기반 서비스 검색 플랫폼과 통합하는 방법을 다룬 다음 블로그 게시물을 확인하세요:
향후 새로운 통합 옵션에 관한 글을 추가할 때마다 이 목록을 업데이트하겠습니다.
결론
NGINX Plus에서 완벽하게 지원되는 DNS 기반 서비스 검색은 마이크로서비스 환경에서 로드 밸런서 구성을 간편하게 업데이트할 수 있는 방법을 제공합니다. 릴리스 9 이상에서 지원되는 SRV 레코드를 사용하면 NGINX Plus가 백엔드의 IP 주소뿐만 아니라 포트 번호까지 가져올 수 있어 더욱 강력해집니다.
NGINX Plus의 DNS 기반 서비스 검색과 기타 향상된 기능을 사용해 볼 준비가 되셨나요? 지금 30일 무료 체험을 시작하거나 사용 사례에 대해 논의하려면 문의해 주세요.
관련 블로그 게시물
시청하기: KubeCon North America 2023에서의 NGINX Gateway Fabric
이 영상에서는 KubeCon의 NGINX 부스를 찾아가, 저희가 공개한 Kubernetes Gateway API 구현을 살펴봅니다.
F5 NGINX로 대규모 WAF 플릿을 확인하고 관리하는 2가지 방법
앱 보안을 강화하는 두 가지 방법을 소개합니다. NGINX Management Suite를 통해 WAF 운영에 대한 가시성을 높이고, NGINX App Protect WAF를 활용해 코드형 보안을 구현하는 것입니다.
Ingress 컨트롤러 선택 가이드, 4부: NGINX Ingress Controller 옵션
개발 주체, 개발 철학, 프로덕션 환경 준비도, 보안 및 지원을 기준으로 어떤 NGINX Ingress 컨트롤러가 가장 적합한지 알아보세요.
진화하는 공격 환경에 NGINX App Protect Denial of Service가 적응하는 방법
NGINX App Protect Denial of Service(DoS)가 계층 7 DoS 공격을 방어하기 위해 완화 방법을 실시간으로 조정하는 방식을 설명합니다. 정상적인 사용자 행동과 서버 상태에 대한 모델을 생성하여 공격을 나타내는 이상 징후를 감지하고 맞춤형 완화 시그니처를 적용할 수 있습니다.
NGINX Instance Manager를 활용한 대규모 구성 업데이트 및 인증서 관리
NGINX Instance Manager 버전 1.0에는 두 가지 새로운 기능이 도입되었습니다. NGINX 인스턴스에 태그와 사용자 역할을 지정하면 전체 그룹에 구성을 한 번에 적용할 수 있습니다. 인증서 검사는 만료 예정인 인증서를 감지하여 서비스 중단을 방지할 수 있도록 인증서를 교체할 수 있게 해줍니다.
Netflix가 자사 CDN의 핵심으로 NGINX를 선택한 이유
Netflix가 글로벌 콘텐츠 전송 네트워크인 Open Connect의 스트리밍 미디어 기술로 NGINX를 선택한 이유를 NGINX 개발자 Gleb Smirnoff에게서 알아보세요.