F5 및 NGINX Plus JavaScript 모듈로 선언적 DNS 활성화
저희 설정에서는 API를 통해 전송된 단일 HTTP POST 메시지로 DNS 레코드를 업데이트할 수 있습니다. 이를 가능하게 하기 위해 NGINX Plus 와 NGINX JavaScript 모듈을 사용합니다.
1990년 영화 “The Hunt for Red October“에서 Sean Connery는 소련의 최신 핵잠수함의 함장 Marko Ramius 역을 연기하며 미국으로 망명하여 잠수함을 가져가려고 합니다. 젊은 Alec Baldwin이 연기한 CIA 분석가 Jack Ryan은 Ramius’s의 동기를 직감하고 강대국 간의 폭력적인 대결을 막기 위해 미 해군에게 자신의 이론을 설득해야 합니다. Ryan은 자신의 주장을 증명하기 위해 먼저 Ramius와 대화를 나누고, Ryan이 Ramius의 위치를 파악하는 데 지나치게 많은 시간을 소비하면서 긴장감이 고조됩니다.
겉으로 보기에 Ryan을 찾는 것은 인터넷에서 웹사이트를 찾으려는 브라우저 클라이언트의 검색과 비슷하지만, 웹사이트가 도메인 이름 시스템(DNS)에 위치를 등록하기 때문에 클라이언트가 쉽게 찾을 수 있다는 점이 다릅니다. 만약 Ramius가 자신의 위치를 공개했더라면 영화는 그다지 흥미롭지 않았겠지만, 빠르고 쉬운 해결은 우리가 애플리케이션에 원하는 바로 그것입니다.
이 포스트에서는 F5의 두 가지 DNS 기술을 사용합니다. BIG-IP DNS를 사용하면 내부 클라이언트에 private 주소(원래 RFC 1918에 정의된 대로)에 대한 DNS 레코드를 게시하여 데이터 센터에서 호스팅되는 서비스에 도달할 수 있는 최적화된 경로를 제공할 수 있습니다. DNS Load Balancer Cloud Service를 통해 외부 클라이언트를 위한 클라우드 기반 DNS 서비스를 제공합니다.

