NGINX Plus, 동적 A/B 쿠버네티스 멀티 클러스터 로드 밸런싱

유지 관리 기간은 팀을 수렁으로 몰아넣고 애플리케이션 제공을 지연시키며 트래픽을 관리할 더 나은 방법이 있을 거야!”라고 선언하게 만들 수 있습니다. 이제 다시 쿠버네티스 환경의 빠른 속도로 돌아갈 수 있는 NGINX Plus 솔루션을 살펴보겠습니다.

오픈 소스(또는 일부 상용) 도구 라이브러리를 사용하여 개발팀을 위한 새로운 앱과 컨테이너를 테스트, 배포 및 관리합니다. 개발, 테스트, 스테이징 및 프로덕션 환경에서 이러한 컨테이너와 파드를 실행하기 위해 쿠버네티스를 선택합니다. 마이크로서비스의 아키텍처와 개념을 이해했고, 대부분의 경우 꽤 잘 작동합니다. 하지만 이 과정에서 몇 가지 과속 방지턱에 부딪히기도 합니다.

예를 들어, 새로운 클러스터, 서비스 및 애플리케이션을 구축하고 배포할 때 트래픽 감소 없이 이러한 새로운 리소스를 프로덕션에 쉽게 통합하거나 마이그레이션하려면 어떻게 해야 할까요? 기존 네트워킹 어플라이언스는 DNS 레코드, 로드 밸런서, 방화벽, 프록시에 대한 구성 변경을 구현할 때 reload 하거나 재부팅해야 합니다. DNS, 로드 밸런서, 방화벽 규칙을 업데이트하려면 “서비스 중단” 또는 “유지 관리 기간”이 필요하기 때문에 이러한 조정은 다운타임 없이 재구성할 수 없습니다. 대부분의 경우 끔찍한 서비스 티켓을 제출하고 다른 팀이 승인하고 변경할 때까지 기다려야 합니다.

목차

1. Active-Active 멀티 클러스터 로드 밸런싱
2. NGINX Plus Key-Value Store
2-1. NGINX Plus Key-Value 사용 사례
2-2. 구성 예시
3. 동적 HTTP 업스트림: 쿠버네티스용 NGINX Loadbalancer
3-1. 아키텍처 및 흐름
3-2. 쿠버네티스용 NGINX Loadbalancer 스냅샷
3-3. NGINX Plus 보안 기능 추가
4. 오늘부터 시작하세요.

1. Active-Active 멀티 클러스터 로드 밸런싱

여러 개의 쿠버네티스 클러스터가 있는 경우, 두 클러스터로 동시에 트래픽을 라우팅하는 것이 이상적입니다. 더 좋은 옵션은 A/B, Canary 또는 Blue-Green 트래픽 분할을 수행하고 테스트용으로 트래픽의 작은 비율을 보내는 것입니다. 이를 위해 ngx_http_split_clients_module과 함께 NGINX Plus를 사용할 수 있습니다.

K8s with NGINX Plus diagram

HTTP Split Clients 모듈은 NGINX 오픈 소스에서 작성되었으며, key를 기반으로 요청의 비율을 분산할 수 있습니다. 이 사용 사례에서 클러스터는 NGINX의 “upstream”입니다. 따라서 클라이언트 요청이 도착하면 트래픽이 두 개의 클러스터로 분할합니다. 클라이언트 요청을 결정하는 데 사용되는 키는 사용 가능한 모든 NGINX 클라이언트 $변수 입니다. 즉, 모든 요청에 대해 이를 제어하려면 NGINX에서 모든 수신 요청에 할당하는 고유 번호인 $request_id 변수를 사용합니다.

