블로그 | NGINX

NGINX Plus를 통한 동적 A/B Kubernetes 다중 클러스터 로드 밸런싱 및 보안 제어

NGINX-F5-수평-검정-유형-RGB의 일부
크리스 아커 썸네일
크리스 아커
2024년 2월 15일 게시

당신은 현대적 플랫폼 운영 또는 DevOps 엔지니어입니다. 오픈 소스(그리고 일부 상업용) 도구 라이브러리를 사용하여 개발팀을 위해 새로운 앱과 컨테이너를 테스트, 배포하고 관리합니다. 개발, 테스트, 스테이징 및 프로덕션 환경에서 이러한 컨테이너와 포드를 실행하기 위해 Kubernetes를 선택했습니다. 여러분은 마이크로서비스의 아키텍처와 개념을 이해했고, 대체로 잘 작동합니다. 하지만 여러분은 이 여정에서 몇 가지 난관에 부딪혔을 것입니다.

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

유지 관리 기간으로 인해 팀이 난관에 부딪히고 애플리케이션 제공이 중단되고 "트래픽을 관리하는 더 나은 방법이 있어야 한다!"고 선언하게 될 수 있습니다. 그렇다면 빠른 속도로 다시 돌아올 수 있는 솔루션을 살펴보겠습니다.

액티브-액티브 멀티 클러스터 로드 밸런싱

Kubernetes 클러스터가 여러 개 있는 경우 두 클러스터에 동시에 트래픽을 라우팅하는 것이 가장 좋습니다. 훨씬 더 나은 옵션은 A/B, 카나리아 또는 블루-그린 트래픽 분할을 수행하고 트래픽의 작은 비율을 테스트로 보내는 것입니다. 이를 위해 NGINX Plus와 ngx_http_split_clients_module을 사용할 수 있습니다.

NGINX Plus 다이어그램이 있는 K8s

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

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

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

# Nginx 멀티 클러스터 로드 밸런싱
# Cluster1:Cluster2 비율에 대한 HTTP 분할 클라이언트 구성
# 100, 99, 50, 1, 0% 비율 제공(필요에 따라 추가/변경)
# 기반
# https://www.nginx.com/blog/dynamic-a-b-testing-with-nginx-plus/
# Chris Akker – 2024년 1월
#

split_clients $request_id $split100 {
* cluster1-cafe; # cluster1로 가는 모든 트래픽
} 

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

split_clients $request_id $split50 { 
50% cluster1-cafe; # 50% 클러스터1, 50% 클러스터2
* 클러스터2-카페;
}

split_clients $request_id $split1 { 
1.0% 클러스터1-카페; # 1% 클러스터1, 99% 클러스터2
* 클러스터2-카페;
}

split_clients $request_id $split0 { 
* 클러스터2-카페; # 모든 트래픽 클러스터2
}

# 비율에 따라 업스트림 클러스터 선택

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

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

메모: NGINX에는 HTTP가 아닌 트래픽에 사용할 수 있는 스트림 컨텍스트의 TCP 연결을 위한 분할 클라이언트 모듈 도 있습니다. 이렇게 하면 HTTP 요청 대신 새로운 TCP 연결을 기준으로 트래픽이 분할됩니다.

NGINX Plus 키-값 저장소

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

우리의 예를 기준으로 보면 다음과 같습니다.

{“카페.예제.com”:90}

이 KeyVal 레코드는 다음과 같습니다.
키는 "cafe.example.com" 호스트 이름입니다.
분할 비율의 값은 "90"입니다.

NGINX 설정 파일에 분할 비율을 하드코딩하는 대신 키-값 메모리를 사용할 수 있습니다. 이렇게 하면 NGINX에서 정적 분할 값을 변경하는 데 필요한 NGINX 다시 로드가 제거됩니다.

이 예에서 NGINX는 큰 Cluster1 에서 90%를, 작은 Cluster2 에서 나머지 10%를 분할 비율로 90:10을 사용하도록 구성되어 있습니다. 이는 키-값 레코드이므로 구성을 다시 로드하지 않고도 NGINX Plus API를 사용하여 이 비율을 동적으로 변경할 수 있습니다! 분할 클라이언트 모듈은 사용자가 비율 값을 변경하자마자 바로 다음 요청에서 이 새로운 비율 값을 사용합니다.