목차
1. 많은 이름, 하나의 IP 주소
2. F5 및 NGINX Plus 기술을 사용하는 방법
3. 애플리케이션 상태 정보 수집, 저장 및 업데이트
4. DNS 레코드 업데이트
4-1. BIG-IP DNS의 레코드 업데이트
4-2. DNS Load Balancer에서 레코드 업데이트
5. BIG-IP DNS GUI에서 애플리케이션 상태 추적
6. DNS Load Balancer GUI에서 애플리케이션 상태 추적
7. NGINX Plus 결론
1. 많은 이름, 하나의 IP 주소
이 예는 여러 데이터 센터에 걸쳐 서비스형 플랫폼(PaaS)을 배포할 때 흔히 발생하는 문제를 해결합니다. 각 위치에는 일반적으로 해당 위치의 DNS 레코드에 광고된 단일 IP 주소 뒤에 많은 서비스가 배포되어 있습니다. 와일드카드 DNS 항목의 문제점은 각 서비스의 위치와 정상 여부에 대한 세부적인 세부 정보를 일게 된다는 것입니다.
이 예에서는 모니터링 작업을 중복할 필요 없이 여러 위치에서 애플리케이션 상태를 추적하고 애플리케이션이 up/down 될 때 내부 및 외부 DNS 레코드를 모두 업데이트하기 위해 NGINX Plus Active Health Check를 사용합니다.
2. F5 및 NGINX Plus 기술을 사용하는 방법
이 예제에서는 F5와 NGINX소프트웨어를 모두 활용합니다:
- F5 BIG-IP DNS – 기존 로드 밸런싱 외에도 BIP-IP는 글로벌 서버 로드 밸런싱(GSLB)도 수행할 수 있습니다. 온프레미스에서는 하드웨어 또는 가상 디바이스로, 클라우드 환경에서는 가상 디바이스로 BIP-IP를 배포할 수 있습니다.
- F5 DNS Load Balancer Cloud Service – DNS Load Balancer는 내장된 DDoS 보호 기능과 API 우선 접근 방식을 통해 GSLB를 클라우드 호스팅 SaaS 서비스로 제공합니다.
BIG-IP DNS와 DNS Load Balancer 모두 DNS 레코드 업데이트를 위한 선언적 API를 제공합니다. 따라서 한 번의 POST API 호출로 업데이트를 수행할 수 있습니다. - NGINX Plus – 여러 NGINX Plus 기능을 사용하고 있습니다.
- 업스트림 서버(애플리케이션)의 상태를 모니터링하기 위한 Active Health Check.
- 애플리케이션 상태를 기록하는 Key-value 저장소를 업데이트하기 위한 NGINX Plus API.
- 여러 NGINX 인스턴스 간에 Key-value 저장소를 동기화하기 위한 NGINX Plus zone synchronization(memcache 또는 Redis와 같은 분산 데이터베이스와 유사.
- NGINX JavaScript 모듈 – NGINX JavaScript(njs)를 사용하면 내부 NGINX Plus API에 하위 요청을 하고, JSON 응답을 구문 분석하고, 내부 NGINX변수를 업데이트하고, Native가 아닌 함수를 NGINX Plus 트래픽 처리 시퀀스에 통합할 수 있습니다.
샘플 솔루션 작동 방식에 대해 자세히 알아보기 전에 각 기술이 함께 작동하는 방식에 대한 개요를 살펴보세요:
- 여러 데이터 센터에서 실행 중인 백엔드 애플리케이션의 Health Check를 확인하기 위해 NGINX Plus Active Health Check를 사용합니다.
- njs 함수를 사용하여 상태 정보를 집계하고 Key-value 저장소를 업데이트 합니다. NGINX Plus 영역 동기화가 활성화되어 있으므로 Key-value 저장소는 모든 NGINX Plus 인스턴스 간에 자동으로 동기화됩니다.
- DNS 레코드를 업데이트하기 위해 njs 함수를 호출하는 인증된 요청을 NGINX Plus에 보냅니다.
NGINX Plus를 구성하고 애플리케이션 상태 정보를 처리하는 방법에 대한 자세한 내용은 애플리케이션 상태 정보 수집, 저장 및 업데이트를 참조하세요. 정보를 DNS 서버에 배포하는 방법에 대한 자세한 내용은 DNS 레코드 업데이트를 참조하세요.
예제에 대한 전체 NGINX Plus 구성 및 NGINX JavaScript 코드는 GitHub 리포지토리에서 확인할 수 있습니다. (이 포스트에서는 NGINX Plus 구성의 모든 location 지시문이나 해당 NGINX JavaScript 함수에 대해 설명하지 않습니다.)
3. 애플리케이션 상태 정보 수집, 저장 및 업데이트
샘플 토폴로지에는 dc1과 dc2라는 두 개의 데이터 센터가 있지만 솔루션은 다양한 배포 유형(하이브리드 클라우드, 멀티 클라우드, 다중 사용성 영역, 다중 Kubernetes 클러스터 또는 단일 위치나 디바이스)으로 쉽게 일반화됩니다.
각 데이터 센터에서 NGINX Plus 인스턴스는 4개의 애플리케이션(app001~app004)의 사용자 지정 조합을 로드 밸런싱 합니다. 각 애플리케이션에 대한 업스트림 서버의 상태를 저장하기 위해 pools라는 Key-value 저장소를 구성합니다. dc1에 대한 NGINX Plus 구성 파일의 다음 keyval 지시문은 데이터 센터에 있는 애플리케이션의 상태 정보를 저장하는 $pool 변수에 NGINX Plus 인스턴스의 IP 주소인 10.1.20.54를 매핑합니다. (dc2용 구성에서는 NGINX Plus 인스턴스의 IP 주소가 10.1.20.55입니다.)
keyval_zone zone=pools:32k state=pools.keyval sync timeout=300;
keyval "10.1.20.54" $pool zone=pools;
pool 변수를 채우기 위해 UpdatePools njs 함수를 호출합니다. 이 함수는 NGINX Plus API를 사용하여 각 애플리케이션에 대한 업스트림 서버의 상태를 확인합니다. pseudocode에서 NGINX Plus API에 대한 하위 요청은 다음과 같습니다.
r.subrequest('/api/5/http/upstreams' ...
출력은 애플리케이션 이름과 정상으로 간주되는 애플리케이션에 대한 서버 수로 구성된 Key-value 쌍 세트를 생성하기 위해 처리됩니다. 다음은 각각 3개의 정상 서버가 있는 2개의 애플리케이션에 대한 샘플 출력입니다.
{"app001":3,"app002":3}
이 pseudocode를 사용하여 자바스크립트 JSON.stringify 함수를 호출하여 출력을 JSON으로 변환합니다:
r.variables.pool = JSON.stringify(output);
두 데이터 센터에서 pool Key-value 저장소의 내용을 동기화하기 위해 NGINX Plus Zone Synchronization 모듈을 사용합니다(샘플 구성 파일에는 표시되지 않음). 이 예는 두 데이터 센터에서 app001부터 app003까지 정상 서버의 수를 보여줍니다:
{
"10.1.20.54": "{\"app001\":3,\"app002\":3}",
"10.1.20.55": "{\"app001\":2,\"app003\":4}"
}
health_check 지시문을 사용하여 로컬 인스턴스의 Key-value 저장소에 있는 상태 정보를 업데이트하는 njs 함수를 30초마다 호출합니다.
location /poll {
internal;
proxy_pass http://127.0.0.1/pools/update;
health_check uri=/pools/update interval=30;
}
Summarize njs 함수는 데이터 센터가 아닌 애플리케이션별로 상태 정보를 그룹화하며, 출력을 표시하기 위해 /pools URI에 요청을 합니다. 다음 샘플 출력에서 app001은 두 데이터 센터 모두에서 정상이고, app002는 dc1에서만 실행 중이며, app003은 dc2에서만 실행 중이고, app004는 두 데이터 센터 모두에 배포되었지만 dc2에서만 정상입니다(dc1의 정상 서버 수는 0개입니다).
$ curl localhost:8245/pools
{"app001.f5demo.com":{"dc1":[{"10.1.20.54":3}],
"dc2":[{"10.1.20.55":2}]},
"app002.f5demo.com":{"dc1":[{"10.1.20.54":3}]},
"app003.f5demo.com":{"dc2":[{"10.1.20.55":4}]},
"app004.f5demo.com":{"dc1":[{"10.1.20.54":0}],
"dc2":[{"10.1.20.55":3}]}}
다음은 현재 애플리케이션 상태를 그래픽으로 나타낸 것입니다.

4. DNS 레코드 업데이트
백엔드 애플리케이션의 상태를 반영하기 위해 BIG-IP DNS와 DNS Load Balancer 모두에서 레코드를 업데이트하고, 데이터 센터 중 하나에서 앱을 사용할 수 없는 경우(예: 위 예제에서 dc1의 app004) 해당 앱의 클라이언트를 다른 데이터 센터로 리다이렉션합니다. BIG-IP DNS와 DNS Load Balancer는 서로 다른 템플릿과 데이터 표현을 사용하므로 두 시스템에서 DNS 레코드를 업데이트하기 위해 njs 하위 요청을 서로 다른 URL로 보내고 서로 다른 기능을 호출합니다.
4-1. BIG-IP DNS의 레코드 업데이트
BIG-IP 디바이스의 구성은 특정 스키마를 준수하는 F5 AS3(Application Services 3 Extension) 형식의 단일 JSON 문서로 표현할 수 있습니다. njs를 사용하여 배포하려는 서비스의 템플릿을 구축할 수 있습니다.
var template = {
"class": "ADC",
"schemaVersion": "3.7.0",
"id": "NGINXPLUS",
app001에 대한 이 예제에서와 같이 각 애플리케이션의 pool 멤버에 대한 정보(NGINX Plus upstream 그룹에 해당하는 BIG-IP)로 템플릿을 업데이트합니다:
"app001_domain": {
"class": "GSLB_Domain",
"domainName": "app001.f5demo.com",
"pools": [ { "use": "dc1_app001_pool" },
{ "use": "dc2_app001_pool"} ],
"resourceRecordType": "A"
},
NGINX Plus 구성에서는 BIG-IP DNS 서버에 대해 bigip이라는 upstream 그룹을 생성하고, NGINX Plus가 /mgmt/shared/appsvcs/declare 위치에서 bigip으로 요청을 배포하도록 합니다:
upstream bigip {
server 10.1.1.5:443;
}
location /mgmt/shared/appsvcs/declare {
internal;
proxy_pass https://bigip;
}
generateAS3Dns njs 함수에는 템플릿을 나타내는 문자열화된 JSON 페이로드가 포함된 POST 요청을 통해 애플리케이션에 대한 DNS 레코드로 BIG-IP DNS를 구성하는 하위 요청이 포함되어 있습니다. 다음은 하위 요청에 대한 pseudocode입니다.
r.subrequest('/mgmt/shared/appsvcs/declare',
{ method: 'POST', body: JSON.stringify(template) },
pools/push/dns에 요청하여 generateAS3Dns 함수를 호출합니다. 이 예제에서는 curl 명령의 -u 매개 변수를 포함시켜 BIG-IP DNS 서버에서 admin 사용자로 인증합니다. 하위 요청을 사용하고 있기 때문에 NGINX Plus는 BIG-IP DNS 서버에 연결할 때 자격 증명을 배포합니다. 또는 자격 증명을 njs 파일에 저장할 수도 있습니다.
$ curl localhost:8245/pools/push/dns -u admin:admin_password
4-2. DNS Load Balancer에서 레코드 업데이트
DNS Load Balancer에서 레코드를 업데이트하는 방법은 BIG-IP DNS 접근 방식과 유사하지만, DNS Load Balancer API가 예상하는 형식을 생성하는 템플릿이 다릅니다.
"load_balanced_records": {
"app001": {
...
"proximity_rules": [
{ ... "pool": "pools_dc1_app001" ...},
{ ... "pool": "pools_dc1_app001" ...},
],
...
NGINX Plus 구성에서 DNS Load Balancer API에 대해 cloud라는 upstream 그룹을 생성하고, NGINX Plus가 /v1/svc-subscription/subscriptions 위치에서 cloud에 요청을 배포하도록 합니다:
upstream cloud {
server api.cloudservices.f5.com:443;
}
#...
location /v1/svc-subscription/subscriptions {
internal;
proxy_pass https://cloud;
}
generateCloudDns njs 함수에는 템플릿을 나타내는 문자열화된 JSON 페이로드가 포함된 PUT 요청을 수행하여 애플리케이션에 대한 DNS 레코드로 DNS Load Balancer를 구성하는 하위 요청이 포함되어 있습니다. 다음은 하위 요청에 대한 pseudocode입니다(URL의 마지막 요소인 s-aabbcc1234는 DNS Load Balancer subscription ID 입니다).
r.subrequest(' /svc-subscription/subscriptions/s-aabbcc1234,
{ method: 'PUT', body: JSON.stringify(template) },
/pools/push/cloud-dns에 요청을 보내 generateCloudDns 함수를 호출합니다.
$ curl localhost:8245/pools/push/cloud_dns?account_id=... -H "Authorization: ..."
5. BIG-IP DNS GUI에서 애플리케이션 상태 추적
BIG-IP DNS 레코드를 생성하고 업데이트하기 위해 NGINX Plus 및 njs 하위 요청을 사용했지만, BIG-IP DNS GUI를 사용하여 애플리케이션의 상태를 확인할 수 있습니다. 이 스크린샷은 app004가 상태 열에서 각각 검은색 다이아몬드와 녹색 원으로 표시된 dc1에서는 비정상이고 dc2에서는 정상임을 보여줍니다. 그 결과, BIG-IP DNS는 app004의 위치 요청에 대한 응답에 dc2의 주소만 포함합니다.

이 스크린샷은 BIG-IP DNS의 레코드가 private(10/8) 주소 공간에 위치하는 방법을 보여줍니다.

6. DNS Load Balancer GUI에서 애플리케이션 상태 추적 (NGINX Plus)
BIG-IP DNS와 마찬가지로 DNS 레코드를 생성하고 업데이트하기 위해 NGINX Plus 및 njs 하위 요청을 사용했지만, DNS Load Balancer GUI를 사용하여 애플리케이션의 상태를 확인할 수 있습니다. 이 스크린샷은 app004가 dc1에서는 비정상이고 dc2에서는 정상임을 보여줍니다(상태 열에서 각각 Disable 및 Enabled로 표시됨).

다음 스크린샷은 DNS Load Balancer 레코드가 BIG-IP DNS의 레코드와 달리 Public IP 주소에 대해 어떻게 사용되는지 보여줍니다(처음 4개의 레코드만 표시됨).

7. NGINX Plus 결론
검토를 위해 NGINX Plus를 사용하여 다음을 수행했습니다.
- 업스트림 애플리케이션의 Active Health Check 수행
- Key-value 저장소에 상태 정보 저장
- 여러 NGINX 인스턴스에서 Key-value 저장소 동기화
njs를 활용하여 다음을 수행했습니다.
- 각 DNS 기술에서 요구하는 형식으로 업스트림 애플리케이션의 상태를 요약합니다.
- DNS 서비스 템플릿화
- DNS 서비스를 적절한 API 엔드포인트로 push
그 결과는 “The Hunt for Red October”의 결말만큼 장대하지는 않지만, 웹사이트를 운영하는 사람에게는 훨씬 더 가치가 있습니다.
설정을 직접 체험해보고 싶으신가요? NGINX Plus 무료 체험판과 BIG-IP DNS 또는 DNS Load Balancer의 무료 체험판을 시작하거나 NGINX STORE에 문의하여 사용 사례에 대해 논의하세요.
댓글을 달려면 로그인해야 합니다.