분할 비율을 구성하려면 각 클러스터로 이동할 비율을 결정합니다. 이 예에서는 K8s의 클러스터1을 프로덕션용 “대규모 클러스터”로, 클러스터2를 사전 프로덕션 테스트용 “소규모 클러스터”로 사용합니다. 스테이징을 위해 작은 클러스터를 사용하는 경우, 90:10의 비율을 사용하고 작은 클러스터에서 트래픽의 10%를 테스트하여 큰 클러스터에 새로운 변경 사항을 적용하기 전에 모든 것이 작동하는지 확인할 수 있습니다. 너무 위험하다고 생각되면 비율을 95:5로 변경할 수 있습니다. 사실, 0에서 100%까지 원하는 비율을 선택할 수 있습니다.

대부분의 실시간 프로덕션 트래픽의 경우, 두 클러스터의 크기가 같은 50:50 비율을 원할 것입니다. 하지만 클러스터 크기나 기타 세부 사항에 따라 다른 비율을 쉽게 제공할 수 있습니다. 비율을 0:100(또는 100:0)으로 쉽게 설정하고 다운타임 없이 전체 클러스터를 업그레이드, 패치, 복구 또는 교체할 수도 있습니다. 다른 클러스터에서 문제를 해결하는 동안 NGINX split_clients가 요청을 라이브 클러스터로 라우팅하도록 하세요.

# Nginx Multi Cluster Load Balancing
# HTTP Split Clients Configuration for Cluster1:Cluster2 ratios
# Provide 100, 99, 50, 1, 0% ratios (add/change as needed)
# Based on
# https://www.nginx.com/blog/dynamic-a-b-testing-with-nginx-plus/
# Chris Akker – Jan 2024
#

split_clients $request_id $split100 {
* cluster1-cafe; # All traffic to cluster1
}

split_clients $request_id $split99 {
99% cluster1-cafe; # 99% cluster1, 1% cluster2
* cluster2-cafe;
}

split_clients $request_id $split50 {
50% cluster1-cafe; # 50% cluster1, 50% cluster2
* cluster2-cafe;
}

split_clients $request_id $split1 {
1.0% cluster1-cafe; # 1% to cluster1, 99% to cluster2
* cluster2-cafe;
}

split_clients $request_id $split0 {
* cluster2-cafe; # All traffic to cluster2
}

# Choose which cluster upstream based on the ratio

map $split_level $upstream {
100 $split100;
99 $split99;
50 $split50;
1.0 $split1;
0 $split0;
default $split50;
}

위의 구성을 추가하거나 편집하여 필요한 비율(예: 90:10, 80:20, 60:40 등)에 맞출 수 있습니다.

참고: NGINX에는 stream 컨텍스트에서 TCP 연결을 위한 Split Clients 모듈도 있으며, 이는 non-HTTP 트래픽에 사용할 수 있습니다.

이 모듈은 HTTP 요청 대신 새로운 TCP 연결을 기반으로 트래픽을 분할합니다.

2. NGINX Plus Key-Value Store

다음으로 사용할 수 있는 기능은 NGINX Plus Key-Value Store입니다. 이것은 다양한 데이터 스토리지 사용 사례에 사용할 수 있는 NGINX 공유 메모리 영역의 key-value 객체입니다. 여기서는 위 섹션에서 언급한 분할 비율 값을 저장하는 데 사용합니다. NGINX Plus를 사용하면 NGINX를 reload하지 않고도 Key-Value 레코드를 변경할 수 있습니다. 이를 통해 API 호출로 이 분할 값을 변경하여 동적 분할 함수를 만들 수 있습니다.

이 예제에서는 다음과 같이 보입니다:

{“cafe.example.com”:90}

This KeyVal record reads:
The Key is the “cafe.example.com” hostname
The Value is “90” for the split ratio

NGINX 구성 파일에 분할 비율을 하드코딩하는 대신 Key-Value 메모리를 사용할 수 있습니다. 이렇게 하면 NGINX에서 정적 분할 값을 변경하는 데 필요한 NGINX reload가 필요하지 않습니다.