KV 레코드를 생성하려면 50/50 비율로 시작하세요.

NGINX Plus에 API 명령을 보내어 KeyValue 저장소에 새 레코드를 추가합니다.

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

KV 레코드를 변경하고 90/10 비율로 변경합니다.

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

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

다음으로, 사전 프로덕션 테스트 팀은 새로운 애플리케이션 코드가 준비되었는지 확인하고, 이를 대규모 Cluster1 에 배포하고 비율을 100%로 변경합니다. 이렇게 하면 모든 트래픽이 Cluster1 로 즉시 전송되고 새 애플리케이션은 트래픽 중단, 서비스 중단, 유지 관리 기간, 재부팅, 다시 로드 또는 많은 티켓 없이 "라이브" 상태로 전환됩니다. 선택한 시점에 이 분할 비율을 변경하려면 API 호출 한 번만 필요합니다.

물론, 90%에서 100%로 쉽게 바꿀 수 있다는 것은 비율을 100:0에서 50:50(심지어 0:100)으로 쉽게 바꿀 수 있다는 것을 의미합니다. 즉, 핫 백업 클러스터를 보유하거나 새로운 리소스를 사용하여 클러스터를 수평적으로 확장할 수 있습니다. 전속력으로 최신 소프트웨어, 하드웨어 및 소프트웨어 패치를 사용하여 완전히 새로운 클러스터를 구축하여 단 하나의 연결도 끊기지 않고 일정 기간에 걸쳐 애플리케이션을 배포하고 트래픽을 마이그레이션할 수도 있습니다!

사용 사례

동적 키-값 저장소 와 함께 HTTP 분할 클라이언트 모듈을 사용하면 다음과 같은 사용 사례를 제공할 수 있습니다.

  • 액티브-액티브 로드 밸런싱 – 여러 클러스터에 대한 로드 밸런싱을 위해.
  • 액티브-패시브 로드 밸런싱 – 기본, 백업, DR 클러스터 및 애플리케이션에 대한 로드 밸런싱을 위해 사용됩니다.
  • A/B, 블루-그린 및 카나리아 테스트 – 새로운 Kubernetes 애플리케이션과 함께 사용됩니다.
  • 수평적 클러스터 확장 – 준비가 되면 더 많은 클러스터 리소스를 추가하고 비율을 변경합니다.
  • 히트리스 클러스터 업그레이드 – 한 클러스터를 사용하는 동안 다른 클러스터를 업그레이드, 패치 또는 수리할 수 있는 기능입니다.
  • 즉각적인 장애 조치 - 한 클러스터에 심각한 문제가 있는 경우 비율을 변경하여 다른 클러스터를 사용할 수 있습니다.

구성 예제

키-값 구성의 예는 다음과 같습니다.

# 키 값 저장소, 백업 상태 파일, 시간 초과 및 동기화 활성화를 정의합니다.
keyval_zone zone=split:1m state=/var/lib/nginx/state/split.keyval timeout=365d sync;

keyval $host $split_level zone=split;

그리고 이것은 cafe.example.com 애플리케이션 구성의 예입니다:

# TLS를 사용하여 cafe.example.com에 대한 서버 및 위치 블록 정의 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; # 트래픽을 업스트림 블록으로 분할 } # 클러스터당 하나씩 2개의 업스트림 블록 정의 # 서버는 NLK에서 동적으로 관리, 상태 파일 백업 # Cluster1 업스트림 업스트림 cluster1-cafe { zone cluster1-cafe 256k; least_time last_byte; keepalive 16; # NLK Controller에서 관리하는 서버 상태 /var/lib/nginx/state/cluster1-cafe.state; } # Cluster2 업스트림 업스트림 cluster2-cafe { zone cluster2-cafe 256k; least_time last_byte; keepalive 16; # NLK Controller에서 관리하는 서버 상태 /var/lib/nginx/state/cluster2-cafe.state; }