이 예제에서는 분할 비율을 90:10으로 설정하여 90%를 큰 클러스터1이, 나머지 10%를 작은 클러스터2가 사용하도록 구성했습니다. 이것은 Key-Value 레코드이므로 구성을 reload하지 않고도 NGINX Plus API를 사용하여 이 비율을 동적으로 변경할 수 있습니다! 분할 클라이언트 모듈은 이 비율 값을 변경하는 즉시 다음 요청 시 이 새 비율 값을 사용합니다.

50/50 비율로 시작하여 KB 레코드를 생성합니다:

NGINX Plus에 API 명령을 전송하여 Key-Value 저장소에 새 레코드를 추가합니다.

curl -iX POST -d '{"cafe.example.com":50}' http://nginxlb:9000/api/8/http/keyvals/split

Change the KV Record, change to the 90/10 ratio:

KeyVal 분할 비율을 90으로 변경하고 HTTP PATCH 메서드를 사용하여 메모리에 있는 KeyVal 레코드를 업데이트합니다:

curl -iX PATCH -d '{"cafe.example.com":90}' http://nginxlb:9000/api/8/http/keyvals/split

다음으로, 사전 프로덕션 테스트팀이 새 애플리케이션 코드가 준비되었는지 확인하고, 이를 대규모 클러스터1에 배포하고, 비율을 100%로 변경합니다. 그러면 모든 트래픽이 즉시 클러스터1로 전송되고 트래픽 중단, 서비스 중단, 유지 관리 기간, 재부팅, reload 또는 많은 티켓 없이 새 애플리케이션이 “라이브” 상태가 됩니다. 원하는 시점에서 API 호출 한 번으로 분할 비율을 변경할 수 있습니다

물론 90%에서 100%로 쉽게 이동할 수 있다는 것은 100:0에서 50:50(또는 0:100)으로 비용을 쉽게 변경할 수 있다는 뜻이기도 합니다. 따라서 hot backup 클러스터를 보유하거나 새로운 리소스로 클러스터를 수평적으로 확장할 수 있습니다. 최대로 활용하면 최신 소프트웨어, 하드웨어, 소프트웨어 패치로 새 클러스터를 완전히 구축하여 단 한 번의 연결 끊김 없이 애플리케이션을 배포하고 일정 기간 동안 트래픽을 마이그레이션할 수도 있습니다!

2-1. NGINX Plus Key-Value 사용 사례

동적 Key-Value Store와 함께 HTTP Split Clients 모듈을 사용하면 다음과 같은 사용 사례를 제공할 수 있습니다.

  • Active-Active 로드 밸런싱 – 여러 클러스터에 대한 로드 밸런싱
  • Active-Passive 로드 밸런싱 – 기본, 백업, DR 클러스터 및 애플리케이션에 대한 로드 밸런싱용
  • A/B, Blue-Green, 카나리 테스트 – 새로운 쿠버네티스 애플리케이션과 함께 사용됩니다.
  • 수평적 클러스터 확장 – 더 많은 클러스터 리소스를 추가하고 준비가 되면 비율을 변경합니다.
  • 무중단 클러스터 업그레이드 – 다른 클러스터를 업그레이드, 패치 또는 복구하는 동안 한 클러스터를 사용할 수 있는 기능
  • 즉시 장애 조치 – 한 클러스터에 심각한 문제가 있는 경우 다른 클러스터를 사용하도록 비율을 변경할 수 있습니다.

2-2. 구성 예시

다음은 Key-Value의 예시입니다.

# Define Key Value store, backup state file, timeout, and enable sync

keyval_zone zone=split:1m state=/var/lib/nginx/state/split.keyval timeout=365d sync;

keyval $host $split_level zone=split;

다음은 cafe.example.com 애플리케이션 구성의 예입니다.

# Define server and location blocks for cafe.example.com, with TLS