업스트림 서버 IP:포트는 Kubernetes용 NGINX Loadbalancer 에서 관리합니다. 이는 NGINX Plus API를 사용하여 NGINX Plus를 동적으로 구성하는 새로운 컨트롤러입니다. 자세한 내용은 다음 섹션을 참조하세요.

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

그래프에는 4개의 업스트림 서버가 있습니다. Cluster1 에 2개, Cluster2 에 2개. HTTP 로드 생성 도구를 사용하여 HTTP 요청을 만들고 이를 NGINX Plus로 전송합니다.

아래 세 개의 그래프에서 그래프 시작부분의 분할 비율은 50:50임을 알 수 있습니다.

LB 업스트림 요청 다이어그램

그러면 12:56:30에서는 비율이 10:90으로 바뀐다.

LB 업스트림 요청 다이어그램

그러면 13:00:00에 90:10으로 변경됩니다.

LB 업스트림 요청 다이어그램

Prometheus와 Grafana의 작동 구성은 Kubernetes용 NGINX Loadbalancer GitHub 저장소 에서 찾을 수 있습니다.

동적 HTTP 업스트림: 쿠버네티스를 위한 NGINX 로드밸런서

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

건축과 흐름

Kubernetes용 NGINX 로드밸런서는 Kubernetes 클러스터 내부에 있습니다. NGINX Ingress Controller( nginx-ingress ) 서비스를 감시하기 위해 Kubernetes에 등록되어 있습니다. Ingress 컨트롤러가 변경되면 Kubernetes용 NGINX Loadbalancer는 Worker IP와 NodePort TCP 포트 번호를 수집한 다음 NGINX Plus API를 통해 IP:포트를 NGINX Plus로 전송합니다.

NGINX 업스트림 서버는 다시 로드할 필요 없이 업데이트되고, NGINX Plus는 트래픽을 올바른 업스트림 서버와 Kubernetes NodePorts로 로드 밸런싱합니다. 추가 NGINX Plus 인스턴스를 추가하면 높은 가용성을 달성할 수 있습니다.

NGINX 로드밸런서가 동작하는 다이어그램

Kubernetes용 NGINX 로드밸런서의 작동 스냅샷

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

  1. 서비스 유형nginx-ingressLoadBalancer
  2. 외부 IP – NGINX Plus 서버에 연결
  3. 포트 - NodePort는 NGINX 업스트림 서버와 일치하는 443:30158에 매핑됩니다(NGINX Plus 실시간 대시보드 에 표시됨)
  4. 로그 - Kubernetes용 NGINX 로드밸런서가 NGINX Plus로 데이터를 성공적으로 전송하고 있음을 나타냄

NGINX Plus 윈도우

메모 : 이 예에서 Kubernetes 워커 노드는 10.1.1.8 및 10.1.1.10입니다.

NGINX Plus 보안 기능 추가

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

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

오늘 시작하세요

Kubernetes 클러스터의 가장자리에서 네트워킹 문제로 어려움을 겪고 있다면 NGINX 다중 클러스터 솔루션을 사용해 보세요. Kubernetes 소프트웨어용 NGINX 로드밸런서를 테스트해 보시고 여러분의 의견을 들려주세요. 소스 코드는 오픈 소스(Apache 2.0 라이선스)이며 모든 설치 지침은 GitHub에서 확인할 수 있습니다.

피드백을 제공하려면 repo에 댓글을 남기거나 NGINX 커뮤니티 Slack 에서 메시지를 보내주세요.


"이 블로그 게시물에는 더 이상 사용할 수 없거나 더 이상 지원되지 않는 제품이 참조될 수 있습니다. 사용 가능한 F5 NGINX 제품과 솔루션에 대한 최신 정보를 보려면 NGINX 제품군을 살펴보세요. NGINX는 이제 F5의 일부가 되었습니다. 이전의 모든 NGINX.com 링크는 F5.com의 유사한 NGINX 콘텐츠로 리디렉션됩니다."