server {
listen 443 ssl;
server_name cafe.example.com;

status_zone https://cafe.example.com;

ssl_certificate /etc/ssl/nginx/cafe.example.com.crt;
ssl_certificate_key /etc/ssl/nginx/cafe.example.com.key;

location / {
status_zone /;

proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header "Connection" "";
proxy_pass https://$upstream; # traffic split to upstream blocks

}

# Define 2 upstream blocks – one for each cluster
# Servers managed dynamically by NLK, state file backup

# Cluster1 upstreams

upstream cluster1-cafe {
zone cluster1-cafe 256k;
least_time last_byte;
keepalive 16;
#servers managed by NLK Controller
state /var/lib/nginx/state/cluster1-cafe.state;
}

# Cluster2 upstreams

upstream cluster2-cafe {
zone cluster2-cafe 256k;
least_time last_byte;
keepalive 16;
#servers managed by NLK Controller
state /var/lib/nginx/state/cluster2-cafe.state;
}

업스트림 서버 IP:port는 NGINX Plus API를 사용하여 NGINX Plus를 동적으로 구성하는 새로운 컨트롤러인 쿠버네티스용 NGINX Loadbalancer에서 관리합니다. 자세한 내용은 다음 섹션에 나와 있습니다.

인기 있는 모니터링 및 시각화 도구인 Grafana를 사용하여 시간 경과에 따른 HTTP 분할 트래픽을 살펴보겠습니다. NGINX Prometheus Exporter(njs 기반)를 사용하여 모든 NGINX Plus 메트릭을 내보낸 다음 Grafana에서 수집하고 그래프로 표시합니다. Prometheus 및 Grafana 구성에 대한 자세한 내용은 여기에서 확인할 수 있습니다.

그래프에는 4개의 업스트림 서버가 있습니다: 클러스터1용 2개와 클러스터2용 2개입니다. HTTP 로드 생성 도구를 사용하여 HTTP 요청을 생성하고 이를 NGINX Plus로 전송합니다.

아래 세 개의 그래프에서 그래프의 시작 부분에서 분할 비율이 50:50인 것을 볼 수 있습니다.

LB Upstream Requests diagram

그런 다음 12:50:30에 비율이 10:90으로 변경됩니다.

LB Upstream Requests diagram

그런 다음 13:00:00에 90:10으로 변경됩니다.

LB Upstream Requests diagram

Prometheus 및 Grafana의 작동 구성은 쿠버네티스용 NGINX LoadBalancer GitHub 리포지토리에서 찾을 수 있습니다.

3. 동적 HTTP 업스트림: 쿠버네티스용 NGINX Loadbalancer

정적 NGINX 업스트림 구성을 정적 클러스터 업스트림으로 변경하려면 NGINX Plus API와 쿠버네티스용 NGINX Loadbalancer 컨트롤러를 사용하세요. 이 무료 프로젝트는 NGINX Ingress Controller를 감시하고 TCP/HTTP 로드 밸런싱을 위해 구성된 외부 NGINX Plus 인스턴스를 자동으로 업데이트하는 Kubernetes Controller입니다. 설계가 매우 간단하고 설치 및 운영이 간단합니다. 이 솔루션을 사용하면 쿠버네티스 환경에서 TCP/HTTP 로드 밸런싱을 구현하여 새로운 앱과 서비스를 즉시 감지하고 트래픽에 사용할 수 있도록 보장할 수 있으며, reload할 필요가 없습니다.

3-1. 아키텍처 및 흐름

쿠버네티스용 NGINX Loadbalancer는 쿠버네티스 클러스터 내부에 위치합니다. 쿠버네티스에 등록되어 NGINX Ingress Controller(nginx-ingress) 서비스를 감시합니다. Ingress Controller에 변경이 있을 때, 쿠버네티스용 NGINX Loadbalancer는 작업자 Ips와 NodePort TCP 포트 번호를 수집한 다음, NGINX Plus API를 통해 IP:ports를 NGINX Plus로 전송합니다.

Reload할 필요 없이 NGINX 업스트림 서버가 업데이트되고, NGINX Plus는 올바른 업스트림 서버와 쿠버네티스 NodePort로 트래픽을 로드 밸런싱합니다. 고가용성을 달성하기 위해 NGINX Plus 인스턴스를 추가로 추가할 수 있습니다.

Diagram of NGINX Loadbalancer in action

3-2. 쿠버네티스용 NGINX Loadbalancer 스냅샷

아래 스크린샷에는 배포되어 작업을 수행하는 쿠버네티스용 NGINX Loadbalancer를 보여주는 두 개의 창이 있습니다.

  1. Service Type – nginx-ingress용 로드 밸런서
  2. External IP – NGINX Plus 서버에 연결합니다.
  3. Ports – NodePort가 443:30158에 매핑되어 일치하는 NGINX upstream 서버에 연결됩니다(NGINX Plus 실시간 대시보드에 표시됨).
  4. Logs – 쿠버네티스용 NGINX Loadbalancer가 NGINX Plus로 데이터를 성공적으로 전송하고 있음을 나타냅니다.
NGINX Plus window

참고: 이 예제에서, 쿠버네티스 워커 노드는 10.1.1.8 및 10.1.1.10입니다.

3-3. NGINX Plus 보안 기능 추가

점점 더 많은 애플리케이션이 개방형 인터넷에 노출되면서 보안이 필요해지고 있습니다. 다행히도 NGINX Plus에는 계층화된 심층 방어 아키텍처를 만드는 데 사용할 수 있는 엔터프라이즈급 보안 기능이 있습니다.

클러스터 앞에 NGINX Plus를 배치하고 split_clients 기능을 수행하면서 이 기능을 활용하여 몇 가지 유용한 보안 기능을 추가하는 것은 어떨까요? 다음은 보안을 강화하는 데 사용할 수 있는 몇 가지 NGINX Plus 기능과 이를 구성, 테스트 및 배포하는 데 사용할 수 있는 다른 문서에 대한 링크 및 참조입니다.

  • IP block/allow lists – Source IP 주소를 기준으로 액세스를 제어합니다. NGINX 문서의 IP 주소 동적 거부 목록 페이지에서 Plus API를 사용하여 동적 IP block/allow 목록에 NGINX Plus Key-Value store를 사용하는 방법에 대한 구성 가이드를 찾을 수 있습니다.
  • Rate limiting – 애플리케이션, API 엔드포인트 및 미디어 다운로드에 대한 TCP 연결 수, HTTP 요청 및 대역폭 사용량을 제어합니다. NGINX를 사용한 속도 제한에 대한 자세한 내용은 NGINX 문서에서 프록시된 HTTP 리소스에 대한 액세스 제한과 블로그 게시물 NGINX와 NGINX Plus를 사용한 속도 제한NGINX Plus Key-Value store를 사용한 동적 대역폭 제한을 참조하세요.
  • GeopIP2 dynamic module – Source IP 주소를 기반으로 위치 메타데이터를 수집합니다. 이에 대한 자세한 내용은 NGINX 문서의 지리적 위치별 액세스 제한 페이지에서 확인하세요.
  • JWT 및 OIDC(OpenID Connect) module – 업계 표준 프로토콜로 사용자 액세스를 제어합니다. 이에 대한 자세한 내용은 NGINX 문서의 JWT 인증 설정 페이지에서 확인할 수 있습니다.
  • NGINX App Protect – 기존 및 진화하는 위협으로부터 보호하는 가볍고 지연 시간이 짧은 웹 애플리케이션 방화벽입니다.

4. 오늘부터 시작하세요.

쿠버네티스 클러스터의 엣지에서 네트워킹 문제로 인해 불편을 겪고 있다면 NGINX 멀티 클러스터 솔루션을 사용해 보세요.

NGINX Plus를 직접 사용해 보시려면 30일 무료 평가판을 신청하거나 NGINX STORE에 연락하여 논의하십시오.

NGINX에 대한 최신 정보들을 빠르게 전달받고 싶으시다면, 아래의 뉴스레터를 구독하세요.

NGINX STORE를 통한 솔루션 도입 및 기술지원 무료 상담 신청

* indicates required