mobile background
NGINX Ingress/Gateway Fabric 에서 구현가능한 기술 / 사용사례 소개 64
프로필 이미지
관리자
2025-01-15
조회 12

모놀리스를 마이크로서비스로 리팩토링하기


NGINX Plus를 사용하여 마이크로서비스를 구현하는 방법에 대한 정보와 함께 전체 문서 세트를 

전자책인 Microservices: From Design to Deployment 로 다운로드할 수 있습니다. 

그리고 Microservices Reference Architecture 및 Microservices Solutions 페이지 에 대한 시리즈를 참조하세요 .


이것은 마이크로서비스로 애플리케이션을 빌드하는 것에 대한 제 시리즈의 일곱 번째이자 마지막 기사입니다. 

첫 번째 기사에서는 마이크로서비스 아키텍처 패턴을 소개 하고 마이크로서비스를 사용하는 것의 이점과 단점을 논의합니다. 

다음 기사에서는 마이크로서비스 아키텍처의 다양한 측면을 논의합니다. 


API Gateway<.htmla> 사용, 프로세스 간 통신 , 서비스 검색 , 이벤트 기반 데이터 관리 및 마이크로서비스 배포 . 

이 기사에서는 모놀리식 애플리케이션을 마이크로서비스로 마이그레이션하기 위한 전략을 살펴봅니다.


이 일련의 기사가 마이크로서비스 아키텍처, 이점과 단점, 

그리고 언제 사용해야 하는지에 대한 좋은 이해를 주었기를 바랍니다. 

아마도 마이크로서비스 아키텍처가 여러분의 조직에 적합할 것입니다.


하지만 여러분이 크고 복잡한 모놀리식 애플리케이션을 작업하고 있을 가능성은 상당히 높습니다. 

애플리케이션을 개발하고 배포하는 일상적인 경험은 느리고 고통스럽습니다. 

마이크로서비스는 먼 천국처럼 보입니다. 

다행히도 모놀리식 지옥에서 벗어나는 데 사용할 수 있는 전략이 있습니다. 


이 글에서는 모놀리식 애플리케이션을 마이크로서비스 세트로 점진적으로 리팩토링하는 방법을 설명합니다.


마이크로서비스 리팩토링 개요

모놀리식 애플리케이션을 마이크로서비스로 변환하는 프로세스는 애플리케이션 모던화의 한 형태입니다. 

이는 개발자들이 수십 년 동안 해 온 일입니다. 

그 결과, 애플리케이션을 마이크로서비스로 리팩토링할 때 재사용할 수 있는 몇 가지 아이디어가 있습니다.


사용하지 말아야 할 한 가지 전략은 "빅뱅" 재작성입니다. 

즉, 모든 개발 노력을 처음부터 새로운 마이크로서비스 기반 애플리케이션을 빌드하는데 집중하는 것입니다. 

매력적으로 들리지만 매우 위험하며 실패로 끝날 가능성이 큽니다. 

Martin Fowler가 말했듯 이 "빅뱅 재작성이 보장하는 것은 빅뱅뿐입니다!"

빅뱅 리라이트 대신 모놀리식 애플리케이션을 점진적으로 리팩토링 해야 합니다. 

마이크로서비스로 구성된 새로운 애플리케이션을 점진적으로 빌드하고 모놀리식 애플리케이션과 함께 실행합니다. 

시간이 지남에 따라 모놀리식 애플리케이션에서 구현된 기능의 양이 줄어들어 

완전히 사라지거나 다른 마이크로서비스가 됩니다. 


이 전략은 고속도로를 시속 70마일로 달리면서 자동차를 정비하는 것과 비슷합니다. 

어렵지만 빅뱅 리라이트를 시도하는 것보다 훨씬 덜 위험합니다.


Martin Fowler는 이 애플리케이션 현대화 전략을 Strangler Application 이라고 부릅니다. 

이 이름은 열대 우림에서 발견되는 strangler vine(strangler fig라고도 함)에서 유래했습니다. 

strangler vine은 숲 캐노피 위의 햇빛에 도달하기 위해 나무 주위에서 자랍니다. 


때로는 나무가 죽어서 나무 모양의 덩굴이 남습니다. 

애플리케이션 현대화도 같은 패턴을 따릅니다. 

우리는 결국 죽을 레거시 애플리케이션 주변에 마이크로서비스로 구성된 새로운 애플리케이션을 빌드할 것입니다.

Richardson-microservices-part7-fig.png

이를 위해 다양한 전략을 살펴보겠습니다.

전략 1 – 파기 중단

홀의 법칙은 당신 이 홀에 빠졌을 때마다 파는 것을 멈춰야 한다고 말합니다. 

이것은 모놀리스 애플리케이션이 관리 불가능해졌을 때 따르기에 좋은 조언입니다. 

다시 말해, 모놀리스를 더 크게 만드는 것을 멈춰야 합니다. 

즉, 새로운 기능을 구현할 때 모놀리스에 더 많은 코드를 추가해서는 안 됩니다. 

대신, 이 전략의 큰 아이디어는 그 새로운 코드를 독립형 마이크로서비스에 넣는 것입니다. 

다음 다이어그램은 이 접근 방식을 적용한 후의 시스템 아키텍처를 보여줍니다.

Richardson-microservices-part7-pull-module-from-monolith.png


새로운 서비스와 레거시 모놀리스 외에도 두 가지 다른 구성 요소가 있습니다. 

첫 번째는 들어오는 (HTTP) 요청을 처리하는 요청 라우터입니다. 

이는 이전 문서<.htmla>에서 설명한 API 게이트웨이와 유사합니다. 

라우터는 새로운 기능에 해당하는 요청을 새 서비스로 보냅니다. 

레거시 요청을 모놀리스로 라우팅합니다.


다른 구성 요소는 서비스를 모놀리스와 통합하는 글루 코드입니다. 

서비스는 거의 고립되어 존재하지 않으며 종종 모놀리스가 소유한 데이터에 액세스해야 합니다. 

모놀리스, 서비스 또는 둘 다에 있는 글루 코드는 데이터 통합을 담당합니다. 

서비스는 글루 코드를 사용하여 모놀리스가 소유한 데이터를 읽고 씁니다.

서비스는 모놀리스의 데이터에 액세스하는 데 사용할 수 있는 세 가지 전략이 있습니다.


  • 모놀리스가 제공하는 원격 API를 호출합니다.
  • 모놀리스의 데이터베이스에 직접 액세스하세요
  • 모놀리스의 데이터베이스와 동기화된 자체 데이터 사본을 유지합니다.


글루 코드는 때때로 부패 방지 계층 이라고 불립니다 . 

글루 코드는 고유한 도메인 모델이 있는 서비스가 레거시 모놀리스 도메인 모델의 개념으로 오염되는 것을 방지하기 때문입니다. 

글루 코드는 두 가지 다른 모델 간에 변환됩니다. 

부패 방지 계층이라는 용어는 에릭 에반스의 필독서인 도메인 주도 설계에 처음 등장한 후 백서 에서 다듬어졌습니다 . 

부패 방지 계층을 개발하는 것은 사소한 일이 아닐 수 있습니다. 

하지만 모놀리스 지옥에서 벗어나려면 계층을 만드는 것이 필수적입니다.

새로운 기능을 가벼운 서비스로 구현하면 몇 가지 이점이 있습니다. 

모놀리스가 더욱 관리하기 어려워지는 것을 방지합니다. 

서비스는 모놀리스와 독립적으로 개발, 배포 및 확장할 수 있습니다. 

새로 만드는 각 서비스에서 마이크로서비스 아키텍처의 이점을 경험할 수 있습니다.

하지만 이 접근 방식은 모놀리스의 문제를 해결하는 데 아무런 도움이 되지 않습니다. 

이러한 문제를 해결하려면 모놀리스를 분해해야 합니다. 이를 위한 전략을 살펴보겠습니다.


전략 2 – 프런트엔드와 백엔드 분할

모놀리식 애플리케이션을 축소하는 전략은 프레젠테이션 계층을 비즈니스 로직 및 데이터 액세스 계층에서 분리하는 것입니다. 

일반적인 엔터프라이즈 애플리케이션은 최소한 세 가지 유형의 구성 요소로 구성됩니다.

  • 프레젠테이션 계층 – HTTP 요청을 처리하고 (REST) API 또는 HTML 기반 웹 UI를 구현하는 구성 요소입니다. 
  • 정교한 사용자 인터페이스가 있는 애플리케이션에서 프레젠테이션 계층은 종종 상당한 양의 코드입니다.
  • 비즈니스 로직 계층 – 애플리케이션의 핵심이며 비즈니스 규칙을 구현하는 구성 요소입니다.
  • 데이터 액세스 계층 – 데이터베이스 및 메시지 브로커와 같은 인프라 구성 요소에 액세스하는 구성 요소입니다.


일반적으로 한 쪽의 프레젠테이션 로직과 다른 쪽의 비즈니스 및 데이터 액세스 로직 사이에는 명확한 구분이 있습니다. 

비즈니스 계층에는 비즈니스 로직 구성 요소를 캡슐화하는 하나 이상의 파사드로 구성된 거친 API가 있습니다. 

이 API는 모놀리스를 두 개의 작은 애플리케이션으로 분할할 수 있는 자연스러운 이음새입니다. 

한 애플리케이션에는 프레젠테이션 계층이 포함됩니다. 


다른 애플리케이션에는 비즈니스 및 데이터 액세스 로직이 포함됩니다. 

분할 후 프레젠테이션 로직 애플리케이션은 비즈니스 로직 애플리케이션에 원격 호출을 합니다. 

다음 다이어그램은 리팩토링 전과 후의 아키텍처를 보여줍니다.


Richardson-microservices-part7-refactoring.png

이런 방식으로 모놀리스를 분할하면 두 가지 주요 이점이 있습니다. 

두 애플리케이션을 서로 독립적으로 개발, 배포 및 확장할 수 있습니다. 

특히, 프레젠테이션 계층 개발자는 사용자 인터페이스에서 빠르게 반복하고 

예를 들어 A/B 테스트를 쉽게 수행할 수 있습니다. 


이 접근 방식의 또 다른 이점은 개발한 마이크로서비스에서 호출할 수 있는 원격 API를 노출한다는 것입니다.

하지만 이 전략은 부분적인 해결책일 뿐입니다. 

애플리케이션 중 하나 또는 둘 다 관리할 수 없는 모놀리스가 될 가능성이 매우 높습니다. 

나머지 모놀리스를 제거하려면 세 번째 전략을 사용해야 합니다.


전략 3 – 서비스 추출

세 번째 리팩토링 전략은 모놀리스 내의 기존 모듈을 독립형 마이크로서비스로 전환하는 것입니다. 

모듈을 추출하여 서비스로 전환할 때마다 모놀리스는 줄어듭니다. 

충분한 모듈을 전환하면 모놀리스는 더 이상 문제가 되지 않습니다. 

완전히 사라지거나 그냥 또 다른 서비스일 정도로 작아집니다.


어떤 모듈을 서비스로 변환할 것인지 우선 순위 지정

크고 복잡한 모놀리식 애플리케이션은 수십 또는 수백 개의 모듈로 구성되며, 모두 추출 후보입니다. 

어떤 모듈을 먼저 변환할지 파악하는 것은 종종 어렵습니다. 

좋은 방법은 추출하기 쉬운 몇 개의 모듈로 시작하는 것입니다. 

이렇게 하면 일반적으로 마이크로서비스와 특히 추출 프로세스에 대한 경험을 얻을 수 있습니다. 


그런 다음 가장 큰 이점을 제공하는 모듈을 추출해야 합니다.

모듈을 서비스로 변환하는 것은 일반적으로 시간이 많이 걸립니다. 

모듈은 얻을 수 있는 이점에 따라 순위를 매겨야 합니다. 

일반적으로 자주 변경되는 모듈을 추출하는 것이 좋습니다. 

모듈을 서비스로 변환하면 모놀리스와 독립적으로 개발하고 배포할 수 있으므로 개발 속도가 빨라집니다.


또한 모놀리스의 나머지와 크게 다른 리소스 요구 사항이 있는 모듈을 추출하는 것도 유익합니다. 

예를 들어, 메모리 내 데이터베이스가 있는 모듈을 서비스로 전환하여 대량의 메모리가 있는 호스트에 배포할 수 있습니다. 

마찬가지로, 컴퓨팅 비용이 많이 드는 알고리즘을 구현하는 모듈을 추출하는 것도 가치가 있을 수 있습니다. 

서비스를 대량의 CPU가 있는 호스트에 배포할 수 있기 때문입니다. 


특정 리소스 요구 사항이 있는 모듈을 서비스로 전환하면 애플리케이션을 훨씬 더 쉽게 확장할 수 있습니다.

추출할 모듈을 파악할 때 기존의 거친 경계(일명 이음매)를 찾는 것이 유용합니다. 

이를 통해 모듈을 서비스로 전환하는 것이 더 쉽고 저렴해집니다. 

이러한 경계의 예로는 비동기 메시지를 통해 나머지 애플리케이션과만 통신하는 모듈이 있습니다. 

해당 모듈을 마이크로서비스로 전환하는 것은 비교적 저렴하고 쉽습니다.


모듈 추출 방법

모듈 추출의 첫 번째 단계는 모듈과 모놀리스 간에 거친 인터페이스를 정의하는 것입니다. 

모놀리스는 서비스가 소유한 데이터가 필요하고 그 반대의 경우도 마찬가지이므로 대부분 양방향 API일 가능성이 큽니다. 

모듈과 나머지 애플리케이션 간의 얽힌 종속성과 세분화된 상호 작용 패턴으로 인해 이러한 API를 구현하는 것이 종종 어렵습니다. 

도메인 모델 패턴을 사용하여 구현된 비즈니스 로직은 도메인 모델 클래스 간의 수많은 연관 관계로 인해 리팩토링하기가 특히 어렵습니다. 


이러한 종속성을 끊으려면 종종 상당한 코드 변경이 필요합니다. 

다음 다이어그램은 리팩토링을 보여줍니다.

거친 인터페이스를 구현한 후에는 모듈을 독립형 서비스로 전환합니다. 

그러기 위해서는 모놀리스와 서비스가 IPC( 프로세스 간 통신 ) 

메커니즘을 사용하는 API를 통해 통신할 수 있도록 코드를 작성해야 합니다. 

다음 다이어그램은 리팩토링 전, 중, 후의 아키텍처를 보여줍니다.


Richardson-microservices-part7-extract-module.png

이 예에서 모듈 Z는 추출할 후보 모듈입니다. 

모듈 X에서 구성 요소를 사용하고 모듈 Y를 사용합니다. 

첫 번째 리팩토링 단계는 거친 API 쌍을 정의하는 것입니다. 

첫 번째 인터페이스는 모듈 X에서 모듈 Z를 호출하는 데 사용하는 인바운드 인터페이스입니다. 

두 번째 인터페이스는 모듈 Z에서 모듈 Y를 호출하는 데 사용하는 아웃바운드 인터페이스입니다.

두 번째 리팩토링 단계는 모듈을 독립형 서비스로 전환합니다.

 

인바운드 및 아웃바운드 인터페이스는 IPC 메커니즘을 사용하는 코드로 구현됩니다. 

서비스 검색과 같은 교차적 문제를 처리하는 Microservice Chassis 프레임워크와 모듈 Z를 결합하여 서비스를 빌드해야 할 가능성이 높습니다.

모듈을 추출하면 모놀리스와 다른 서비스와 독립적으로 개발, 배포 및 확장할 수 있는 또 다른 서비스가 생깁니다. 

서비스를 처음부터 다시 작성할 수도 있습니다. 


이 경우 모놀리스와 서비스를 통합하는 API 코드는 두 도메인 모델 간에 변환되는 부패 방지 계층이 됩니다. 

서비스를 추출할 때마다 마이크로서비스 방향으로 한 걸음 더 나아갑니다. 

시간이 지남에 따라 모놀리스는 줄어들고 마이크로서비스의 수가 늘어날 것입니다.


요약

기존 애플리케이션을 마이크로서비스로 마이그레이션하는 프로세스는 애플리케이션 모던화의 한 형태입니다. 

처음부터 애플리케이션을 다시 작성하여 마이크로서비스로 전환해서는 안 됩니다. 

대신 애플리케이션을 점진적으로 리팩토링하여 일련의 마이크로서비스로 전환해야 합니다. 

사용할 수 있는 세 가지 전략이 있습니다. 

새로운 기능을 마이크로서비스로 구현합니다. 

프레젠테이션 구성 요소를 비즈니스 및 데이터 액세스 구성 요소에서 분리합니다. 

모놀리스의 기존 모듈을 서비스로 변환합니다. 

시간이 지남에 따라 마이크로서비스의 수가 늘어나고 개발 팀의 민첩성과 속도가 향상됩니다.


편집자  – 이 7부작 시리즈 기사는 이제 완료되었습니다.

마이크로서비스 소개

마이크로서비스 구축: API 게이트웨이 사용

마이크로서비스 구축: 마이크로서비스 아키텍처에서의 프로세스 간 통신

마이크로서비스 아키텍처에서의 서비스 발견

마이크로서비스를 위한 이벤트 기반 데이터 관리

마이크로서비스 배포 전략 선택

모놀리스를 마이크로서비스로 리팩토링하기(이 문서)


또한 NGINX Plus를 사용하여 마이크로서비스를 구현하는 방법에 대한 정보와 함께 

전체 문서 세트를 전자책인 Microservices: From Design to Deployment 로 다운로드할 수 있습니다. 

그리고 Microservices Reference Architecture 및 Microservices Solutions 페이지 에 대한 시리즈를 참조하세요 .



위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요.



전문가에게 상담받기

프로필 이미지
관리자
2024-11-13
조회 189

2016년 9월, 오스틴에서 열린 NGINX.conf 2016에서 저는 Docker Swarm 클러스터에서 

NGINX와 NGINX Plus를 활용하는 방법에 대해 발표했습니다. 

이 글에서는 Docker 1.12에서 새롭게 추가된 기능을 포함해 

Docker Swarm의 로드 밸런싱 기능을 NGINX와 NGINX Plus로 구현하는 방법을 설명하고자 합니다. 

발표에서 사용했던 모든 파일은 GitHub에서 제공되며, 직접 실험해볼 수 있습니다.


개요

2016년 7월 말 출시된 Docker 1.12는 Docker Engine과 Swarm을 통합하여 몇 가지 새로운 오케스트레이션 기능을 도입함으로써 

Kubernetes와 유사한 플랫폼을 제공합니다. 

Docker 1.12의 Swarm 모드는 여러 Docker 호스트를 하나의 Swarm으로 통합하여 내결함성, 자동 복구 기능, 분산 아키텍처를 지원합니다. 

이 플랫폼은 Swarm 클러스터 설정을 단순화하고, 모든 노드에 키 기반 보호와 노드 간 통신의 TLS 암호화를 기본으로 제공합니다.


Docker API는 이제 컨테이너 세트를 ‘서비스’로 인식하게 되어, 서비스를 생성 및 확장하고, 

롤링 업데이트와 상태 검사를 수행하는 등 다양한 기능을 제공합니다. 

DNS 기반 서비스 검색과 로드 밸런싱이 기본으로 제공되며, 클러스터 전체에 걸친 오버레이 네트워크도 설정할 수 있습니다.

Docker Swarm 로드 밸런싱 토폴로지

이 데모에서는 관리자 노드와 두 개의 작업자 노드로 구성된 Swarm 클러스터를 사용했습니다. 

관리자 노드는 Swarm 명령어가 실행되는 중앙 노드로서, 

Swarm은 모든 노드에서 스케줄링, DNS 서비스 검색, 확장 및 컨테이너 로드 밸런싱을 담당합니다.



Swarm 관리자 노드와 두 개의 Swarm 작업자 노드를 갖춘 Docker 부하 분산을 위한 토폴로지

그림 1: Docker Swarm 클러스터 토폴로지

Docker Swarm 클러스터는 관리자 노드와 두 개의 작업자 노드로 구성되며, 

모든 노드는 내부 오버레이 네트워크를 통해 연결되어 있습니다. 

클러스터 내 컨테이너 간에는 이 네트워크를 통해 프라이빗 통신이 이루어지며, 

Swarm 로드 밸런서를 사용하여 외부와의 연결도 지원합니다.

Docker Swarm 클러스터 로드 밸런싱의 경우 내부 오버레이 네트워크는 외부 및 내부 연결을 제공합니다.그림 2. Docker Swarm 클러스터의 내부 및 외부 네트워크 연결

Docker Swarm 클러스터의 내부 오버레이 네트워크는 외부 및 내부 요청 모두를 처리합니다. 

Swarm 로드 밸런서는 모든 노드에서 실행되어 클러스터 내 모든 컨테이너에 대해 로드 밸런싱을 수행합니다. 

Swarm 기본 로드 밸런서가 배포된 경우, 인바운드 클라이언트 요청과 서비스 간 내부 요청을 

각각 그림 3의 녹색 및 빨간색 화살표로 표현했습니다.

NGINX 또는 NGINX Plus 없이 Docker Swarm 로드 밸런싱은 4계층에서만 내부 및 외부 트래픽을 처리합니다.그림 3. NGINX 또는 NGINX Plus가 없는 Swarm 클러스터에서 클라이언트 및 서비스 간 요청의 로드 밸런싱


하지만 Swarm에 자체 로드 밸런서가 포함되어 있음에도, 다른 로드 밸런서를 추가해야 하는 이유가 있습니다. 

Swarm의 기본 로드 밸런서는 Layer 4(TCP) 수준에서만 로드 밸런싱을 제공하기 때문에, 

다음과 같은 고급 기능을 원하는 애플리케이션에는 제한이 있습니다:

  • SSL/TLS 종료
  • URL 또는 헤더 기반의 콘텐츠 라우팅
  • 접근 제어 및 권한 관리
  • URL 리디렉션 및 다시 쓰기


또한 이미 로드 밸런서를 사용해 본 경험이 있을 수 있으며, 

Swarm과 함께 사용하면 이미 사용 중인 툴과 지식을 활용할 수 있습니다.

NGINX 오픈 소스 및 NGINX Plus의 역할

NGINX 오픈 소스와 NGINX Plus는 Swarm 기본 로드 밸런서로는 지원되지 않는 애플리케이션에 필수적인 다양한 기능을 제공합니다.

NGINX 오픈 소스 사용

NGINX 오픈 소스는 SSL/TLS 종료 외에도 다음과 같은 기능을 지원합니다:

  • 다양한 부하 분산 알고리즘
  • HTTP/2 및 WebSocket과 같은 프로토콜 지원
  • 구성 가능한 로깅 기능
  • 요청 속도, 대역폭, 연결에 따른 트래픽 제한
  • 고급 스크립팅(nginScript 동적 모듈로 Lua, Perl, JavaScript 등 지원)
  • 허용/거부 목록과 같은 보안 설정


NGINX 오픈 소스를 Swarm 클러스터에서 사용하는 가장 간단한 방법은 

NGINX를 하나 이상의 컨테이너로 서비스 형태로 배포하는 것입니다. 

필요한 포트는 클러스터 외부에 노출되며, 

Swarm 로드 밸런서는 이 포트로 들어오는 요청을 NGINX 컨테이너에 분배합니다.

195422aa1f2bc.png그림 4. Swarm 로드 밸런서는 NGINX 서비스에 대한 요청을 인스턴스 간에 분산합니다.


이 예제에서는 NGINX가 SSL/TLS 종료 서비스를 제공하도록 구성되어 있습니다. 

SSL/TLS 종료란 클라이언트와의 통신에서 SSL/TLS 암호화를 해제하여, 

클러스터 내부 통신에서는 암호화된 연결을 요구하지 않는 방식입니다. 


이를 설명하기 위해 클러스터에 백엔드 서비스 A를 배포하고 

세 개의 컨테이너(그림 5에 표시된 대로 한 노드에 두 개의 인스턴스, 다른 노드에 하나의 인스턴스)로 확장합니다. 

Swarm은 클러스터 내부에서 사용할 가상 IP 주소(VIP)를 서비스 A에 할당합니다. 

컨테이너의 개별 IP 주소를 나열하는 대신 서비스 A의 업스트림 그룹의 NGINX 구성에서 이 VIP를 사용합니다. 

이렇게 하면 NGINX 구성을 변경하지 않고도 서비스 A를 확장할 수 있습니다.

479ec46f634e8.png그림 5. NGINX는 외부 클라이언트 요청에 대해 SSL/TLS 종료를 제공합니다.


그림 5에서 보듯이, 클라이언트가 첫 번째 Swarm 노드에 서비스 A에 대한 요청을 하면, 

해당 노드의 Swarm 로드 밸런서는 요청을 NGINX로 라우팅합니다. NGINX는 요청을 처리하는데, 

이 예에서는 SSL/TLS 복호화를 수행하고 서비스 A의 VIP로 라우팅합니다.

Swarm 로드 밸런서는 (이제 암호화되지 않은) 요청을 

모든 Swarm 노드의 서비스 A 컨테이너 중 하나로 라우팅합니다.


이런 구조는 클러스터 외부에서의 SSL/TLS 통신은 유지하면서, 

내부에서는 비암호화된 상태로 빠르게 요청을 전달할 수 있어, 

보안성과 성능을 모두 고려한 효율적인 아키텍처를 제공합니다.



NGINX는 로드 밸런싱된 요청을 백엔드 컨테이너로 직접 보낼 수 있으며, 

또한 내부 서비스 간 요청을 처리할 수 있습니다. 

하지만 이 경우, 서비스 A의 컨테이너 인스턴스가 확장될 때마다 NGINX 구성을 수동으로 업데이트하고 

다시 로드해야 하는 번거로움이 발생합니다. 

이는 서비스 인스턴스가 자주 변경되는 환경에서는 다소 복잡한 해결책이 될 수 있습니다.


이 문제를 더 효율적으로 해결할 수 있는 방법이 NGINX Plus를 활용하는 것입니다.

NGINX Plus는 서비스 인스턴스의 동적 변화를 자동으로 인식하여, 

NGINX 구성을 수동으로 조정할 필요 없이 자동으로 로드 밸런싱 설정을 업데이트할 수 있습니다. 

이를 통해 운영의 복잡성을 줄이고, 서비스의 확장과 유지보수를 보다 쉽게 관리할 수 있습니다.


NGINX Plus 사용

NGINX Plus가 제공하는 추가 기능 중 일부는 다음과 같습니다.


> 활성 애플리케이션 상태 점검  – NGINX Plus는 백엔드 노드를 지속적으로 점검하여 정상 상태이며 

적절하게 응답하는지 확인하고, 로드 밸런싱 로테이션에서 비정상 상태인 노드를 제거합니다


> 세션 지속성 - 스티키 세션이라고도 하며 , 클라이언트가 동일한 백엔드로 요청을 계속 보내야 하는 애플리케이션에 필요합니다. 

NGINX Plus는 열려 있는 세션이 있는 클라이언트에 영향을 주지 않고, 

백엔드 서버를 오프라인으로 전환해야 할 때 세션 드레이닝을 지원합니다.


> 동적 재구성  - NGINX 구성을 변경하고 다시 로드할 필요 없이 백엔드를 확장 및 축소할 수 있는 기능을 제공합니다. 

이는 Swarm과 같은 마이크로서비스 플랫폼으로 서비스 검색을 수행할 때 특히 유용하며, 

NGINX Plus가 이러한 플랫폼과 완벽하게 통합될 수 있도록 하는 가장 중요한 기능 중 하나입니다. 

동적 재구성 방법에는 두 가지가 있습니다. NGINX Plus에 변경 사항을 푸시할 수 있는 

API와 NGINX Plus가 도메인 이름에 연결된 노드 수의 변경 사항을 지속적으로 확인하는 DNS입니다. 

이 방법은 이 NGINX Plus 데모에서 Swarm의 기본 제공 서비스 검색과 통합하는 데 사용됩니다.


> 라이브 활동 모니터링  – NGINX Plus에서 광범위한 지표를 얻기 위한 API와 API를 기반으로 

구축된 웹 대시보드를 제공하여 지표를 보고 백엔드 서버를 추가, 제거, 변경할 수 있습니다.


위 설명에 따르면, NGINX 오픈 소스 구성에서는 

Swarm 로드 밸런서가 주로 외부 요청을 백엔드 컨테이너에 분산시키고 서비스 간 내부 요청을 처리합니다. 

여기서 NGINX의 주요 역할은 SSL/TLS 오프로드로, 

외부로부터 받은 암호화된 요청을 복호화해 백엔드 컨테이너로 전달하는 것입니다.


반면 NGINX Plus를 사용할 경우, Swarm 로드 밸런서가 여전히 외부 요청을 먼저 수신하지만, 

이후 요청의 실제 로드 밸런싱은 NGINX Plus가 수행하게 됩니다(그림 6 참조).


이 설정은 NGINX Plus가 요청을 처리하는 단계에서 고급 로드 밸런싱 기능을 활용하게 하며, 

고가용성(HA) 구성도 쉽게 구축할 수 있는 장점이 있습니다. 

Swarm 로드 밸런서가 초기에 요청을 받아 NGINX Plus로 전달하는 구조를 통해, 

NGINX Plus가 장애 발생 시에도 안정적인 운영을 유지할 수 있도록 설정할 수 있습니다.


클러스터 로드 밸런싱 토폴로지에서 NGINX Plus는 Docker Swarm 로드 밸런서에서 전달된 클라이언트 요청을 서비스 인스턴스 간에 로드 밸런싱합니다.그림 6. Docker Swarm 로드 밸런서는 서비스 인스턴스 간 로드 밸런싱을 위해 클라이언트 요청을 NGINX Plus로 전달합니다.

마찬가지로 Swarm 로드 밸런서는 서비스 간 요청을 받지만 NGINX Plus는 실제로 이를 여러 서비스에 분산합니다(그림 7).

Docker Swarm 로드 밸런싱 토폴로지에서 NGINX Plus는 Docker Swarm 로드 밸런서에서 전달된 서비스 간 요청을 서비스 인스턴스 간에 로드 밸런싱합니다.그림 7. Docker Swarm 로드 밸런서는 서비스 인스턴스 간 로드 밸런싱을 위해 서비스 간 요청을 NGINX Plus로 전달합니다.


NGINX를 사용하거나 사용하지 않고 Docker 로드 밸런싱에 Swarm을 사용하는 

몇 가지 예를 제공하기 위해 세 가지 데모를 만들었습니다. 

이러한 데모의 모든 파일은 자세한 지침과 함께 GitHub 에서 사용할 수 있습니다. 

세 가지 데모는 다음과 같습니다.

  • Docker Swarm 로드 밸런싱
  • NGINX 오픈 소스를 사용한 Docker Swarm 로드 밸런싱
  • NGINX Plus를 사용한 Docker Swarm 로드 밸런싱


Docker Swarm 로드 밸런싱

이는 NGINX나 NGINX Plus를 사용하지 않고도 간단한 웹 앱 백엔드에 대한 요청의 Docker Swarm 로드 밸런싱을 보여줍니다.


NGINX 오픈 소스를 사용한 Docker Swarm 로드 밸런싱

이 데모는 외부 요청에 대한 SSL/TLS 오프로드를 제공하기 위해 NGINX 오픈 소스를 추가합니다. 

Swarm 로드 밸런서는 이전 데모와 동일한 간단한 웹 앱 백엔드에 요청을 분산하고 내부 서비스 간 요청을 처리합니다.


NGINX Plus를 사용한 Docker Swarm 로드 밸런싱

이 데모의 첫 번째 부분에서는 NGINX Plus를 사용해 SSL/TLS 오프로드뿐 아니라, 

백엔드 컨테이너에 직접 요청을 로드 밸런싱하고, 내부 서비스 간 요청도 처리하는 방식을 보여줍니다. 

이때 NGINX Plus는 동적 DNS를 활용하여 백엔드 서비스와 관련된 도메인 이름을 지속적으로 확인하고, 

Swarm의 서비스 검색 기능과 통합되어 있습니다. 

이를 통해 백엔드 인프라가 변경될 때도 실시간으로 업데이트된 상태를 유지할 수 있습니다.


이 구성에서 NGINX Plus는 두 개의 백엔드 서비스, 즉 Service1과 Service2를 로드 밸런싱합니다. 

또한 Service1이 Service2에 요청을 보내는 방식으로 내부 서비스 간 요청을 처리합니다. 

이를 통해 서비스 간 통신에 있어서도 안정성과 효율성을 제공합니다.

 

Docker Swarm 부하 분산 토폴로지에서 NGINX Plus는 Swarm의 동적 DNS 서비스 검색 메커니즘을 사용합니다.그림 8. NGINX Plus는 백엔드 서비스 부하 분산 시 Swarm의 동적 DNS 서비스 검색 메커니즘을 사용합니다.

두 번째 부분에서는 NGINX Status API와 Docker Service API를 결합해 백엔드 컨테이너를 자동으로 확장하는 방법을 보여줍니다. 

이 구성에서는 Python 프로그램이 NGINX Plus Status API를 활용해 Service1과 Service2의 부하 상태를 모니터링하고, 

이를 기반으로 Docker Swarm의 Service API를 통해 백엔드 컨테이너를 확장하거나 축소합니다. 


Docker 부하 분산 토폴로지에서 Swarm은 NGINX Plus 라이브 활동 모니터링을 사용하여 자동 확장 목적으로 서비스 부하를 추적합니다.그림 9. Docker Swarm은 자동 확장 목적으로 서비스 부하를 추적하기 위해 NGINX Plus 라이브 활동 모니터링을 사용합니다.

요약

Docker 1.12에 도입된 새로운 기능은 Swarm을 더욱 강력한 플랫폼으로 만들었지만 

NGINX Open Source를 활용하고 NGINX Plus를 사용하면 더욱 강화할 수 있습니다. 

NGINX Plus가 DNS를 사용하여 부하 분산을 위해 백엔드 컨테이너를 동적으로 재구성하는 기능과 

Status API가 제공하는 가시성은 매우 강력한 컨테이너 솔루션을 제공합니다.

NGINX Plus를 사용해보려면 오늘 무료 30일 체험판을 시작하거나 저희에게 연락해 사용 사례에 대해 논의해 보세요 .

GitHub 저장소 에서 제공되는 데모를 사용해 보세요 .



위 내용과 같이 NGINX Plus 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요



전문가와 상담하기  

프로필 이미지
관리자
2024-11-08
조회 215

Red Hat과의 파트너십 에서 우리는 OpenShift에서 DevOps 호환 서비스 제공을 위한 고성능, 

확장 가능한 장기적 솔루션이 필요한 엔터프라이즈 사용자를 지원하는 데 계속 집중하고 있습니다. 

OpenShift용 NGINX Ingress Operator는 OpenShift 환경에서 기본 라우터와 함께 

Kubernetes용 NGINX Plus Ingress Controller를 배포하기 위한 지원 및 인증된 메커니즘으로 , 

포인트 앤 클릭 설치 및 자동 업그레이드가 가능합니다. 


Operator Lifecycle Manager (OLM)를 활용하여 NGINX Ingress Operator의 설치, 업그레이드 및 구성을 수행할 수 있습니다.

기본 라우터 외에도 NGINX Plus Ingress Controller를 사용하고 싶은 이유가 궁금하신가요? 

Red Hat + NGINX의 가치 블로그에서 파트너십이 안전하고 확장 가능하며 지원되는 애플리케이션 제공을 어떻게 가능하게 하는지 알아보세요.

이 단계별 가이드는 NGINX Ingress Operator를 시작하는 데 필요한 모든 것을 제공합니다. 

시작하기 전에 OpenShift 4.3 이상을 실행하는 OpenShift 클러스터 환경에 대한 관리자 액세스 권한이 있는지 확인하세요.


운영자 설치

NGINX Ingress Operator를 설치하는 방법을 보여주는 비디오와 스크린샷이 포함되어 있습니다.

OpenShift 콘솔에서 NGINX Ingress Operator를 설치합니다.

OpenShift 콘솔에 관리자로 로그인합니다. 왼쪽 탐색 열에서 Operators를 클릭한 다음 OperatorHub를 클릭합니다 . 

검색 상자에 nginx를 입력하고 나타나는 Nginx Ingress Operator 상자를 클릭합니다.

3. 제품 정보를 검토한 후 설치 버튼을 클릭하세요.


4. 열리는 Create Operator Subscription 페이지 에서 Operator를 설치할 클러스터 네임 스페이스를 지정합니다 

(이 예에서는 nginx-ingress ). 

또한 Approval Strategy 아래의 Automatic 라디오 버튼을 클릭하여 관리자의 수동 승인 없이 실행 중인 Operator 인스턴스의 자동 업데이트를 활성화합니다.  

Subscribe 버튼을 클릭합니다 .

5. 설치가 완료되면 터미널에서 다음 명령을 실행하여 Operator가 실행 중인지 확인하세요.

 # oc get pods –n nginx-ingress NAME READY STATUS RESTARTS AGE
 nginx-ingress-operator-dd546d869-xxxxx   1/1     Running   0          7m29s


6. 왼쪽 탐색 열에서 설치된 운영자를 클릭합니다. 

열리는 페이지에서 제공된 API 열에서 NginxIngressController 링크를 클릭합니다 . 

NginxIngressController는 운영자가 OpenShift 클러스터에 NGINX Plus Ingress Controller를 배포하는 데 사용하는 사용자 지정 리소스입니다.

fa5624b2a9b18.png

7. 열리는 페이지에서 다음 예제와 같은 매니페스트를 텍스트 필드에 붙여넣고 ' 만들기'  버튼을 클릭하여 

Kubernetes 배포를 위한 NGINX Plus Ingress Controller를 배포합니다.

TLS 인증서와 키가 있는 SecretdefaultSecret 을 필드에 임베드한다는 점에 유의하세요

 wildcardTLS. 이를 통해 Secret을 Ingress 정책에 포함시키지 않고도 TLS 종료 및 패스스루가 가능해집니다.

Kubernetes용 NGINX Plus Ingress Controller를 구성할 때 설정할 수 있는 다양한 옵션이 있으며, 이는 GitHub 저장소 에 나열되어 있습니다 

 

apiVersion: k8s.nginx.org/v1alpha1kind: NginxIngressController

metadata:

  name: my-nginx-ingress-controller

  namespace: nginx-ingress

spec:

  enableCRDs: true

  image:

    pullPolicy: Always

    repository: registry.hub.docker.com/nginx/nginx-ingress

    tag: edge

  nginxPlus: false

  serviceType: LoadBalancer

  type: deployment

  replicas: 2

  defaultSecret: nginx-ingress/default-server-secret

  wildcardTLS: default/app-secret

  configMapData:

    error-log-level: debug

  enableTLSPassthrough: true

  globalConfiguration: nginx-ingress/nginx-configuration

8. 배포를 확인하려면 터미널에서 다음 명령을 실행합니다. 출력에서 볼 수 있듯이 이전 단계에서 사용한 매니페스트는 NGINX Plus Ingress Controller의 복제본 두 개를 배포하고 이를 서비스에 노출했습니다 LoadBalancer. (명령의 출력은 get읽기 쉽도록 여러 줄에 걸쳐 있습니다.)

다음 명령을 실행하여 NGINX Plus Ingress Controller가 요청에 응답하는지 확인합니다. NGINX Plus Ingress Controller를 노출하는 서비스 public_IP_address의 외부 IP 주소를 대체합니다 .LoadBalancer

이 시점에서 명령이 를 반환한다는 점에 유의하세요 404 Not Found. 이는 아직 백엔드 Pod로 트래픽을 라우팅하기 위한 Ingress 리소스를 구성하고 배포하지 않았기 때문입니다. 자세한 내용은 설명서 를 참조하세요 .

# oc get pods -n nginx-ingressNAME                                          READY  STATUS   RESTARTS  AGE
my-nginx-ingress-controller-579f455d7d-xxxxx  1/1    Running  0         5m53s
my-nginx-ingress-controller-579f455d7d-xxxxx  1/1    Running  0         5m53s
nginx-ingress-operator-dd546d869-xxxxx        1/1    Running  0         56m

# oc get svc –n nginx-ingress
my-nginx-ingress-controller      LoadBalancer   172.xx.48.254    <pending>  ...   
nginx-ingress-operator-metrics   ClusterIP      172.xx.209.190   <none>     ...   
    ... 80:32028/TCP,443:31973/TCP   10m    
    ... 80:32028/TCP,443:31973/TCP   10m

다음 명령을 실행하여 NGINX Plus Ingress Controller가 요청에 응답하는지 확인합니다. NGINX Plus Ingress Controller를 노출하는 서비스 public_IP_address의 외부 IP 주소를 대체합니다 .LoadBalancer

이 시점에서 명령이 를 반환한다는 점에 유의하세요 404 Not Found. 이는 아직 백엔드 Pod로 트래픽을 라우팅하기 위한 Ingress 리소스를 구성하고 배포하지 않았기 때문입니다. 자세한 내용은 설명서 를 참조하세요 .

# curl public_IP_address <html> 
<head><title>404 Not Found</title></head> 
<body bgcolor="white"> 
<center><h1>404 Not Found</h1></center> 
<hr><center>nginx/1.13.4</center> 
</body> 
</html>

최종 사용자는 NginxIngressController 리소스의 여러 매니페스트를 제출할 수 있으며 각각에 대해 별도의 배포가 생성됩니다. 

Operator는 또한 다른 네임스페이스에 걸친 배포를 지원합니다. 

네임스페이스는 metadata매니페스트의 섹션에서 지정할 수 있습니다.

다음은 무엇인가요?

NGINX Ingress Operator는 특히 다음을 통해 NGINX Plus Ingress Controller 배포를 관리하는 데 도움이 됩니다.

  • 구성 – 몇 가지 입력 매개변수와 하나의 매니페스트만 사용하여 기본 배포 시작
  • 확장 – 복제본을 원활하게 추가 및 제거
  • 업그레이드 – 다운타임 없이 롤링 업데이트 활용
  • 제거 – 모든 Operator 및 Kubernetes Ingress Controller 객체가 적절하고 안전하게 제거되었는지 확인하십시오.

이제 NGINX Plus Ingress Controller를 준비하고 배포했으니, 

설명서 와 GitHub 리포지토리를 참조하여 OpenShift에서 NGINX Plus의 고급 기능을 사용해보세요.



위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요




프로필 이미지
관리자
2024-11-01
조회 143


이 블로그 시리즈는 Kubernetes의 테스트부터 운영 환경까지의 전환을 다루고 있으며, 전체 블로그를 묶어 제공하는 무료 eBook 형태로도 다운로드할 수 있습니다.점점 더 많은 기업들이 운영 환경에서 컨테이너화된 애플리케이션을 실행함에 따라 Kubernetes는 컨테이너 오케스트레이션의 표준 도구로서 입지를 굳히고 있습니다. 또한, COVID-19 팬데믹으로 인한 재택근무 확대가 인터넷 트래픽 증가를 가속화하면서 클라우드 컴퓨팅 수요 역시 몇 년 빨리 앞당겨졌습니다. 많은 회사들이 고객의 네트워크 장애와 과부하 문제를 해결하기 위해 인프라 업그레이드에 속도를 내고 있습니다.


클라우드 기반 마이크로서비스 환경에서 요구되는 성능 수준을 달성하기 위해서는 차세대 하이퍼스케일 데이터 센터의 확장성과 성능을 활용할 수 있는 빠르고 완전한 동적 소프트웨어가 필요합니다. Kubernetes를 사용하여 컨테이너를 관리하는 조직들 중 상당수가 NGINX 기반의 Ingress 컨트롤러를 사용하여 애플리케이션을 사용자에게 전달하고 있습니다.

이 블로그에서는 멀티 클라우드 환경에서 NGINX Ingress 컨트롤러 세 가지의 성능 테스트 결과를 보고합니다. 

테스트에서는 인터넷을 통한 클라이언트 연결의 지연 시간을 측정했습니다.

  • 커뮤니티 Ingress 컨트롤러: Kubernetes 커뮤니티에서 유지 관리하며 NGINX 오픈 소스를 기반으로 하는 Ingress 컨트롤러입니다. Google Container Registry에서 가져온 버전 0.34.1 이미지를 사용했습니다.
  • NGINX 오픈 소스 기반 NGINX Ingress 컨트롤러: NGINX에서 유지 관리하는 버전 1.8.0을 테스트했습니다.
  • NGINX Plus 기반 NGINX Ingress 컨트롤러: NGINX에서 유지 관리하는 버전 1.8.0을 테스트했습니다.

테스트 프로토콜 및 수집된 메트릭

우리는 wrk2라는 부하 생성 프로그램을 사용하여 클라이언트를 에뮬레이션하고, 정의된 기간 동안 지속적으로 HTTPS 요청을 생성했습니다. 테스트 중인 Ingress 컨트롤러(커뮤니티 Ingress 컨트롤러, NGINX 오픈 소스 기반 NGINX Ingress 컨트롤러, NGINX Plus 기반 NGINX Ingress 컨트롤러)는 Kubernetes Pods에 배포된 백엔드 애플리케이션으로 요청을 전달하고, 클라이언트에게 응답을 반환했습니다. Ingress 컨트롤러들을 스트레스 테스트하여 다음과 같은 성능 지표를 수집했습니다.

  • 지연 시간 (Latency): 클라이언트가 요청을 생성하고 응답을 받는 데 걸리는 시간입니다. 지연 시간은 백분위수 분포로 보고됩니다. 예를 들어, 지연 시간 테스트에서 100개의 샘플이 있을 경우, 99번째 백분위수의 값은 100번의 테스트 실행 중 가장 느린 응답 시간 바로 다음에 해당하는 지연 시간입니다.
  • 연결 타임아웃 (Connection timeouts): Ingress 컨트롤러가 특정 시간 내에 응답하지 않아 TCP 연결이 조용히 끊기거나 폐기되는 경우입니다.
  • 읽기 오류 (Read errors): Ingress 컨트롤러의 소켓이 닫혀 연결에서 읽기 시도가 실패하는 경우입니다.
  • 연결 오류 (Connection errors): 클라이언트와 Ingress 컨트롤러 간의 TCP 연결이 성립되지 않는 경우입니다.

토폴로지

모든 테스트에서 AWS 클라이언트 머신에서 wrk2 유틸리티를 사용해 요청을 생성했습니다. AWS 클라이언트는 Ingress 컨트롤러의 외부 IP 주소에 연결했으며, 해당 컨트롤러는 Google Kubernetes Engine(GKE) 환경의 GKE-node-1에 Kubernetes DaemonSet으로 배포되었습니다. Ingress 컨트롤러는 SSL 종료를 위해 Kubernetes Secret을 참조하고 레이어 7 라우팅이 구성되었으며, Kubernetes의 LoadBalancer 타입 서비스로 노출되었습니다. 백엔드 애플리케이션은 GKE-node-2에 Kubernetes Deployment로 실행되었습니다.


클라우드 머신 유형과 소프트웨어 구성에 대한 전체 세부 사항은 부록을 참조하세요.

테스트 방법론

클라이언트 배포

AWS 클라이언트 머신에서 wrk2 (버전 4.0.0) 스크립트를 실행했습니다. 이 스크립트는 두 개의 wrk 스레드를 생성하여 GKE에 배포된 Ingress 컨트롤러에 1,000개의 연결을 동시에 설정합니다. 각 테스트는 3분 동안 실행되며, 스크립트는 초당 30,000개의 요청(RPS)을 생성합니다. 이는 운영 환경에서 Ingress 컨트롤러에 가해질 수 있는 부하를 효과적으로 시뮬레이션하기 위한 적절한 조건으로 간주됩니다.

wrk -t2 -c1000 -d180s -L -R30000 https://app.example.com:443/

설명:

  • -t – 스레드 수를 설정 (2)
  • -c – TCP 연결 수를 설정 (1000)
  • -d – 테스트 실행 시간을 초 단위로 설정 (180초, 즉 3분)
  • -L – 분석 도구로 내보내기 위한 상세 지연 시간 백분위 정보를 생성
  • -R – 초당 요청 수 (RPS) 설정 (30,000)

TLS 암호화는 2048비트 키 크기의 RSA와 Perfect Forward Secrecy를 사용하여 구현했습니다.

백엔드 애플리케이션의 각 응답 (https://app.example.com:443에서 액세스)에는 약 1KB의 기본 서버 메타데이터와 200 OK HTTP 상태 코드가 포함됩니다.

백엔드 애플리케이션 배포

테스트는 정적 배포와 동적 배포 환경에서 수행했습니다.

  • 정적 배포에서는 5개의 Pod 복제본을 사용하였으며, Kubernetes API를 통해 적용된 변경 사항이 없습니다.

  • 동적 배포에서는 다음 스크립트를 사용하여 백엔드 nginx 배포를 주기적으로 확장하여 Pod 복제본을 5개에서 7개로 늘렸다가 다시 5개로 축소했습니다. 이를 통해 동적 Kubernetes 환경을 에뮬레이션하며 Ingress 컨트롤러가 엔드포인트 변경 사항에 얼마나 효과적으로 적응하는지 테스트했습니다.


while [ 1 -eq 1 ] do  
kubectl scale deployment nginx --replicas=5  sleep 12  
kubectl scale deployment nginx --replicas=7  sleep 10 done

성능 결과

정적 배포에 대한 지연 시간 결과
그래프에 나타난 바와 같이, 세 가지 Ingress 컨트롤러 모두 백엔드 애플리케이션의 정적 배포에서 유사한 성능을 보였습니다. 이는 모두 NGINX Open Source를 기반으로 하고 있으며, 정적 배포에서는 Ingress 컨트롤러의 재구성이 필요하지 않기 때문에 합리적인 결과입니다.

동적 배포에 대한 지연 시간 결과
동적 배포에서는 백엔드 애플리케이션의 Pod 복제본을 주기적으로 5개에서 7개로 확장했다가 다시 5개로 축소했습니다(자세한 내용은 백엔드 애플리케이션 배포 섹션 참조). 그래프에 따르면, 동적 환경에서는 NGINX Plus 기반 Ingress 컨트롤러만이 뛰어난 성능을 유지하며, 99.99번째 백분위수까지도 거의 지연 시간이 발생하지 않았습니다. 반면, 커뮤니티와 NGINX Open Source 기반 Ingress 컨트롤러는 각각 다른 양상으로 낮은 백분위수부터 눈에 띄는 지연 시간이 발생했습니다.

  • 커뮤니티 Ingress 컨트롤러의 경우 지연 시간이 점진적으로 증가하여 99번째 백분위수에서 약 5000ms(5초)에서 안정화되었습니다.
  • 반면, NGINX Open Source 기반 Ingress 컨트롤러의 경우 지연 시간이 급격히 증가하여 99번째 백분위수에서 약 32초에 도달했으며, 99.99번째 백분위수에서는 60초까지 증가했습니다.

이러한 지연 시간은 Ingress 컨트롤러가 백엔드 애플리케이션의 엔드포인트 변경에 대응해 NGINX 구성을 업데이트하고 재로드할 때 발생하는 오류와 타임아웃으로 인해 발생한 것입니다.


상세한 결과 분석

동일한 테스트 조건에서 커뮤니티 Ingress 컨트롤러와 NGINX Plus 기반 Ingress 컨트롤러의 성능을 보다 세밀하게 분석한 결과는 다음과 같습니다. NGINX Plus 기반 Ingress 컨트롤러는 99.99번째 백분위수까지 거의 지연 시간이 없으며, 99.9999번째 백분위수에서는 254ms에 도달하며 상승하기 시작합니다. 반면, 커뮤니티 Ingress 컨트롤러는 지연 시간이 점진적으로 증가하여 99번째 백분위수에서 5000ms에 도달한 후 일정한 수준을 유지합니다.

타임아웃 및 오류 결과 (동적 배포)

다음 표는 각 Ingress 컨트롤러에서 발생한 지연 시간의 원인을 상세히 설명합니다.

Connection errors3336500
Connection timeouts30988090
Read errors465000

NGINX Open Source 기반 Ingress 컨트롤러는 백엔드 애플리케이션의 엔드포인트 변경 시 매번 NGINX 설정을 업데이트하고 다시 로드해야 하므로 많은 연결 오류, 타임아웃, 읽기 오류가 발생했습니다. 설정이 리로드되는 동안 클라이언트가 할당되지 않은 소켓에 연결을 시도하거나, 백엔드 엔드포인트가 더 이상 사용 가능하지 않아 연결 타임아웃이 발생할 수 있습니다. 이러한 오류와 타임아웃으로 인해 높은 백분위수에서 32초에서 60초에 달하는 지연 시간이 발생했습니다.

커뮤니티 Ingress 컨트롤러는 엔드포인트 변경 시 설정을 다시 로드하지 않고 Lua 코드로 엔드포인트 변경을 처리합니다. 그 결과 일부 성능 문제가 개선되었지만, 여전히 연결 타임아웃이 발생하여 높은 백분위수에서 상당한 지연 시간이 관찰되었습니다.

NGINX Plus 기반 Ingress 컨트롤러는 NGINX Plus API를 사용하여 엔드포인트가 변경될 때마다 설정을 동적으로 업데이트하여 오류와 타임아웃이 발생하지 않았습니다. 성능에 거의 영향을 받지 않았으며, 최대 지연 시간은 99.9999번째 백분위수에서 254ms에 불과했습니다.

결론

이 테스트 결과에 따르면, 동적 Kubernetes 클라우드 환경에서 타임아웃과 오류를 완전히 없애기 위해서는 엔드포인트 변경 시 동적으로 설정을 조정할 수 있는 Ingress 컨트롤러가 필요합니다. NGINX Plus API는 동적 환경에서 NGINX 설정을 재구성하기 위한 최적의 솔루션임이 확인되었습니다.

Appendix

Cloud Machine Specs

MachineCloud ProviderMachine Type
ClientAWSm5a.4xlarge
GKE-node-1GCPe2-standard-32
GKE-node-2GCPe2-standard-32

NGINX Open Source 및 NGINX Plus Ingress 컨트롤러 설정

Kubernetes 설정

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-ingress
  namespace: nginx-ingress
spec:
  selector:
    matchLabels:
      app: nginx-ingress
  template:
    metadata:
      labels:
        app: nginx-ingress
     #annotations:
       #prometheus.io/scrape: "true"
       #prometheus.io/port: "9113"
    spec:
      serviceAccountName: nginx-ingress
      nodeSelector:
        kubernetes.io/hostname: gke-rawdata-cluster-default-pool-3ac53622-6nzr
      hostNetwork: true    
      containers:
      - image: gcr.io/nginx-demos/nap-ingress:edge
        imagePullPolicy: Always
        name: nginx-plus-ingress
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: https
          containerPort: 443
          hostPort: 443
        - name: readiness-port
          containerPort: 8081
       #- name: prometheus
         #containerPort: 9113
        readinessProbe:
          httpGet:
            path: /nginx-ready
            port: readiness-port
          periodSeconds: 1
        securityContext:
          allowPrivilegeEscalation: true
          runAsUser: 101 #nginx
          capabilities:
            drop:
            - ALL
            add:
            - NET_BIND_SERVICE
        env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        args:
          - -nginx-plus
          - -nginx-configmaps=$(POD_NAMESPACE)/nginx-config
          - -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret

ConfigMap 설정 (NGINX Plus)

이 설정은 NGINX Plus를 위한 ConfigMap으로, NGINX Open Source에 대한 참조는 필요에 따라 조정되었습니다. 

NGINX App Protect는 이미지(gcr.io/nginx-demos/nap-ingress)에 포함되어 있지만, 

-enable-app-protect 플래그는 생략되어 비활성화되었습니다. 

ConfigMap 예시

아래는 NGINX Plus의 ConfigMap 설정 예시입니다. 이 설정은 애플리케이션의 구성을 관리하기 위해 사용됩니다

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-config
  namespace: nginx-ingress
data:
  worker-connections: "10000"
  worker-rlimit-nofile: "10240"
  keepalive: "100"
  keepalive-requests: "100000000" 

커뮤니티 NGINX Ingress 컨트롤러 구성


Kubernetes 구성 예시

apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    helm.sh/chart: ingress-nginx-2.11.1
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.34.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/instance: ingress-nginx
      app.kubernetes.io/component: controller
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/component: controller
    spec:
      nodeSelector: 
        kubernetes.io/hostname: gke-rawdata-cluster-default-pool-3ac53622-6nzr
      hostNetwork: true
      containers:
        - name: controller
          image: us.gcr.io/k8s-artifacts-prod/ingress-nginx/controller:v0.34.1@sha256:0e072dddd1f7f8fc8909a2ca6f65e76c5f0d2fcfb8be47935ae3457e8bbceb20
          imagePullPolicy: IfNotPresent
          lifecycle:
            preStop:
              exec:
                command:
                  - /wait-shutdown
          args:
            - /nginx-ingress-controller
            - --election-id=ingress-controller-leader
            - --ingress-class=nginx
            - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
            - --validating-webhook=:8443
            - --validating-webhook-certificate=/usr/local/certificates/cert
            - --validating-webhook-key=/usr/local/certificates/key
          securityContext:
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
            runAsUser: 101
            allowPrivilegeEscalation: true
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          readinessProbe:
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            periodSeconds: 1
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
            - name: https
              containerPort: 443
              protocol: TCP
            - name: webhook
              containerPort: 8443
              protocol: TCP
          volumeMounts:
            - name: webhook-cert
              mountPath: /usr/local/certificates/
              readOnly: true
      serviceAccountName: ingress-nginx
      terminationGracePeriodSeconds: 300
      volumes:
        - name: webhook-cert
          secret:
            secretName: ingress-nginx-admission

ConfigMap 구성

apiVersion: v1
kind: ConfigMap
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
data:
  max-worker-connections: "10000"
  max-worker-open-files: "10204"
  upstream-keepalive-connections: "100"
  keep-alive-requests: "100000000"

백엔드 애플리케이션 구성

Kubernetes Configuration

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx 
  template:
    metadata:
      labels:
        app: nginx
    spec:
      nodeSelector:
        kubernetes.io/hostname: gke-rawdata-cluster-default-pool-3ac53622-t2dz 
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 8080
        volumeMounts: 
        - name: main-config-volume
          mountPath: /etc/nginx
        - name: app-config-volume
          mountPath: /etc/nginx/conf.d
        readinessProbe:
          httpGet:
            path: /healthz
            port: 8080
          periodSeconds: 3
      volumes: 
      - name: main-config-volume
        configMap:
          name: main-conf
      - name: app-config-volume
        configMap: 
          name: app-conf
---

ConfigMaps

apiVersion: v1
kind: ConfigMap
metadata:
  name: main-conf
  namespace: default
data:
  nginx.conf: |+
    user nginx;
    worker_processes 16;
    worker_rlimit_nofile 102400;
    worker_cpu_affinity auto 1111111111111111;
    error_log  /var/log/nginx/error.log notice;
    pid        /var/run/nginx.pid;
 
    events {
        worker_connections  100000;
    }
 
    http {
 
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
 
        sendfile        on;
        tcp_nodelay on;
 
        access_log off;
 
        include /etc/nginx/conf.d/*.conf;
    }
 
---
 
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-conf
  namespace: default
data:
  app.conf: "server {listen 8080;location / {default_type text/plain;expires -1;return 200 'Server address: $server_addr:
  $server_port\nServer name:$hostname\nDate: $time_local\nURI: $request_uri\nRequest ID:
  $request_id\n';}location /healthz {return 200 'I am happy and healthy :)';}}"
---

Service

apiVersion: v1
kind: Service
metadata:
  name: app-svc
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
    name: http
  selector:
    app: nginx
--- 


위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요



전문가에게 상담받기 


프로필 이미지
관리자
2024-09-24
조회 96


편집자 - 이 게시물은 10부작 시리즈의 일부입니다.

  1. 프로덕션 등급 Kubernetes로 복잡성 줄이기(이 게시물)
  2. 고급 트래픽 관리를 사용하여 Kubernetes의 복원력을 개선하는 방법
  3. Kubernetes에서 가시성을 개선하는 방법
  4. 트래픽 관리 도구를 사용하여 Kubernetes를 보호하는 6가지 방법
  5. Ingress Controller 선택 가이드, 1부: 요구 사항 식별
  6. Ingress 컨트롤러 선택 가이드, 2부: 위험 및 미래 대비
  7. Ingress 컨트롤러 선택 가이드, 3부: 오픈소스 대 기본 대 상업용
  8. Ingress 컨트롤러 선택 가이드, 4부: NGINX Ingress 컨트롤러 옵션
  9. 서비스 메시를 선택하는 방법
  10. 동적 Kubernetes 클라우드 환경에서 NGINX Ingress 컨트롤러 성능 테스트


2020년은 우리 중 거의 누구도 잊지 못할 한 해였습니다. 

학교, 기업, 공공 서비스가 갑자기 문을 닫으면서 우리는 갑자기 지역 사회에서 고립되었고 

안전과 재정적 안정에 대한 불확실성에 빠졌습니다. 

이제 이런 일이 2000년이나 2010년에 일어났다고 상상해보세요. 

무엇이 달랐을까요? 기술입니다. 


우리가 당연하게 여기는 고품질 디지털 서비스(의료, 스트리밍 비디오, 원격 협업 도구)가 없었다면 

팬데믹은 매우 다른 경험이었을 것입니다. 

2020년의 기술을 지난 수십 년과 크게 다르게 만든 것은 무엇일까요? 

컨테이너와 마이크로서비스입니다.


마이크로서비스 아키텍처(일반적으로 컨테이너와 쿠버네티스를 활용)는 디지털 경험의 출시 시간을 단축하여 

비즈니스 성장과 혁신을 촉진합니다. 

기존 아키텍처와 함께든 단독으로든 이러한 최신 앱 기술은 뛰어난 확장성과 유연성, 

더 빠른 배포, 심지어 비용 절감까지 가능하게 합니다.


2020년 이전에는 대부분 고객이 디지털 전환 전략의 일환으로 마이크로서비스를 도입하기 시작했지만, 

팬데믹으로 인해 앱 현대화가 진정으로 가속화되었습니다. 

NGINX 사용자를 대상으로 한 2020년 설문 조사에서 응답자의 60%가 프로덕션에서 마이크로서비스를 사용하고 있으며,

 이는 2019년의 40%에서 증가한 수치이며, 컨테이너는 다른 최신 앱 기술보다 두 배 이상 인기가 높습니다.


Kubernetes는 컨테이너화된 앱을 관리하는 데 있어 사실상의 표준입니다. 

이는 Cloud Native Computing Foundation(CNCF)의 2020년 설문 조사에서 입증되었는데, 

응답자의 91%가 Kubernetes를 사용하고 있으며, 그 중 83%가 프로덕션에 사용하고 있습니다. 

Kubernetes를 도입할 때 많은 조직은 상당한 아키텍처 변경에 대비하지만 

대규모로 최신 앱 기술을 실행하는 데 따른 조직적 영향에 놀랐습니다.


 Kubernetes를 실행하고 있다면 다음과 같은 세 가지 비즈니스에서 중요한 장벽을 모두 겪었을 가능성이 큽니다.


조직 문화 
앱 팀이 애자일 개발 및 DevOps와 같은 현대적인 접근 방식을 채택 하더라도 
일반적으로 "조직은 자체 커뮤니케이션 구조를 반영하는 시스템을 설계한다"는 Conway의 법칙에 따라야 합니다. 
즉, 분산 애플리케이션은 독립적으로 작동하지만 리소스를 공유하는 분산 팀에서 개발합니다. 
이 구조는 팀이 빠르게 실행할 수 있도록 하는 데 이상적이지만 사일로를 확립하도록 장려합니다. 
그 결과로는 커뮤니케이션 부족(자체적인 결과가 있음), 보안 취약성, 도구 확산, 일관되지 않은 자동화 관행 및 팀 간 충돌이 있습니다.

복잡성 
기업용 마이크로서비스 기술을 구현 하려면 조직에서 가시성, 보안 및 트래픽 관리를 제공하는 중요한 구성 요소 모음을 조각해야 합니다. 
일반적으로 팀은 인프라 플랫폼, 클라우드 네이티브 서비스 및 오픈 소스 도구를 사용하여 이러한 요구 사항을 충족합니다. 
이러한 전략에는 각각 자리가 있지만 복잡성에 기여할 수 있는 단점이 있습니다. 
그리고 단일 조직 내의 여러 팀이 동일한 요구 사항을 충족하기 위해 
서로 다른 전략을 선택하는 경우가 너무 많아서 "운영 부채"가 발생합니다. 
또한 팀은 특정 시점에 프로세스와 도구를 선택하고 컨테이너를 사용하여 
최신 마이크로서비스 기반 애플리케이션을 배포하고 실행하는 것과 관련된 요구 사항이 변경 되더라도 계속 사용합니다.

CNCF 클라우드 네이티브 인터랙티브 랜드스케이프는 마이크로서비스 기반 애플리케이션을 지원하는 데
필요한 인프라의 복잡성을 잘 보여줍니다.
조직은 광범위한 이질적 기술에 능숙 해져야 하며, 그로 인해 인프라 잠금, 섀도우 IT, 도구 확산, 
인프라 유지 관리 담당자들의 학습이 필요합니다. 

보안 
클라우드 네이티브 앱과 기존 앱의 보안 요구 사항은 상당히 다릅니다. 
왜냐하면 링펜스 보안과 같은 전략은 쿠버네티스에서 실행 가능하지 않기 때문입니다. 
컨테이너화된 앱의 대규모 생태계와 분산된 특성은 공격 표면이 훨씬 더 크다는 것을 의미하며, 
외부 SaaS 애플리케이션에 대한 의존성은 직원과 외부인이 악성 코드를 삽입하거나 
정보를 빼낼 수 있는 기회가 훨씬 더 많다는 것을 의미합니다. 


또한 문화 및 복잡성 영역에서 설명한 결과(특히 도구 확산)는 최신 앱의 보안 및 복원력에 직접적인 영향을 미칩니다. 
생태계 주변의 다양한 도구를 사용하여 동일한 문제를 해결하는 것은 비효율적일 뿐만 아니라 
각 구성 요소를 올바르게 구성하는 방법을 배워야 하는 SecOps 팀에 큰 과제를 안겨줍니다.

솔루션: 프로덕션 등급 Kubernetes

대부분의 조직적 문제와 마찬가지로 쿠버네티스의 과제를 극복하기 위한 답은 기술과 프로세스의 조합입니다. 

이 글의 나머지 부분에서는 기술 구성 요소에 집중하겠지만, 프로세스 및 기타 주제에 대한 향후 블로그에도 주목하세요.

쿠버네티스는 오픈소스 기술이기 때문에 구현 방법이 다양합니다. 


일부 조직은 자체 바닐라 쿠버네티스를 롤링하는 것을 선호하지만, 

많은 조직은 Amazon Elastic Kubernetes Service(EKS), 

Google Kubernetes Engine(GKE), Microsoft Azure Kubernetes Service(AKS), 

Red Hat OpenShift Container Platform, Rancher와 같은 서비스가 제공하는 

유연성, 처방성, 지원의 조합에서 가치를 찾습니다.


쿠버네티스 플랫폼은 쉽게 시작하고 실행할 수 있게 해줍니다. 하지만 깊이보다는 광범위한 서비스에 초점을 맞춥니다. 

따라서 필요한 모든 서비스를 한곳에서 얻을 수 있지만, 규모에 맞는 진정한 프로덕션 준비에 필요한 기능 세트를 제공하지는 않을 것입니다. 

즉, 고급 네트워킹과 보안에 초점을 맞추지 않는데, 쿠버네티스가 많은 고객을 실망시키는 부분입니다.

Kubernetes를 프로덕션 수준으로 만들려면 다음 순서로 세 가지 구성 요소를 추가해야 합니다.


  1. 클러스터에서 트래픽을 입출력하기 위한 확장 가능한 인그레스-이그레스 계층
    이는 Kubernetes 네트워킹의 복잡성을 추상화하고 Kubernetes 클러스터의 서비스와 외부 서비스 간을 연결하는 

특수 로드 밸런서인 Ingress 컨트롤러를 사용하여 달성됩니다. 

이 구성 요소는 복원성을 높이고(예: 고급 상태 검사 및 Prometheus 메트릭), 빠른 확장성(동적 재구성)을 지원하고, 

셀프 서비스(역할 기반 액세스 제어[RBAC])를 지원하는 기능이 포함되면 프로덕션 등급이 됩니다.


확장 가능한 인그레스-이그레스 계층을 제공하는 일반 인그레스 컨트롤러가 있는 Kubernetes 환경의 토폴로지 다이어그램


2. 클러스터 전체에서 위협으로부터 보호하기 위한 내장 보안

 
"거친" 보안이 클러스터 외부에서 충분할 수 있지만, 클러스터 내부에서는 "세밀한" 보안이 필요합니다. 

클러스터의 복잡성에 따라 유연한 웹 애플리케이션 방화벽(WAF)을 배포해야 할 수 있는 세 가지 위치가 있습니다. 

Ingress 컨트롤러, 서비스별 프록시, Pod별 프록시입니다. 

이러한 유연성 덕분에 민감한 앱(예: 청구)에는 더 엄격한 제어를 적용하고 위험이 낮은 곳에는 더 느슨한 제어를 적용할 수 있습니다.


일반 Ingress 컨트롤러와 함께 배포된 WAF가 있는 Kubernetes 환경의 토폴로지 다이어그램

3. 클러스터 내 트래픽을 최적화하기 위한 확장 가능한 동서 트래픽 계층
 

이 세 번째 구성 요소는 Kubernetes 애플리케이션이 기본 도구가 처리할 수 있는 복잡성과 규모 수준을 넘어선 후에 필요합니다. 

이 단계에서는 클러스터 내 애플리케이션 서비스에 더욱 세분화된 트래픽 관리 및 보안을 제공하는 오케스트레이션 도구인 

서비스 메시가 필요합니다. 서비스 메시는 일반적으로 컨테이너화된 애플리케이션 간의 애플리케이션 라우팅을 관리하고, 

자율적인 서비스 간 상호 TLS(mTLS) 정책을 제공하고 시행하며, 애플리케이션 가용성 및 보안에 대한 가시성을 제공하는 역할을 합니다


일반 Ingress 컨트롤러와 함께 배포된 WAF와 확장 가능한 동서 계층을 제공하는 서비스 메시가 있는 Kubernetes 환경의 토폴로지 다이어그램

이러한 구성 요소를 선택할 때 이식성과 가시성을 우선시하세요. 

플랫폼 독립적인 구성 요소는 복잡성을 줄이고 보안을 개선하며, 팀이 학습하고 보안을 강화해야 할 도구가 줄어들고 

비즈니스 요구 사항에 따라 워크로드를 보다 쉽게 전환할 수 있습니다. 

가시성과 모니터링의 중요성은 과장하기 어렵습니다. 


Grafana 및 Prometheus와 같은 인기 있는 도구와 통합하면 인프라에 대한 통합된 "단일 창" 뷰가 생성되어 

고객이 문제를 발견하기 전에 팀이 문제를 감지할 수 있습니다. 

또한 프로덕션 등급 Kubernetes에 반드시 필요하지는 않지만 최신 앱 개발의 필수적인 부분인 다른 보완 기술이 있습니다. 

예를 들어 조직이 기존 앱을 현대화할 준비가 되면 첫 번째 단계 중 하나는 API 게이트웨이로 마이크로서비스를 구축하는 것입니다.

NGINX가 어떻게 도움을 줄 수 있는지


당사의 Kubernetes 솔루션은 플랫폼에 구애받지 않으며 프로덕션 등급 Kubernetes를 활성화하는 데 필요한 세 가지 구성 요소를 포함합니다. 

즉, 수신-송신 계층인 NGINX Ingress Controller, WAF인 NGINX App Protect, 동서 계층인 NGINX Service Mesh입니다.

이러한 솔루션은 Kubernetes를 네 가지 핵심 영역에서 활성화하여ㅡ 가장 가깝게 활용할 수 있습니다.


- 자동화 
앱을 더 빠르고 안전하게 출시하세요
NGINX Ingress Controller의 트래픽 라우팅 및 앱 온보딩 기능과 NGINX Service Mesh의 NGINX Plus 사이드카
자동 배포를 결합하여 앱을 배포, 확장, 보호 및 업데이트하세요.

- 보안 
기존 및 새로운 위협으로부터 고객과 비즈니스를 보호하세요.
NGINX Service Mesh와 NGINX Ingress Controller를 사용하여 서비스 간 종단 간 암호화를 관리하고 적용하면서 
클러스터의 어느 곳에나 NGINX App Protect를 배포하여 잠재적인 장애 지점을 줄이세요.

- 성능 
고객과 사용자가 기대하는 디지털 경험 제공
NGINX 솔루션으로 성능을 저하시키지 않고도 트래픽 급증과 보안 위협을 손쉽게 처리하세요. 
이 솔루션은 다른 WAF, Ingress 컨트롤러 및 로드 밸런서보다 성능이 뛰어납니다.

- 통찰력 
비즈니스를 발전시키고 고객에게 더 나은 서비스를 제공하세요
NGINX Ingress Controller와 NGINX Service Mesh에서 앱 성능과 가용성에 대한 타겟팅된 통찰력을 얻고, 
마이크로서비스 앱에서 요청이 처리되는 방식을 이해하기 위한 심층적 추적을 활용하세요.

NGINX로 프로덕션 준비 완료

위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요





프로필 이미지
관리자
2024-09-13
조회 36


통찰력을 얻기 위한 가시성 확보

통찰력을 얻기 위한 가시성 확보 

가시성과 통찰력에 대한 기본 정의를 살펴보겠습니다:

  • 가시성: 사물이나 상태가 눈에 보이거나 인식될 수 있는 정도.
  • 통찰력: 사물이나 사람에 대한 깊은 이해와 통찰.

StackRox의 2020년 설문 조사에 따르면, Kubernetes 사용자 중 75%가 가시성을 "필수" 기능으로 인식했습니다. 

Kubernetes에서의 가시성은 특히 배포된 콘텐츠를 파악하기 어려운 경우가 많기 때문에 매우 중요합니다. 


그러나 F5의 2021년 State of Application Strategy(SOAS) 보고서에 따르면, 

응답자의 95%가 방대한 데이터는 가지고 있지만, 

애플리케이션의 성능, 보안, 가용성에 대한 중요한 통찰력이 부족하다고 보고했습니다. 

그렇다면 통찰력의 중요성과 이를 확보하는 방법에 대해 알아보겠습니다.


통찰력의 중요성:

통찰력은 다음과 같은 여러 측면에서 중요합니다:

  1. 보안 강화: 취약점과 잠재적인 공격 벡터를 식별하여 보안과 규정 준수를 개선할 수 있습니다.
  2. 문제 예방: 고객이 문제를 인식하기 전에 문제를 발견하여 시스템의 중단 및 가동 중지 시간을 줄일 수 있습니다.
  3. 문제 해결: 애플리케이션 문제의 근본 원인을 파악하여 문제 해결의 효율성을 높일 수 있습니다.
  4. 트래픽 관리: 트래픽이 적절한 방향으로 이동하는지 확인하여 서비스의 효율성을 보장할 수 있습니다.
  5. Kubernetes 환경 관리: 실행 중인 구성 요소를 정확히 파악하고, 적절하게 구성 및 보안 조치를 취할 수 있습니다.
  6. 리소스 최적화: 대기 시간과 성능 기록을 바탕으로 적절한 리소스 사용을 보장할 수 있습니다.
  7. 수요 예측: 과거의 트래픽 패턴을 분석하여 계절적 수요를 예측할 수 있습니다.
  8. SLA 성과 추적: 서비스 수준 계약(SLA)에 대한 성과를 측정하고, 사용자 경험에 영향을 미치기 전에 문제를 조기에 발견할 수 있습니다.

통찰력 확보 방법:

통찰력을 얻기 위해서는 두 가지 유형의 가시성 데이터가 필요합니다:

  1. 실시간 데이터: 현재 발생하고 있는 문제의 원인을 진단하는 데 유용합니다.
  2. 과거 데이터: 무엇이 '정상'이고 무엇이 이상치인지에 대한 기준을 제공합니다.

이 두 가지 유형의 데이터를 결합하면, 애플리케이션과 Kubernetes 성능에 대한 유의미한 통찰력을 얻을 수 있습니다.

전략적 접근 필요성:

SOAS 보고서는 또한 통찰력을 얻는 데 있어서 전략적 접근의 중요성을 강조합니다. 

전략적 접근을 가로막는 주요 조직적 요인은 다음과 같습니다:

관련 기술 세트 부족: 응답자의 47%가 숙련된 기술 전문가 부족을 문제로 보고했습니다.
- 데이터 공유 부족 : 응답자의 12%만이 비즈니스 의사 결정권자에게 데이터를 보고하여  
  기술적 문제의 비즈니스 영향을 설명하는 전략과 프로세스를 갖추고 있습니다.
- 가시성의 목적 부족 : 대부분의 응답자는 원격 측정을 문제 해결을 위해 반응적으로 사용하며,  
  오직 24%만이 잠재적인 성능 저하를 감시하기 위해 데이터를 적극적으로 사용하고, 16%만이 SLA 성과를 추적합니다.


이 게시물은 통찰력의 기술적 측면에 중점을 두었습니다.  

향후 블로그에서는 전략, 프로세스 및 기타 관련 주제에 대해 다룰 예정입니다.

NGINX가 Kubernetes에서 통찰력을 제공하는 방법

대부분의 Kubernetes 배포는 이미 여러 모니터링 도구를 사용하고 있지만, 

NGINX는 이러한 도구와의 통합을 통해 성능과 가용성에 대한 중요한 통찰력을 추가적으로 제공합니다. 

다음은 NGINX가 어떻게 도움이 되는지와 관련된 몇 가지 주요 측면입니다.

1. NGINX Plus API를 통한 메트릭 내보내기

NGINX Plus API는 메트릭을 쉽게 내보낼 수 있는 기능을 제공하며,

OpenTracing, Grafana, Prometheus와 같은 인기 있는 모니터링 도구와 통합할 수 있습니다. 

이를 통해 Kubernetes 클러스터 내에서 애플리케이션의 성능을 종합적으로 파악할 수 있습니다.

  • OpenTracing: 애플리케이션의 트랜잭션을 추적하여, 요청이 처리되는 과정을 시각적으로 분석할 수 있습니다.
  • Grafana: 실시간 대시보드와 시각화를 통해 NGINX의 성능 메트릭을 모니터링하고, 성능 트렌드를 시각화할 수 있습니다.
  • Prometheus: 메트릭을 수집하고 저장하여, NGINX 및 Kubernetes 환경의 성능을 세부적으로 분석할 수 있습니다.

2. 유입-유출 트래픽에 대한 인사이트

NGINX Ingress Controller는 Kubernetes 클러스터 내로 들어오고 나가는 트래픽에 대한 중요한 통찰력을 제공합니다. 

다양한 NGINX 기반 Ingress 컨트롤러 중에서 적합한 것을 선택하는 것이 중요합니다. 

잘못된 선택은 마이크로서비스 전략을 복잡하게 만들 수 있습니다. 

블로그 게시물 [Wait, Which NGINX Ingress Controller for Kubernetes Am I Using?]에서 

각 옵션을 비교하여 최적의 선택을 할 수 있도록 돕습니다.

3. 동서 트래픽에 대한 인사이트

NGINX Service Mesh는 컨테이너화된 애플리케이션 간의 트래픽 흐름에 대한 깊이 있는 통찰력을 제공합니다. 

이를 통해 다음과 같은 두 가지 일반적인 문제를 해결할 수 있습니다:

  • 앱이 느리거나 다운됨: DDoS 공격이나 애플리케이션 오류의 원인을 파악하는 데 도움이 됩니다.
  • 리소스 부족: 클러스터나 플랫폼의 리소스 부족 문제를 식별하고 해결할 수 있습니다.

4. NGINX Ingress Controller를 통한 라이브 모니터링

NGINX Plus를 사용하면 라이브 활동 모니터링 대시보드를 통해 수백 개의 주요 부하 및 성능 메트릭을 실시간으로 표시할 수 있습니다. 

이를 통해 단일 포드 수준까지 세부적인 정보를 얻을 수 있으며, 앱의 응답 시간을 빠르게 측정하고 문제의 근원을 진단할 수 있습니다. 

Kubernetes 환경이 커짐에 따라, 각 NGINX Ingress Controller 인스턴스에 대한 대시보드도 자동으로 업데이트됩니다.

요청: 초당 요청 수(Req/s)가 예상보다 낮으면 (예: 초당 40개의 요청이 정상이라면, 이 수치가 감소하면)
Ingress 컨트롤러나 애플리케이션의 구성 문제일 수 있습니다.
응답 시간: 응답 시간이 10밀리초(ms) 이하일 때는 우수한 상태입니다. 
응답 시간이 30~40ms 이상으로 증가하면 애플리케이션에 문제가 있을 가능성이 큽니다.


NGINX Ingress Controller의 스텁 상태

NGINX Ingress Controller는 NGINX 오픈 소스를 기반으로 하며, 기본적으로 8가지 주요 측정 항목을 보고하는 상태 페이지를 제공합니다.

이 상태 페이지는 다음과 같은 정보를 포함하여 Ingress Controller의 성능을 모니터링하는 데 유용합니다:
  • 요청 수: 초당 요청 수
  • 응답 시간: 평균 응답 시간
  • 오류율: HTTP 오류 코드 비율
  • 활성 연결 수: 현재 활성화된 연결의 수
  • 세션 수: 활성 세션의 수

이러한 메트릭을 통해 클러스터의 트래픽을 실시간으로 분석하고, 성능 문제를 조기에 감지할 수 있습니다.

NGINX Service Mesh의 OpenTracing 지원

NGINX Service Mesh는 NGINX OpenTracing 모듈을 통해 OpenTracing을 지원합니다. 

현재 이 모듈은 다음과 같은 분산 추적 시스템과 통합됩니다:

- Datadog 

- LightStep 

- Jaeger 

- Zipkin 

NGINX OpenTracing 모듈을 통해 마이크로서비스 간의 요청 흐름을 추적하고, 애플리케이션의 성능을 깊이 분석할 수 있습니다. 

이를 통해 서비스 간의 지연 시간, 오류 발생 지점 등을 시각적으로 파악할 수 있습니다.

리소스 부족 문제 해결

클러스터나 플랫폼의 리소스 부족 문제를 진단할 때, 다음과 같은 HTTP 오류 코드를 확인하는 것이 중요합니다:

  • 503 오류: 서버가 요청을 처리할 수 없는 상태를 나타내며, 주로 리소스 부족이나 서버 과부하를 의미합니다.
  • 40x 오류: 클라이언트 요청에 문제가 있음을 나타냅니다. 특히 404와 403 오류가 포함됩니다.
  • 502 오류: 게이트웨이 오류로, 서버 간의 통신 문제나 잘못된 구성 변경을 의미합니다.
  • 과거 데이터를 분석하여 리소스가 부족한 위치를 파악하고, 필요에 따라 리소스를 확장하거나 재구성할 수 있습니다.

NGINX Ingress Controller의 로깅 기능


네트워크 문제를 진단하는 첫 번째 단계는 NGINX Ingress Controller 로그를 확인하는 것입니다. 

이 로그에는 모든 로그 항목에 관련 Kubernetes 서비스가 주석으로 달려 있습니다. 오류에 관한 항목은 연관된 서비스를 식별합니다. 

로그에는 Ingress Controller를 통과한 모든 트래픽에 대한 자세한 정보가 포함되며, 타임스탬프, 소스 IP 주소 및 응답 상태 코드가 포함됩니다. 

또한, 로그를 Datadog, Grafana, Splunk와 같은 인기 있는 애그리게이터로 내보낼 수 있습니다.

Prometheus 메트릭

NGINX Ingress Controller의 가장 인기 있는 기능 중 하나는 

네트워크 성능 및 Ingress 컨트롤러 트래픽에 대한 메트릭을 포함하는 끊임없이 확장되는 Prometheus 메트릭 목록입니다. 

NGINX Plus를 사용하면 NGINX Ingress Controller는 NGINX 작업자 그룹이 처리하는 연결, 캐싱, 

HTTP 및 TCP/UDP 트래픽에 대한 메트릭을 내보냅니다. 

이 작업자 그룹은 메모리 영역에서 데이터를 공유하며, HTTP 및 TCP/UDP 트래픽은 백엔드 서버 그룹이 처리합니다.

NGINX Service Mesh는 NGINX Plus API를 사용하여 NGINX Service Mesh 사이드카와 

NGINX Ingress Controller 포드에서 메트릭을 스크래핑하는 Prometheus 서버를 배포합니다. 

기존 Prometheus 배포를 사용하려는 경우, Prometheus 구성 파일에 추가할 스크래핑 구성을 제공합니다.

Grafana 대시보드

우리는 NGINX Ingress Controller 및 NGINX Service Mesh에 대한 공식 Grafana 대시보드를 제공하여 

Prometheus Exporter에서 노출된 메트릭을 시각화합니다. 

사용자는 밀리초 단위의 세부 사항, 일별 오버레이 및 트래픽 급증 등을 포함하는 데이터의 세분성을 중요하게 생각합니다. 

예를 들어, NGINX Service Mesh 대시보드는 특정 서비스나 포드의 트래픽 양과 모니터링되는 활성 POD 수를 표시하여 포드가 용량에 도달했는지를 나타낼 수 있습니다.




위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요


전문가에게 상담받기


프로필 이미지
관리자
2024-09-12
조회 50


회사가 최신 앱 개발 기술을 제대로 활용하지 않는다는 신호는 고객의 소셜 미디어에서 불만이 쏟아지는 것과 같은 경우입니다. 

예를 들어, 사용자가 '비디오 재생 오류'에 대해 불평하거나, 온라인 뱅킹에 접속할 수 없거나, 장바구니가 시간 초과되는 등의 상황입니다. 

고객이 공개적으로 불만을 토로하지 않더라도, 그들의 나쁜 경험이 기업에 큰 영향을 미칠 수 있습니다. 

예를 들어, 한 대형 보험사는 자사의 홈페이지가 3초 이내에 로드되지 않으면 고객을 잃을 수 있다고 경고했습니다.

이러한 문제의 근본 원인은 애플리케이션의 복원력 부족에 있습니다. 

컨테이너와 Kubernetes를 활용한 마이크로서비스 아키텍처는 앱의 복원력을 개선하여 사용자 경험을 크게 향상시킬 수 있습니다. 

핵심은 아키텍처 설계에 있습니다.


모놀리식 vs. 마이크로서비스 아키텍처

모놀리식 아키텍처는 조명이 꺼지면 전체 조명이 어두워지는 전구 스트랜드와 비슷합니다. 

전구 하나가 고장나면 전체 시스템이 멈추는 것입니다. 

반면, 현대의 조명 시스템은 개별 전구가 꺼져도 나머지 전구가 계속 켜집니다. 

이는 잘 설계된 마이크로서비스 아키텍처와 같습니다. 

즉, 하나의 서비스가 실패하더라도 나머지 서비스는 계속 작동할 수 있습니다.


'비디오 재생 오류'에 대해 불평하는 트윗 이미지

쿠버네티스 트래픽 관리

컨테이너는 애플리케이션을 더 작고 개별적인 구성 요소로 나누어 빌드할 수 있게 해 주기 때문에 

마이크로서비스 아키텍처에서 매우 인기가 있습니다. 컨테이너는 가볍고, 이동이 용이하며, 확장성이 뛰어납니다. 

Kubernetes는 컨테이너 오케스트레이션의 사실상 표준으로 자리 잡았지만, 

이를 프로덕션 환경에서 효과적으로 사용하는 데는 여러 도전 과제가 있습니다. 

Kubernetes 앱의 제어와 복원력을 향상시키기 위한 중요한 요소 중 하나는 트래픽을 단순히 패킷이 아닌 서비스 단위로 관리하고, 

트래픽 관리 규칙을 동적으로 조정할 수 있는 성숙한 전략을 갖추는 것입니다. 

트래픽 관리의 중요성은 모든 아키텍처에서 공통적이지만, 

특히 고성능 앱에서는 두 가지 핵심 도구인 트래픽 제어트래픽 분할이 필수적입니다.

트래픽 제어 

트래픽 제어(일명 트래픽 라우팅 또는 트래픽 셰이핑)는 트래픽이 어디로 향하고 어떻게 도달할지를 조절하는 작업을 의미합니다. 

Kubernetes 환경에서 이러한 제어는 특히 중요합니다. 

이는 인프라와 애플리케이션을 공격이나 트래픽 급증으로부터 보호하는 데 필수적이기 때문입니다. 

트래픽 제어를 앱 개발 주기에 통합하는 방법에는 속도 제한과 회로 차단이 있습니다.

사례: 서비스에 과도한 요청이 들어오는 것을 방지하고 싶습니다.
솔루션: 속도 제한

속도 제한은 사용자가 특정 시간 동안 수행할 수 있는 요청 수를 제한하는 기술입니다. 

이는 악의적인 공격(예: 무차별 대입 공격, DDoS 공격)이나 비정상적으로 많은 요청(예: 세일 기간 동안 몰려드는 고객들)으로부터 

서비스를 보호하는 데 유용합니다. 

속도 제한을 설정하면, 대량의 요청이 들어와도 이를 필터링하여 실제 사용자에게 영향을 미치지 않도록 할 수 있습니다.

사례: 연쇄적인 실패를 방지하고 싶습니다.
솔루션: 회로 차단

서비스가 응답하지 않거나 지연될 경우, 클라이언트는 시간 초과 오류를 경험할 수 있으며, 

이는 연쇄적인 실패로 이어질 수 있습니다. 

연쇄적인 실패는 한 서비스의 중단이 다른 서비스의 시간 초과를 초래하고, 

결국 애플리케이션 전체의 실패로 이어질 수 있습니다. 

회로 차단기는 서비스의 실패를 모니터링하여 이러한 연쇄적 실패를 방지합니다. 

실패한 요청 수가 특정 임계값을 초과하면 회로 차단기가 활성화되어 요청을 즉시 거부하고, 

클라이언트에게 오류 응답을 반환함으로써 서비스에 대한 트래픽을 효과적으로 제한합니다. 

회로 차단기는 요청을 제한된 수만큼 허용하고, 이를 성공적으로 처리하면 트래픽 제한을 해제합니다. 

그렇지 않으면, 회로 차단기는 요청을 계속 거부하며 상태를 모니터링합니다.

트래픽 분할

트래픽 분할(또는 트래픽 테스트라고도 함)은 트래픽 제어의 하위 범주로, 

여러 버전의 백엔드 애플리케이션(일반적으로 현재 프로덕션 버전과 새로운 버전)으로 수신 트래픽의 비율을 조절하는 작업을 의미합니다. 

이는 새로운 기능이나 버전의 안정성을 고객에게 부정적인 영향을 주지 않으면서 테스트할 수 있는 방법을 제공합니다. 

일반적인 배포 시나리오로는 디버그 라우팅, 카나리아 배포, A/B 테스트, 블루-그린 배포 등이 있습니다.

사례: 프로덕션에서 새 버전을 테스트할 준비가 되었습니다.
솔루션: 디버그 라우팅

예를 들어, 은행 앱에 신용 점수 기능을 추가하려는 경우, 

고객과 공유하기 전에 이 기능의 성능을 프로덕션 환경에서 미리 보고 싶을 수 있습니다. 

디버그 라우팅을 사용하면, 특정 사용자만 새로운 기능에 접근할 수 있도록 설정할 수 있습니다. 

예를 들어, 관리자 세션 쿠키를 가진 사용자에게만 신용 점수 기능이 포함된 새로운 버전을 제공하고, 

다른 모든 사용자에게는 기존의 안정적인 버전을 계속 제공할 수 있습니다. 

이를 통해 실사용자에게 영향을 주지 않으면서 새로운 기능을 테스트할 수 있습니다.

Ingress 컨트롤러를 사용하여 트래픽을 분할하는 디버그 라우팅의 토폴로지 다이어그램

사례: 새 버전의 안정성을 검증해야 할 때

솔루션: 카나리아 배포


카나리아 배포는 역사적 광산 안전 관행에서 유래된 개념입니다. 

과거 석탄 광산에서는 독가스가 발생할 경우 카나리아가 먼저 피해를 입어 광부들이 위험을 감지할 수 있었습니다. 

현대 애플리케이션에서는 새 버전이 실제로 해를 입지는 않습니다! 

카나리아 배포는 새로운 기능이나 버전의 안정성을 테스트하기 위한 안전하고 유연한 방법을 제공합니다. 

일반적으로, 카나리아 배포는 안정적인 기존 버전이 전체 트래픽의 대부분(예: 99%)을 처리하도록 유지하면서, 

소수(예: 1%)의 트래픽만 새로운 버전으로 전환합니다. 

새 버전에서 문제가 발생하면(예: 충돌, 오류 응답) 즉시 해당 트래픽을 안정적인 버전으로 되돌릴 수 있습니다. 

새 버전이 성공적일 경우, 모든 사용자에게 새 버전을 배포할 수 있으며, 이는 즉시 전환하거나 점진적으로 진행할 수 있습니다.


Ingress 컨트롤러를 사용하여 트래픽을 분할하는 Canary 배포의 토폴로지 다이어그램

사례: 고객이 현재 버전보다 새 버전을 더 선호하는지 알아내고 싶을 때

솔루션: A/B 테스트

새로운 기능이 프로덕션 환경에서 정상적으로 작동하는 것을 확인한 후, A/B 테스트를 통해 고객의 피드백을 받아볼 수 있습니다. 

A/B 테스트는 사용자 행동을 측정하여 다양한 제품 또는 앱 버전의 상대적인 성공을 판단하는 방법입니다. 

일반적으로, A/B 테스트에서는 사용자 그룹의 50%가 현재 버전(A)을 사용하고, 나머지 50%는 새로운 기능이 포함된 버전(B)을 사용합니다. 

KPI(핵심 성과 지표)가 더 우수한 버전이 승자로 간주됩니다.

ceb5c47774dcf.jpeg

사례: 다운타임 없이 사용자를 새 버전으로 전환하고 싶을 때

솔루션: 블루-그린 배포

예를 들어, 뱅킹 앱의 주요 버전 업데이트를 고려해 보겠습니다. 

과거에는 버전 업그레이드가 사용자에게 다운타임을 발생시켰습니다. 

새로운 버전을 프로덕션에 배포하기 전에 기존 버전을 삭제해야 했기 때문입니다. 

그러나 오늘날 경쟁적인 환경에서는 다운타임이 거의 용납되지 않습니다. 

블루-그린 배포는 다운타임을 크게 줄이거나 완전히 제거할 수 있는 방법입니다. 

기존 버전(블루)을 프로덕션에 유지하면서 동시에 새 버전(그린)을 배포합니다. 

대부분의 조직은 100%의 사용자를 한 번에 새 버전으로 전환하지 않으려 합니다. 

만약 새 버전에서 문제가 발생하면 어떻게 될까요? 

카나리아 배포를 사용하여 점진적으로 사용자를 새 버전으로 이동시켜 위험을 최소화할 수 있습니다. 

문제가 발생하면 빠르게 기존 버전으로 복구할 수 있습니다.

Ingress 컨트롤러를 사용하여 트래픽을 분할하는 블루-그린 배포의 토폴로지 다이어그램

NGINX가 어떻게 도움이 되는지

고급 트래픽 제어와 분할을 위해 Ingress 컨트롤러와 서비스 메시를 사용할 수 있습니다. 

어떤 기술을 선택할지는 애플리케이션 아키텍처와 사용 사례에 따라 다릅니다. 

Ingress 컨트롤러는 다음과 같은 경우 유용할 수 있습니다:

  • 애플리케이션이 단일 엔드포인트를 가진 간단한 앱이거나, Kubernetes로 "리프트 앤 시프트"된 모놀리식 앱인 경우
  • 클러스터 내에서 서비스 간 통신이 없는 경우
  • 서비스 간 통신이 있지만 아직 서비스 메시를 사용하지 않는 경우

서비스 메시가 필요한 복잡한 배포에서는, 개별 마이크로서비스의 테스트 또는 업그레이드를 위해 

서비스 간에 트래픽을 분할하는 것이 일반적입니다. 

예를 들어, 모바일 프런트엔드 뒤에 두 가지 버전의 지리적 위치 마이크로서비스 API 간에 카나리아 배포를 수행할 수 있습니다.

그러나 일부 Ingress 컨트롤러와 서비스 메시를 설정하는 데는 시간이 많이 걸리고 오류가 발생할 수 있습니다.

이유는 다음과 같습니다:

  • 다양한 공급업체의 Ingress 컨트롤러와 서비스 메시가 Kubernetes 기능을 다르게 구현합니다.
  • Kubernetes는 7계층 트래픽을 관리하고 이해하기 위해 설계되지 않았습니다.
  • 일부 Ingress 컨트롤러와 서비스 메시가 정교한 트래픽 관리를 지원하지 않습니다.

NGINX Ingress Controller와 NGINX Service Mesh를 사용하면 강력한 트래픽 라우팅 및 분할 정책을 쉽게 구성할 수 있습니다. 

NGINX Ingress Controller와 NGINX Service Mesh를 활용하면, 몇 초 만에 설정을 완료하고, 

고급 사용자 정의와 향상된 가시성으로 시간을 절약할 수 있습니다.

NGINX Ingress 리소스를 사용하면 구성이 보다 간편해집니다.

NGINX Ingress Controller는 표준 Kubernetes Ingress 리소스 외에도 NGINX Ingress 리소스를 제공하여, 

SSL/TLS 종료, HTTP 로드 밸런싱, 레이어 7 라우팅을 간소화합니다. 

이는 NGINX 사용자가 기존 로드 밸런서 구성을 재사용할 수 있게 합니다.

**SMI(Specification for Service Mesh Interface)**를 사용한 NGINX 서비스 메시도 유용합니다. 

SMI는 Kubernetes에서 서비스 메시에 대한 표준 인터페이스를 정의하며, 

이를 통해 카나리아 배포와 같은 트래픽 분할 정책을 쉽게 구현할 수 있습니다. 

예를 들어, NGINX 서비스 메시로 카나리아 배포를 설정하는 방법을 통해 최소한의 중단으로 프로덕션 트래픽을 배포할 수 있습니다.


NGINX Ingress 리소스 및 SMI 사양을 사용한 더 쉬운 구성

이러한 NGINX 기능은 구성을 보다 쉽게 만듭니다.

  • NGINX Ingress Controller용 NGINX Ingress 리소스  - 

    NGINX Ingress Controller를 사용할 때 표준 Kubernetes Ingress 리소스는 SSL/TLS 종료, HTTP 로드 밸런싱, 레이어 7 라우팅 등의 기본 기능을 제공하지만, 회로 차단, A/B 테스트, 블루-그린 배포와 같은 고급 사용자 정의 기능은 포함되어 있지 않습니다. NGINX 사용자는 주석, ConfigMaps, 사용자 정의 템플릿 등을 사용하여 이러한 기능을 구현해야 하는데, 이 방법들은 세부적인 제어가 부족하고, 보안 문제를 일으킬 수 있으며, 오류가 발생하기 쉬운 점이 있습니다.

    반면, NGINX Ingress 리소스는 표준 Ingress 리소스의 대안으로 제공됩니다. 이 리소스는 네이티브하고 타입 안전성이 높은 구성 스타일을 제공하여 Ingress 로드 밸런싱을 단순화합니다. NGINX Ingress 리소스를 사용하면 기존 NGINX 환경에서 로드 밸런싱 구성을 재사용할 수 있어, 모든 NGINX 로드 밸런서가 일관된 구성을 사용할 수 있습니다.

  • SMI를 사용한 NGINX 서비스 메시  – NGINX 서비스 메시는 Kubernetes에서 서비스 메시에 대한 표준 인터페이스를 정의하는 SMI(Specification for Service Mesh Interface) 사양을 구현합니다. SMI는 TrafficSplit, TrafficTarget, HTTPRouteGroup 등과 같은 형식화된 리소스를 제공합니다. 이를 통해 NGINX 서비스 메시와 SMI는 카나리아 배포와 같은 트래픽 분할 정책을 프로덕션 트래픽을 최소한으로 중단하여 쉽게 배포할 수 있도록 도와줍니다. 예를 들어, 카나리아 배포를 NGINX 서비스 메시로 정의하는 방법은 다음과 같습니다: 

    apiVersion: split.smi-spec.io/v1alpha2kind: TrafficSplit
    metadata:
    name: target-ts
    spec:
    service: target-svc
    backends:
    - service: target-v1-0    weight: 90
    - service: target-v2-0    weight: 10

    이러한 접근법을 통해 트래픽 제어 및 분할을 효과적으로 수행하면서도 간편하게 구성할 수 있습니다.


고급 사용자 정의를 통한 정교한 트래픽 제어 및 분할

NGINX의 다양한 기능을 활용하면 트래픽을 정교하게 제어하고 분할할 수 있습니다.

카나리아 배포를 위한 키-값 저장소


A/B 테스트나 블루-그린 배포를 진행할 때, 

트래픽을 단계적으로 새 버전으로 전환하는 작업(예: 0%, 5%, 10%, 25%, 50%, 100%)은 

일반적으로 수동적인 과정이 필요합니다. 

각 단계에서 백분율을 수정하고 구성 파일을 다시 로드해야 하기 때문입니다. 

이로 인해 5%에서 100%로의 급격한 전환을 감수할 수도 있습니다. 

그러나 NGINX Plus 기반의 NGINX Ingress Controller를 사용하면, 

키-값 저장소를 통해 백분율을 동적으로 조정할 수 있으며,

이 과정에서 구성 파일을 다시 로드할 필요가 없습니다.


NGINX Ingress Controller를 통한 회로 차단

정교한 회로 차단기는 장애를 신속하게 감지하고 대응하며, 

상태가 좋지 않은 업스트림에 대해 사용자 정의 오류 페이지를 설정하여 시간을 절약하고 시스템 복원력을 향상시킬 수 있습니다. 

예를 들어, 검색 서비스의 회로 차단기는 비어 있는 검색 결과 집합을 반환하도록 설정할 수 있습니다.

NGINX Plus 기반의 NGINX Ingress Controller는 TCP 및 UDP 업스트림 서버의 상태를 사전에 모니터링하는 

활성 상태 검사를 제공하여 클라이언트가 오류를 경험할 가능성을 줄입니다.

NGINX 서비스 메시를 통한 회로 차단
NGINX 서비스 메시의 회로 차단기 사양에는 다음과 같은 세 가지 사용자 정의 필드가 포함됩니다:

  • errors: 회로가 트립되기 전 허용되는 오류 수
  • timeoutSeconds: 회로가 트립되기 전 오류가 발생할 수 있는 시간 창과 회로를 닫기 전에 기다리는 시간
  • fallback: 회로가 트립된 후 트래픽이 다시 라우팅되는 Kubernetes 서비스의 이름과 포트

errors와 timeoutSeconds는 표준 회로 차단기 기능을 제공하며, fallback을 통해 백업 서버를 정의함으로써 복원력을 더욱 강화할 수 있습니다. 

백업 서버에서의 응답이 클러스터의 문제를 조기에 나타내는 지표가 될 수 있어, 문제 해결을 신속하게 시작할 수 있습니다.


대시보드를 통한 트래픽 분할 결과 분석

트래픽 분할을 구현한 후, 결과 분석이 필요합니다. 

많은 조직이 Kubernetes 트래픽과 애플리케이션 성과에 대한 중요한 통찰력을 놓치는 경우가 많습니다. 

NGINX는 Prometheus Exporter에서 노출된 메트릭을 시각화할 수 있는 

NGINX Plus 대시보드와 사전 구축된 Grafana 대시보드를 제공하여 이러한 통찰력을 보다 쉽게 얻을 수 있도록 돕습니다. 

Kubernetes에서 가시성을 개선하는 방법에 대한 자세한 내용은 블로그를 참조하세요.


NGINX로 마이크로서비스 마스터하기

NGINX Plus 기반의 NGINX Ingress Controller는 NGINX App Protect가 포함된 30일 무료 평가판을 제공하며, 

이를 통해 컨테이너화된 애플리케이션을 보호할 수 있습니다. 

NGINX 오픈 소스의 NGINX Ingress Controller를 사용해 보려면 

릴리스 소스 코드를 다운로드하거나 DockerHub에서 미리 빌드된 컨테이너를 받으세요.

또한, NGINX 서비스 메시는 항상 무료로 제공되며, f5.com에서 다운로드할 수 있습니다.




프로필 이미지
관리자
2024-09-02
조회 224


NGINX가 현대 애플리케이션의 요구 계층을 지원하는 방법

표준 Kubernetes Ingress 리소스는 기본적인 Ingress 로드 밸런싱을 프로비저닝하고 구성하는 데 유용하지만, 

Kubernetes를 프로덕션 등급으로 만들기 위해 필요한 맞춤화 기능은 포함되어 있지 않습니다. 

대신, 비-NGINX 사용자는 주석, ConfigMaps 및 맞춤 템플릿을 사용해야 하는데, 


이는 오류가 발생하기 쉽고, 사용하기 어려우며, 보안이 부족하고 세밀한 범위 설정이 부족합니다. 

NGINX Ingress 리소스는 이러한 문제에 대한 우리의 해결책입니다.

NGINX Ingress 리소스는 NGINX Open Source 및 NGINX Plus 기반의 NGINX Ingress Controller 버전 모두에서 사용할 수 있습니다. 


이 리소스는 기본적인, 타입-안전하며 의도된 구성 스타일을 제공하여 Ingress 로드 밸런싱 구현을 간소화합니다. 

이 블로그에서는 NGINX Ingress Controller 1.11.0에서 도입된 

두 가지 기능에 중점을 두어 WAF 및 로드 밸런싱 정책 구성을 쉽게 할 수 있도록 합니다:


TransportServer 리소스 – TransportServer 리소스는 TCP, UDP, TLS Passthrough 로드 밸런싱 구성을 정의합니다. 

우리는 TCP/UDP 로드 밸런싱을 향상시키기 위해 헬스 체크, 상태 보고 및 구성 스니펫을 추가했습니다.

 NGINX Ingress WAF 정책 – NGINX App Protect 3.0을 NGINX Ingress Controller와 함께 배포하면, 

NGINX Ingress 리소스를 활용하여 특정 Kubernetes 서비스에 WAF 정책을 적용할 수 있습니다.


TransportServer 스니펫

NGINX Ingress Controller에서는 VirtualServer 및 VirtualServerRoute (VS 및 VSR) 리소스에 대해 구성 스니펫을 도입했습니다. 

이는 HTTP 기반 클라이언트를 위한 NGINX Ingress 구성을 네이티브로 확장할 수 있게 해 줍니다. 

1.11.0 릴리스에서는 TS 리소스에 대한 스니펫을 도입하여 TCP/UDP 기반 서비스를 제공할 수 있는 

NGINX 및 NGINX Plus의 전체 기능을 쉽게 활용할 수 있습니다. 

예를 들어, IP 주소 및 범위를 사용하여 서비스에 접근할 수 있는 클라이언트를 정의하는 deny 및 allow 지시어를 추가할 수 있습니다.

TransportServer 리소스의 향상 사항

NGINX Ingress Controller 1.11.0은 다음 영역에서 TransportServer (TS) 리소스를 확장합니다:

  • 스니펫(Snippets)
  • 헬스 체크(Health checks)
  • 여러 TS 리소스 지원

참고: TransportServer 리소스에 대한 추가 사항은 1.11.0 릴리스에서 기술 미리보기 상태이며, 

향후 릴리스에서 안정적이고 프로덕션 준비가 완료된 품질 기준으로 승격될 것입니다.

TransportServer Snippets

NGINX Ingress Controller에서는 VirtualServer 및 VirtualServerRoute (VS 및 VSR) 리소스에 대해 구성 스니펫을 도입했습니다. 

이는 HTTP 기반 클라이언트를 위한 NGINX Ingress 구성을 네이티브로 확장할 수 있게 해 줍니다. 

1.11.0 릴리스에서는 TS 리소스에 대한 스니펫을 도입하여 TCP/UDP 기반 서비스를 제공할 수 있는 

NGINX 및 NGINX Plus의 전체 기능을 쉽게 활용할 수 있습니다.

 예를 들어, IP 주소 및 범위를 사용하여 서비스에 접근할 수 있는 클라이언트를 정의하는 deny 및 allow 지시어를 추가할 수 있습니다.

apiVersion: k8s.nginx.org/v1alpha1
kind: TransportServer
metadata:
  name: cafe
spec:
  host: cafe.example.com
  serverSnippets: |
    deny 192.168.1.1;
    allow 192.168.1.0/24;
  upstreams:
  - name: tea
    service: tea-svc
    port: 80

Health Checks


Kubernetes 클러스터의 상태를 모니터링하기 위해 NGINX Ingress Controller는 

애플리케이션 포드에 로컬로 적용된 Kubernetes 프로브만 고려하지 않고, 

TCP/UDP 기반의 업스트림 서비스 간 네트워크 상태도 지속적으로 점검합니다. 

패시브 헬스 체크를 통해 전송 중인 트랜잭션의 건강 상태를 평가하고, 

액티브 헬스 체크(NGINX Plus 전용)를 통해 엔드포인트를 주기적으로 탐색합니다.

헬스 체크는 회로 차단 및 애플리케이션 오류 처리에 매우 유용할 수 있습니다. 

TS 리소스의 healthCheck 필드를 사용하여 프로브 간 간격, 프로브 타임아웃, 프로브 간 지연 시간 등을 설정하여

 헬스 체크를 사용자 정의할 수 있습니다.

또한, NGINX Ingress Controller에서 헬스 프로브의 업스트림 서비스 및 포트 대상을 설정할 수 있습니다. 

이는 업스트림 애플리케이션의 건강 상태가 다른 프로세스나 서브시스템에 의해 다른 리스너에서 노출되는 상황에서 유용합니다.


IngressClassName을 통한 여러 TransportServer 리소스 지원

TS 리소스를 업데이트하고 적용할 때, 구성이 유효한지 및 해당 Ingress Controller 배포에 성공적으로 적용되었는지 

확인하는 것이 유용합니다. 1.11.0 릴리스에서는 TS 리소스에 대해 ingressClassName 필드와 상태 보고를 도입했습니다. 

ingressClassName 필드는 여러 배포가 있는 환경에서 TS 리소스가 특정 Ingress Controller 배포에 의해 처리되도록 보장합니다.

TS 리소스의 상태를 표시하려면 kubectl get transportserver 명령을 실행하십시오. 


출력에는 상태(유효 또는 무효), 가장 최근 업데이트의 이유, 그리고 (단일 TS의 경우) 사용자 정의 메시지가 포함됩니다

$ kubectl get transportserver
NAME      STATE   REASON           AGE
dns-tcp   Valid   AddedOrUpdated   47m

$ kubectl describe transportserver dns-tcp
. . .
Status:
  Message:  Configuration for default/dns-tcp was added or updated
  Reason:   AddedOrUpdated
  State:    Valid 

여러 TS 리소스가 동일한 호스트/리스너를 경쟁할 경우, 

NGINX Ingress Controller는 가장 오래된 타임스탬프를 가진 TS 리소스를 선택하여 결과를 결정합니다.


NGINX App Protect 지원을 통한 WAF 정책 정의

NGINX Ingress 리소스는 구성 작업을 더 쉽고 유연하게 만들 뿐만 아니라, 트래픽 제어를 다양한 팀에 위임하고 

VirtualServerRoute (VSR) 리소스에서 정의된 애플리케이션 하위 경로에 대한 엄격한 권한 제한을 적용할 수 있게 해줍니다. 

올바른 팀에 적절한 Kubernetes 리소스에 대한 액세스를 부여함으로써, 

NGINX Ingress 리소스는 네트워킹 리소스에 대한 세밀한 제어를 가능하게 하고, 

사용자가 침해되거나 해킹될 경우 애플리케이션의 잠재적 피해를 줄일 수 있습니다.

1.11.0 릴리스에서는 Kubernetes 배포에서 NGINX App Protect의 구성을 확장하기 위해 

네이티브 웹 애플리케이션 방화벽(WAF) 정책 객체를 도입했습니다. 

이 정책은 1.8.0 릴리스에서 도입된 APLogConf 및 APPolicy 객체를 활용하며, 

VirtualServer (VS) 및 VSR 리소스 모두에 첨부할 수 있습니다. 




이는 보안 관리자가 VS 리소스를 통해 Ingress 구성의 전체 범위를 소유할 수 있도록 하면서, 

VSR 리소스를 참조하여 다른 팀에 보안 책임을 위임할 수 있게 해줍니다.

apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
  name: webapp
spec:
  host: webapp.example.com
  policies:
  - name: waf-prod
  tls:
    secret: app-secret
  upstreams:
  - name: webapp-prod
    service: webapp-svc
    port: 80
  routes:
  - path: /v2
    route: test/test
  - path: /v1
    action:
      pass: webapp-prod

다음 예제에서는 waf-prod 정책이 webapp-prod 업스트림으로 라우팅되는 사용자에게 적용됩니다. 

다른 네임스페이스에 걸쳐 /v2 경로에 대한 보안 책임을 위임하기 위해, 강조된 경로 지시어가 VSR 리소스를 참조합니다..

apiVersion: k8s.nginx.org/v1
kind: VirtualServerRoute
metadata:
  name: test
  namespace: test
spec:
  host: webapp.example.com
  upstreams:
  - name: webapp
    service: webapp-test-svc
    port: 80
  subroutes:
  - path: /v2
    policies:
    - name: waf-test
    action:
      pass: webapp

이 예제는 네임스페이스별로 테넌트를 분리하고,

test 네임스페이스의 webapp-test-svc 서비스에 대해 다른 WAF 정책을 적용합니다. 


이는 리소스를 다른 팀에 위임하고 객체로 캡슐화하여 프로덕션 애플리케이션을 방해하지 않고

새로운 기능을 테스트할 수 있는 방법을 보여줍니다.

릴리스 1.11.0의 추가 사항은 무엇인가요?

NGINX Ingress Controller 1.11.0 릴리스는 유연하고 강력하며 

사용하기 쉬운 프로덕션 등급의 Ingress 컨트롤러를 제공하겠다는 

우리의 약속을 지속적으로 이행합니다. 

WAF 및 TS 개선 사항 외에도, 1.11.0 릴리스는 다음과 같은 향상을 포함하고 있습니다:

- 주석의 추가 검증 – 더 많은 구성 오류 방지
- 정책 상태 정보 – 정책 객체의 상태를 표시하여 Ingress 구성에 적용하기 전 확인
- Istio 호환성 – Istio 환경에서 NGINX Ingress Controller의 고급 기능 활용
- 업스트림 엔드포인트의 클러스터-IP 주소 – NGINX Ingress Controller 구성에 서비스/클러스터-IP 주소로 업스트림 엔드포인트 채우기

주석의 추가 검증

릴리스 1.10.0에서 주석 검증 개선에 이어, 이제 다음과 같은 추가 주석을 검증하고 있습니다:

AnnotationValidation

nginx.org/client-max-body-sizeMust be a valid offset
nginx.org/fail-timeoutMust be a valid time
nginx.org/max-connsMust be a valid non‑negative integer
nginx.org/max-failsMust be a valid non‑negative integer
nginx.org/proxy-buffer-sizeMust be a valid size
nginx.org/proxy-buffersMust be a valid proxy buffer spec
nginx.org/proxy-connect-timeoutMust be a valid time
nginx.org/proxy-max-temp-file-sizeMust be a valid size
nginx.org/proxy-read-timeoutMust be a valid time
nginx.org/proxy-send-timeoutMust be a valid time
nginx.org/upstream-zone-sizeMust be a valid size

주석의 값이 유효하지 않으면, Ingress 리소스가 적용될 때

Ingress Controller는 리소스를 거부하고 해당 구성 항목을 NGINX에서 제거합니다.


Status Information about Policies

kubectl get policy 명령을 사용하여 정책의 상태(유효 또는 무효) 및 (단일 TS의 경우) 

사용자 정의 메시지 및 가장 최근 업데이트의 이유를 보고할 수 있습니다.

$ kubectl get policy
NAME              STATE   AGE
webapp-policy     Valid   30s

$ kubectl describe policy webapp-policy
. . .
Status:
  Message:  Configuration for default/webapp-policy was added or updated
  Reason:   AddedOrUpdated
  State:    Valid

Compatibility with Istio


NGINX Ingress Controller는 이제 Istio 서비스 메시 내부에서 실행되는 앱의 Ingress 컨트롤러로 사용할 수 있습니다. 

이를 통해 사용자는 NGINX Ingress Controller가 제공하는 

고급 기능을 Istio 기반 환경에서도 계속 사용할 수 있습니다. 

이 통합에는 두 가지 요구 사항이 있습니다:

  • Istio 사이드카를 NGINX Ingress Controller 배포에 주입하기
  • 백엔드로 전송되는 HTTP Host 헤더가 하나만 있어야 함

첫 번째 요구 사항을 충족하려면 NGINX Ingress Deployment 파일의 주석 필드에 다음 항목을 포함하십시오

annotations:
  traffic.sidecar.istio.io/includeInboundPorts: ""
  traffic.sidecar.istio.io/excludeInboundPorts: "80,443"
  traffic.sidecar.istio.io/excludeOutboundIPRanges: "10.90.0.0/16,10.45.0.0/16"
  sidecar.istio.io/inject: 'true'

두 번째 요구 사항은 requestHeaders 필드의 동작을 변경하여 달성됩니다. 

이전 릴리스에서는 다음 구성으로 두 개의 Host 헤더가 백엔드로 전송되었습니다: $host와 지정된 값인 bar.example.com. 

apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
  name: foo
spec:
  host: foo.example.com
  upstreams:
  - name: foo
    port: 8080
    service: backend-svc
    use-cluster-ip: true
  routes:
  - path: "/"
    action:
      proxy:
        upstream: foo
        requestHeaders:
          set:
          - name: Host
            value: bar.example.com

릴리스 1.11.0 이후로는 지정된 값만 전송됩니다. $host를 보내려면 requestHeaders 필드를 생략하십시오.

Cluster-IP Addresses for Upstream Endpoints

NGINX Ingress Controller 구성에서 업스트림 엔드포인트를 개별 포드 엔드포인트의 IP 주소 대신 

서비스/클러스터-IP 주소로 채울 수 있습니다. 

NGINX Ingress Controller가 Cluster-IP 서비스로 트래픽을 라우팅할 수 있도록 하려면,

 VS 또는 VSR 구성의 upstreams 섹션에 use-cluster-ip: true 필드를 포함하십시오:

upstreams:
- name: tea
  service: tea-svc
  port: 80
  use-cluster-ip: true
- name: coffee
  service: coffee-svc
  port: 80
  use-cluster-ip: true




위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요




프로필 이미지
관리자
2024-08-29
조회 245


서비스 메시가 실제로 Kubernetes 환경을 관리하는 것을 더 복잡하게 만들 수 있는 방법 중 하나는 

Ingress 컨트롤러 와 별도로 구성해야 하는 경우입니다 . 


별도의 구성은 시간 소모적일 뿐만 아니라, 적절한 트래픽 라우팅을 방해하고 

심지어 보안 취약성(예: 악의적인 행위자가 제한된 앱에 액세스)과 열악한 경험(예: 고객이 권한이 있는 앱에 액세스할 수 없음)으로 

이어질 수 있는 구성 오류의 가능성을 높입니다. 

별도의 구성을 수행하는 데 걸리는 시간 외에도 오류 문제 해결에 더 많은 시간을 소비하게 됩니다.


NGINX Plus 기반 NGINX Ingress Controller를 NGINX Service Mesh 와 통합하여 

인그레스와 이그레스 mTLS 트래픽을 모두 제어하면 이러한 문제를 피하고 시간을 절약할 수 있습니다 .



필수 조건
1. NGINX 서비스 메시를 사용하여 NGINX Ingress Controller 배포
2. 표준 Kubernetes Ingress 리소스를 사용하여 앱 노출
3. NGINX VirtualServer 리소스를 사용하여 앱 노출
4. NGINX Ingress Controller를 사용하여 보안 Egress 경로 구성


필수 조건 (0:18)

실제 데모를 시작하기 전에, 다음과 같은 전제조건을 갖고 착수했습니다. 

1. Kubernetes 클러스터에 NGINX Server Mesh 제어 평면을 설치 하고 mTLS와 서비스 메시에 대한 정책을 설정했습니다 strict .
2. Kubernetes 클러스터에 NGINX Plus 기반 NGINX Ingress Controller를 DaemonSet이 아닌 배포로 설치하고 egress를 활성화 하고 유형의 서비스로 노출했습니다 LoadBalancer .
참고: 데모는 NGINX 오픈 소스 기반 NGINX Ingress Controller와 함께 작동하지 않습니다. 읽기 편하도록 이 블로그의 나머지 부분에서는 NGINX Plus 기반 NGINX Ingress Controller를 간단히 "NGINX Ingress Controller"라고 합니다.
3. 지침에 따라 샘플 bookinfo앱을 다운로드하고 NGINX 서비스 메시 사이드카를 주입한 다음 앱을 배포했습니다.


strict1 단계에서 만든 정책 의 결과로 bookinfo메시 외부의 클라이언트에서 앱으로의 요청은 사이드카에서 거부됩니다. 데모에서 다음 명령을 먼저 실행하여 포트 포워딩을 설정하여 이를 설명합니다.

> kubectl port-forward svc/product-page 9080Forwarding from 127.0.0.1:9080 -> 9080
Forwarding from [::1]:9080 -> 9080
Handling connection for 9080

앱에 액세스하려고 하면  503로컬 머신이 서비스 메시의 일부가 아니기 때문에 상태 코드가 표시됩니다.

> curl localhost:9080503

NGINX 서비스 메시를 사용하여 NGINX Ingress Controller 배포(1:50)

앱을 노출하는 프로세스의 첫 번째 단계는 NGINX Ingress Controller 인스턴스를 배포하는 것입니다. 

해당 지침은 튜토리얼 Deploy with NGINX Plus Ingress Controller for Kubernetes 에서 제공됩니다 .

NGINX는 이 목적을 위해 Deployment와 DaemonSet 매니페스트를 모두 제공합니다. 

데모에서는 Deployment 매니페스트인 nginx-plus-ingress.yaml을 사용합니다. 

여기에는 동일한 NGINX Ingress Controller 인스턴스를 통해 인그레스와 이그레스 트래픽을 

모두 라우팅하는 주석이 포함되어 있습니다.


1        nsm.nginx.com/enable-ingress: "true"
2        nsm.nginx.com/enable-egress: "true"
view rawnginx-plus-ingress.yaml hosted with ❤ by GitHub

매니페스트는 NGINX Ingress Controller를 NGINX Service Mesh의 인증 기관(CA)인 Spire와 

직접 통합할 수 있게 하므로 NGINX Ingress Controller에 NGINX Service Mesh 사이드카를 주입할 필요가 없습니다. 

대신 NGINX Ingress Controller는 Spire CA에서 직접 인증서와 키를 가져와 메시의 포드와 함께 mTLS에 사용합니다. 

매니페스트는 Spire 에이전트 주소를 지정합니다.


1        args:
2          - -spire-agent-address=/run/spire/sockets/agent.sock
view rawnginx-plus-ingress.yaml hosted with ❤ by GitHub

그리고 Spire 에이전트 UNIX 소켓을 NGINX Ingress Controller Pod에 마운트합니다.


1      volumes:
2      - hostPath:
3          path: /run/spire/sockets
4          type: DirectoryOrCreate
5        name: spire-agent-socket
view rawnginx-plus-ingress.yaml hosted with ❤ by GitHub

매니페스트에 대해 주목해야 할 마지막 사항은 -enable-internal-routesCLI 인수로, 

이를 통해 송신 서비스로 라우팅할 수 있습니다.


1        args:
2          - -enable-internal-routes
view rawnginx-plus-ingress.yaml hosted with ❤ by GitHub


데모를 시작하기 전에 NGINX Ingress Controller를 설치

 kubectl apply -f nginx-plus-ingress.yaml 하는 명령을 실행했고 , 

이 시점에서 네임스페이스에서 배포를 검사합니다 . 


다음 출력의 열에 표시된 대로 NGINX Ingress Controller 포드에 대한 컨테이너는 하나뿐입니다. 

NGINX Service Mesh 사이드카를 주입하지 않았기 때문입니다.nginx-ingressREADY

또한 클러스터 외부의 NGINX Ingress Controller(여기서는 35.233.133.188)의 

외부 IP 주소를 노출하는 유형의 서비스를 배포했습니다. 


해당 IP 주소에서 LoadBalancer샘플 애플리케이션에 액세스합니다 .bookinfo


 kubectl get pods '--namespace=nginx-ingressNAME                                 
READY   STATUS    RESTARTS   AGE
pod/nginx-ingress-867f954b8f0fzdrm   1/1     Running   0          3d3h

NAME                    TYPE           CLUSTER-IP      EXTERNAL-IP      ...
service-nginx-ingress   LoadBalancer   10.31.245.207   35.233.133.188   ...

      ... PORT(S)                      AGE
      ... 80:31469/TCP,443:32481/TCP   4d2h
...

표준 Kubernetes Ingress 리소스를 사용하여 앱 노출(3:55)

이제 bookinfo-ingress.yamlbookinfo 에 정의된 표준 Kubernetes Ingress 리소스를 사용하여 

메시에서 앱을 노출합니다 . 

해당 지침은 튜토리얼 NGINX Plus Ingress Controller로 애플리케이션 노출에 제공됩니다 .


1apiVersion: networking.k8s.io/v1beta1
2kind: Ingress
3metadata:
4  name: bookinfo-ingress
5
6spec:
7  ingressClassName: nginx # use only with k8s version &gt= 1.18.0
8  tls:
9  - hosts:
10    - bookinfo.example.com
11    secretName: bookinfo-secret
12  rules:
13  - host: bookinfo.example.com
14    http:
15      paths:
16      - path: /
17        backend:
18          serviceName: productpage
19          servicePort: 9080
view rawbookinfo-ingress.yaml hosted with ❤ by GitHub

리소스는 10번째 줄에서 앱에 대한 Kubernetes Secret을 참조 하고 bookinfo.example.com 에 대한 요청이 

서비스 로 전송되도록 bookinfo지정하는 라우팅 규칙을 포함합니다 ( 11~18번째 줄 ). 

Secret은 bookinfo-secret.yaml 에 정의되어 있습니다 .productpage


1apiVersion: v1
2kind: Secret
3metadata:
4  name: bookinfo-secret
5type: kubernetes.io/tls
6data:
7  tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURMakNDQWhZQ0NRREFPRjl0THNhWFdqQU5CZ2txaGtpRzl3MEJBUXNGQURCYU1Rc3dDUVlEVlFRR0V3SlYKVXpFTE1Ba0dBMVVFQ0F3Q1EwRXhJVEFmQmdOVkJBb01HRWx1ZEdWeWJtVjBJRmRwWkdkcGRITWdVSFI1SUV4MApaREViTUJrR0ExVUVBd3dTWTJGbVpTNWxlR0Z0Y0d4bExtTnZiU0FnTUI0WERURTRNRGt4TWpFMk1UVXpOVm9YCkRUSXpNRGt4TVRFMk1UVXpOVm93V0RFTE1Ba0dBMVVFQmhNQ1ZWTXhDekFKQmdOVkJBZ01Ba05CTVNFd0h3WUQKVlFRS0RCaEpiblJsY201bGRDQlhhV1JuYVhSeklGQjBlU0JNZEdReEdUQVhCZ05WQkFNTUVHTmhabVV1WlhoaApiWEJzWlM1amIyMHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDcDZLbjdzeTgxCnAwanVKL2N5ayt2Q0FtbHNmanRGTTJtdVpOSzBLdGVjcUcyZmpXUWI1NXhRMVlGQTJYT1N3SEFZdlNkd0kyaloKcnVXOHFYWENMMnJiNENaQ0Z4d3BWRUNyY3hkam0zdGVWaVJYVnNZSW1tSkhQUFN5UWdwaW9iczl4N0RsTGM2SQpCQTBaalVPeWwwUHFHOVNKZXhNVjczV0lJYTVyRFZTRjJyNGtTa2JBajREY2o3TFhlRmxWWEgySTVYd1hDcHRDCm42N0pDZzQyZitrOHdnemNSVnA4WFprWldaVmp3cTlSVUtEWG1GQjJZeU4xWEVXZFowZXdSdUtZVUpsc202OTIKc2tPcktRajB2a29QbjQxRUUvK1RhVkVwcUxUUm9VWTNyemc3RGtkemZkQml6Rk8yZHNQTkZ4MkNXMGpYa05MdgpLbzI1Q1pyT2hYQUhBZ01CQUFFd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFLSEZDY3lPalp2b0hzd1VCTWRMClJkSEliMzgzcFdGeW5acS9MdVVvdnNWQTU4QjBDZzdCRWZ5NXZXVlZycTVSSWt2NGxaODFOMjl4MjFkMUpINnIKalNuUXgrRFhDTy9USkVWNWxTQ1VwSUd6RVVZYVVQZ1J5anNNL05VZENKOHVIVmhaSitTNkZBK0NuT0Q5cm4yaQpaQmVQQ0k1ckh3RVh3bm5sOHl3aWozdnZRNXpISXV5QmdsV3IvUXl1aTlmalBwd1dVdlVtNG52NVNNRzl6Q1Y3ClBwdXd2dWF0cWpPMTIwOEJqZkUvY1pISWc4SHc5bXZXOXg5QytJUU1JTURFN2IvZzZPY0s3TEdUTHdsRnh2QTgKN1dqRWVxdW5heUlwaE1oS1JYVmYxTjM0OWVOOThFejM4Zk9USFRQYmRKakZBL1BjQytHeW1lK2lHdDVPUWRGaAp5UkU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
8  tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBcWVpcCs3TXZOYWRJN2lmM01wUHJ3Z0pwYkg0N1JUTnBybVRTdENyWG5LaHRuNDFrCkcrZWNVTldCUU5semtzQndHTDBuY0NObzJhN2x2S2wxd2k5cTIrQW1RaGNjS1ZSQXEzTVhZNXQ3WGxZa1YxYkcKQ0pwaVJ6ejBza0lLWXFHN1BjZXc1UzNPaUFRTkdZMURzcGRENmh2VWlYc1RGZTkxaUNHdWF3MVVoZHErSkVwRwp3SStBM0kreTEzaFpWVng5aU9WOEZ3cWJRcCt1eVFvT05uL3BQTUlNM0VWYWZGMlpHVm1WWThLdlVWQ2cxNWhRCmRtTWpkVnhGbldkSHNFYmltRkNaYkp1dmRySkRxeWtJOUw1S0Q1K05SQlAvazJsUkthaTAwYUZHTjY4NE93NUgKYzMzUVlzeFR0bmJEelJjZGdsdEkxNURTN3lxTnVRbWF6b1Z3QndJREFRQUJBb0lCQVFDUFNkU1luUXRTUHlxbApGZlZGcFRPc29PWVJoZjhzSStpYkZ4SU91UmF1V2VoaEp4ZG01Uk9ScEF6bUNMeUw1VmhqdEptZTIyM2dMcncyCk45OUVqVUtiL1ZPbVp1RHNCYzZvQ0Y2UU5SNThkejhjbk9SVGV3Y290c0pSMXBuMWhobG5SNUhxSkpCSmFzazEKWkVuVVFmY1hackw5NGxvOUpIM0UrVXFqbzFGRnM4eHhFOHdvUEJxalpzVjdwUlVaZ0MzTGh4bndMU0V4eUZvNApjeGI5U09HNU9tQUpvelN0Rm9RMkdKT2VzOHJKNXFmZHZ5dGdnOXhiTGFRTC94MGtwUTYyQm9GTUJEZHFPZVBXCktmUDV6WjYvMDcvdnBqNDh5QTFRMzJQem9idWJzQkxkM0tjbjMyamZtMUU3cHJ0V2wrSmVPRmlPem5CUUZKYk4KNHFQVlJ6NWhBb0dCQU50V3l4aE5DU0x1NFArWGdLeWNrbGpKNkY1NjY4Zk5qNUN6Z0ZScUowOXpuMFRsc05ybwpGVExaY3hEcW5SM0hQWU00MkpFUmgySi9xREZaeW5SUW8zY2czb2VpdlVkQlZHWTgrRkkxVzBxZHViL0w5K3l1CmVkT1pUUTVYbUdHcDZyNmpleHltY0ppbS9Pc0IzWm5ZT3BPcmxEN1NQbUJ2ek5MazRNRjZneGJYQW9HQkFNWk8KMHA2SGJCbWNQMHRqRlhmY0tFNzdJbUxtMHNBRzR1SG9VeDBlUGovMnFyblRuT0JCTkU0TXZnRHVUSnp5K2NhVQprOFJxbWRIQ2JIelRlNmZ6WXEvOWl0OHNaNzdLVk4xcWtiSWN1YytSVHhBOW5OaDFUanNSbmU3NFowajFGQ0xrCmhIY3FIMHJpN1BZU0tIVEU4RnZGQ3haWWRidUI4NENtWmlodnhicFJBb0dBSWJqcWFNWVBUWXVrbENkYTVTNzkKWVNGSjFKelplMUtqYS8vdER3MXpGY2dWQ0thMzFqQXdjaXowZi9sU1JxM0hTMUdHR21lemhQVlRpcUxmZVpxYwpSMGlLYmhnYk9jVlZrSkozSzB5QXlLd1BUdW14S0haNnpJbVpTMGMwYW0rUlk5WUdxNVQ3WXJ6cHpjZnZwaU9VCmZmZTNSeUZUN2NmQ21mb09oREN0enVrQ2dZQjMwb0xDMVJMRk9ycW40M3ZDUzUxemM1em9ZNDR1QnpzcHd3WU4KVHd2UC9FeFdNZjNWSnJEakJDSCtULzZzeXNlUGJKRUltbHpNK0l3eXRGcEFOZmlJWEV0LzQ4WGY2ME54OGdXTQp1SHl4Wlp4L05LdER3MFY4dlgxUE9ucTJBNWVpS2ErOGpSQVJZS0pMWU5kZkR1d29seHZHNmJaaGtQaS80RXRUCjNZMThzUUtCZ0h0S2JrKzdsTkpWZXN3WEU1Y1VHNkVEVXNEZS8yVWE3ZlhwN0ZjanFCRW9hcDFMU3crNlRYcDAKWmdybUtFOEFSek00NytFSkhVdmlpcS9udXBFMTVnMGtKVzNzeWhwVTl6WkxPN2x0QjBLSWtPOVpSY21Vam84UQpjcExsSE1BcWJMSjhXWUdKQ2toaVd4eWFsNmhZVHlXWTRjVmtDMHh0VGwvaFVFOUllTktvCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
view rawbookinfo-secret.yaml hosted with ❤ by GitHub


데모에서는 자체 서명된 키와 인증서를 로드하려면 다음 명령을 실행합니다.

> kubectl apply -f bookinfo-secret.yamlsecret/bookinfo-secret unchanged

Ingress 리소스를 활성화합니다.

> kubectl apply -f bookinfo-ingress.yamlingress.networking.k8s.io/bookinfo-ingress deleted

그리고 출력 끝의 이벤트에서 확인된 대로 Ingress Controller가 

리소스에 정의된 경로를 추가했는지 확인합니다.

>  kubectl describe ingress bookinfo-ingress...
Events:
  Type    Reason          Age   From                      Message
  ----    ------          ----  ----                      -------
  Normal  AddedOrUpdated  5s    nginx-ingress-controller  Configuration for ...
        ...default/bookinfo-ingress was added or updated

데모에서는 이제 브라우저를 사용하여 https://bookinfo.example.com/bookinfo 에서 앱에 액세스합니다. 

(이전에 로컬 /etc/hosts 파일에 Ingress Controller 서비스의 IP 주소(데모에서는 위에 언급된 대로 35.233.133.188)와 

bookinfo.example.com 간의 매핑을 추가했습니다 . 지침은 설명서 를 참조하세요.) 

페이지의 Book Reviews 섹션 에 있는 정보는 bookinfo.yaml 에 정의된 서비스의 

세 가지 버전을 통해 요청이 순환함에 따라 주기적으로 변경됩니다 ( 다운로드 ).reviews

다음으로 클러스터로의 인그레스 트래픽을 검사합니다. 

generate-traffic.shproductpage 스크립트를 실행하여 

NGINX Ingress Controller의 공개 IP 주소를 통해 서비스 에 요청을 한 다음 

nginx-meshctl top명령을 실행하여 트래픽을 모니터링합니다.


> > nginxmesh-ctl top deploy/productpage-v1Deployment       Direction  Resource       Success Rate  P99    P90    P50   ...
productpage-v1  
                 To         details-v1     100.00%       3ms    3ms    2ms   
                 To         reviews-v2     100.00%       99ms   90ms   20ms
                 To         reviews-v3     100.00%       99ms   85ms   18ms
                 To         reviews-v1     100.00%       20ms   17ms   9ms
                 From       nginx-ingress  100.00%       192ms  120ms  38ms

      ... NumRequests 
      ... 14
      ... 5
      ... 5
      ... 12

NGINX VirtualServer 리소스를 사용하여 앱 노출(6:45)

다음으로 NGINX VirtualServer 리소스를 사용하여 앱을 노출하는 대체 방법을 보여드리겠습니다. 

이는 트래픽 분할 및 콘텐츠 기반 라우팅과 같은 보다 

복잡한 트래픽 처리를 지원하는 사용자 지정 NGINX Ingress Controller 리소스입니다.

먼저 표준 Ingress 리소스를 삭제합니다.

> kubectl delete -f bookinfo-ingress.yamlingress.networking.k8s.io "bookinfo-ingress" deleted

bookinfo -vs.yaml 파일은 bookinfo-ingress.yaml ( 7-8행 ) 과 동일한 Secret으로 mTLS를 구성합니다 . 

9-12행은productpage 서비스를 업스트림으로 정의하고 , 

13-24행은 bookinfo.example.comGET 에서 수행된 모든 요청을 해당 업스트림으로 보내는 경로를 정의합니다. 

이외의 HTTP 메서드의 경우 상태 코드를 반환합니다  .GET405


1apiVersion: k8s.nginx.org/v1
2kind: VirtualServer
3metadata:
4  name: bookinfo-vs
5spec:
6  host: bookinfo.example.com
7  tls:
8    secret: bookinfo-secret
9  upstreams:
10  - name: product
11    service: productpage
12    port: 9080
13  routes:
14  - path: /
15    matches:
16    - conditions:    
`17      - variable: $request_method
18        value: GET
19      action:
20        pass: product
21    action:
22     return:
23       code: 405
24       body: "Method not allowed\n"
view rawbookinfo-vs.yaml hosted with ❤ by GitHub

우리는 리소스를 적용합니다:

> kubectl apply -f bookinfo-vs.yamlvirtualserver.kubernetes.nginx.org/bookinfo-vs created

그런 다음 Ingress 리소스와 동일한 단계를 수행합니다. 

즉, kubectl describe올바른 배포를 확인하기 위해 명령을 실행하고 브라우저에서 앱에 액세스합니다. 

앱이 올바르게 작동한다는 또 다른 확인은 메서드를 거부한다는 것입니다 POST.


> curl -k -X POST https://bookinfo.example.com/Method not allowed

NGINX Ingress Controller를 사용하여 보안 Egress 경로 구성(8:44)

이제 NGINX Ingress Controller를 통해 egress 트래픽을 라우팅하는 방법을 보여드리겠습니다. 

NGINX Plus Ingress Controller로 보안 egress 경로 구성 튜토리얼은 다양한 샘플 앱을 사용하여 프로세스를 다룹니다.

우리는 이미 bash.yamlbash 에서 간단한 포드를 정의 하고 요청을 보내는 기본 네임스페이스에 배포했습니다. 

이 출력의 열에 표시된 대로 NGINX Service Mesh 사이드카로 주입되었습니다.READY

>> kubectl get allNAME                        READY  STATUS    RESTARTS   AGE
pod/bash-6ccb678958-zsgm7   2/2    Running   0          77s

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.31.240.1           443/TCP   4d2h
....

포드 내부에서 NGINX 서비스 메시에 속하지 않는 모든 엔터티인 Igress 서비스 로의 요청을 활성화하려는 

사용 사례가 여러 가지 있습니다 . 배포된 서비스의 예는 다음과 같습니다.

 - 클러스터 외부
- 다른 클러스터에서
- 동일한 클러스터에 있지만 NGINX 서비스 메시 사이드카로 주입되지 않음


데모에서는 최종 사용 사례를 고려하고 있습니다. 

legacyNGINX Service Mesh에서 제어하지 않고 NGINX Service Mesh 사이드카의 자동 주입이 

비활성화된 네임스페이스에 배포된 애플리케이션이 있습니다. 앱에서 실행되는 포드는 하나뿐입니다.

>> kubectl get all --namespaces=legacyNAME                          READY  STATUS    RESTARTS   AGE
pod/target-5f7bcb96c6-km9lz   1/1    Running   0          27m

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/target-svc   ClusterIP   10.31.245.213           80/TCP,443/TCP   27m

NGINX 서비스 메시에 mTLS 정책을 구성했다는 점을 기억하세요 strict. 

그 결과 포드에서 bash대상 서비스로 직접 요청을 보낼 수 없습니다. 

둘이 서로 인증할 수 없기 때문입니다. 시도하면  503여기에 설명된 대로 상태 코드가 표시됩니다.

> kubectl exec -it bash-6ccb678958-zsgm7 -c bash -- curl target-svc.legacycurl: (56) Recv failure: connection reset by peer
503command terminated with exit code 56

해결책은 포드가 NGINX Ingress Controller를 통해 egress 트래픽을 보낼 수 있도록 하는 것입니다 . 

bash.yaml 의 14~15번째 줄bash 에 있는 주석의 주석을 해제합니다 .


1      #annotations:
2        #config.nsm.nginx.com/default-egress-allowed: "true" # uncomment to route egress traffic to NGINX Ingress Controller
view rawbash.yaml hosted with ❤ by GitHub


그런 다음 새로운 구성을 적용합니다.

> kubectl apply -f bash.yamldeployment.apps/bash configured

새로운 bash포드가 재배포 되었는지 확인하세요.

> kubectl get podsNAME READY  STATUS RESTARTS AGE 
bash-678c8b4579-7sfml  2/2  Running 0 6s 
bash-6ccb678958-zsgm7 2/2 Terminating 0 3m28s

kubectl exec이제 이전과 같은 명령을 실행하여 bash포드에서 대상 서비스로 

요청을 보내면 404 대신 상태 코드가 표시됩니다 503. 

이는 bash포드가 NGINX Ingress Controller로 요청을 성공적으로 보냈지만 

후자는 경로가 정의되지 않았기 때문에 어디로 전달해야 할지 모른다는 것을 나타냅니다.

다음 Ingress 리소스 정의를 legacy-route.yaml 에 사용하여 필요한 경로를 만듭니다 . 

internal-route7번째 줄의 주석은 대상 서비스가 인터넷에 노출되지 않고 

NGINX Service Mesh 내의 워크로드 에만 노출된다는 것을 의미합니다.


1apiVersion: networking.k8s.io/v1beta1
2kind: Ingress
3metadata:
4  name: target-internal-route
5  namespace: legacy
6  annotations: 
7    nsm.nginx.com/internal-route: "true"
8spec:
9  ingressClassName: nginx # use only with k8s version &gt= 1.18.0
10  tls:
11  rules:
12  - host: target-svc.legacy
13    https:
14      paths:
15      - path: /
16        backend:
17          serviceName: target-svc
18          servicePort: 80
view rawlegacy-route.yaml hosted with ❤ by GitHub


새 리소스를 활성화하고 NGINX Ingress Controller가 리소스에 정의된 경로를 추가했는지 확인합니다.

> kubectl apply -f legacy-route.yamlingress.networking.k8s.io/target-internal-route created
> kubectl describe ingress target-internal-route -n legacy
...
Events:
  Type    Reason          Age   From                      Message
  ----    ------          ----  ----                      -------
  Normal  AddedOrUpdated  6s    nginx-ingress-controller  Configuration for ...
        ...legacy/target-internal-route was added or updated

이제 명령을 실행하면 kubectl exec대상 서비스에 도달합니다.

{"req": {"method": "GET"  "url": "/",  
         "host": "target-svc.legacy", 
          "remoteAddr": "10.28.2.76:56086"}}

NGINX Ingress Controller를 통해 송신 트래픽을 라우팅하는 이점은 클러스터 내부에서 

어떤 외부 서비스에 접근할 수 있는지 정확하게 제어할 수 있다는 것입니다. 

즉, 경로를 정의한 서비스에만 해당됩니다.

데모에서 보여드릴 마지막 사항은 이탈 트래픽을 모니터링하는 방법입니다. 

kubectl exec여러 요청을 보내는 명령을 실행한 다음 이 명령을 실행합니다.

> > nginxmesh-ctl top deploy/nginx-ingress -n nginx-ingressDeployment      
Direction  Resource  Success Rate  P99  P90  P50  NumRequests
nginx-ingress  
                To         target    100.00%       1ms  1ms  1ms  9
                From       bash      100.00%       0ms  0ms  0ms  9

지연에 대해 "NO"라고 하세요  

NGINX Ingress Controller로 NGINX 서비스 메시를 시도하세요

많은 서비스 메시가 인그레스 및 이그레스 게이트웨이 옵션을 제공하지만, 

NGINX 통합의 추가 이점인 낮은 지연 시간을 높이 평가하실 것으로 생각합니다. 

대부분의 메시는 인그레스 컨트롤러에 사이드카를 주입해야 하며, 

이를 위해 트래픽이 앱으로 가는 길에 추가 홉을 만들어야 합니다. 

몇 초가 중요하며, 디지털 경험을 느리게 하는 추가 홉으로 인해 고객이 다른 곳으로 전환할 수 있습니다. 

NGINX Service Mesh는 NGINX Ingress Controller에 사이드카를 주입하지 않으므로 

불필요한 지연 시간을 추가하지 않습니다. 

대신 메시의 CA인 Spire와 직접 통합하여 NGINX Ingress Controller가 NGINX Service Mesh의 일부가 됩니다. 

NGINX Ingress Controller는 Spire 에이전트에서 인증서와 키를 간단히 가져와서 

메시된 포드와 mTLS 인증서 교환에 참여하는 데 사용합니다.

 Kubernetes용 NGINX Ingress Controller에는 NGINX Open Source와 NGINX Plus의 두 가지 버전이 있습니다. 

이 블로그에 설명된 대로 NGINX Service Mesh와 함께 NGINX Ingress Controller를 배포하려면 

30일 무료 평가판 으로 제공되는 NGINX Plus 버전을 사용해야 합니다 .

NGINX Service Mesh는 완전 무료이며 즉시 다운로드 할 수 있으며 

10분 이내에 배포할 수 있습니다! 시작하려면 문서를 확인 하고 GitHub을 통해 진행 상황을 알려주세요 .


위 내용과 같이 NGINX 솔루션을 활용한 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요



전문가에게 상담받기

프로필 이미지
관리자
2024-08-16
조회 105


NGINX에서는 끊임없이 소프트웨어를 최대한 활용할 수 있는 방법을 모색하고 있습니다. 

솔루션 브리핑과 사이징 가이드는 우리가 제공하는 중요한 리소스 중 하나입니다. 

다양한 수준의 컴퓨팅 파워에서 기대할 수 있는 성능을 경험적으로 테스트하여 

이미 보유한 인프라로 애플리케이션 성능 제공을 극대화하고, 

준비하고 있는 성능과 규모에 대한 정확한 운영 비용을 결정하는 데 도움을 드립니다.

최근 Amazon Elastic Kubernetes Service(EKS)에 대한 사이징 가이드라인으로 NGINX Ingress Controller 솔루션 브리핑을 업데이트했습니다. 

이 브리핑은 Amazon EKS의 다양한 인스턴스 유형에서 실행되는 

NGINX Ingress Controller로 달성할 수 있는 성능과 추정 월간 총 소유 비용(TCO)을 설명합니다. 

이 블로그에서는 이러한 숫자를 도출한 방법을 설명하며, 직접 유사한 테스트를 수행하는 데 필요한 모든 정보도 포함합니다.

토폴로지

다음 다이어그램은 테스트에 사용된 토폴로지를 보여줍니다.

Amazon Elastic Kubernetes Service(EKS)에서 NGINX Plus Ingress Controller 성능 테스트를 위한 토폴로지


  • Admin 은 다음 섹션에 지정된 명령을 실행하여 테스트를 수행하는 사용자입니다.
  • Amazon ECR(Elastic Container Registry)은 테스트에 사용된 공식 NGINX Plus Ingress Controller Docker 이미지를 호스팅합니다. NGINX Plus Ingress Controller 배포를 참조하세요.
  • Amazon EC2(Elastic Compute Cloud)는 wrk가 실행되는 c5n.9xlarge 이미지를 호스팅하여 요청을 생성합니다. 테스트 방법론을 참조하세요.
  • Amazon EKS(Elastic Kubernetes Service)는 NGINX Plus Ingress Controller와 백엔드 애플리케이션에 대한 c5n.9xlarge 이미지를 호스팅합니다. Amazon EKS 클러스터 생성을 참조하세요.
  • NGINX Plus Ingress Controller는 wrk에서 생성된 요청을 백엔드 애플리케이션으로 프록시하고 애플리케이션의 응답을 반환합니다. NGINX Plus Ingress Controller 배포를 참조하세요.
  • Backend Application 은 NGINX에서 프록시된 요청에 응답합니다. 백엔드 포드 배포를 참조하세요.
Amazon EKS 클러스터 생성

EKS 클러스터를 배포하기 전에 다이어그램에서 관리자 아이콘으로 표현된 로컬 컴퓨터에서 다음 단계를 수행합니다.

  1. Amazon EKS의 공식 명령줄 인터페이스인 eksctl을 다운로드하세요. 컴퓨터에 이미 eksctl이 설치되어 있는 경우 최신 버전으로 업데이트하세요.
  2. ${HOME}/.aws/credentials 파일에 적절한 AWS 관리자 자격 증명을 추가합니다.
  3. Gist 저장소에서 이 블로그의 YAML 파일을 다운로드하세요.
  4. GitHub의 NGINX Ingress Controller 저장소에서 rbac.yaml(NGINX App Protect를 사용하는 경우 ap-rbac.yaml)을 다운로드합니다.

EKS 클러스터를 배포하려면 로컬 머신에서 다음 eksctl 명령을 실행합니다. (--nodes 플래그는 생략합니다. 기본적으로 이 명령은 테스트에 필요한 두 개의 노드를 생성하기 때문입니다. 하나는 NGINX Plus Ingress Controller용이고 다른 하나는 기본 백엔드 애플리케이션용입니다.)

참고: us-west-1이 아닌 다른 모든 지역에 EKS 클러스터를 배포할 수 있습니다. Amazon Marketplace for Containers(다음 섹션 참조)에서 NGINX Plus Ingress Controller 이미지를 구독하는 것은 해당 지역에서 지원되지 않습니다.

# eksctl create cluster --instance-types=c5n.9xlarge --managed --ssh-access=true --ssh-public-key=/path/to/public-key

SSH를 통해 클러스터 노드에 연결하려면 이 명령을 실행합니다. 테스트하는 동안 NGINX Plus Ingress Controller 노드에 연결하여 htop 명령을 실행하고 wrk 클라이언트의 부하가 노드의 CPU 사용량을 100%로 끌어올리기에 충분한지 확인해야 합니다.

# ssh -i /path/to/private-key ec2-user@ >

NGINX Plus Ingress Controller 배포

이제 Amazon EKS에 NGINX Plus Ingress Controller를 배포하는 것이 그 어느 때보다 쉬워졌습니다.

  1. EKS 클러스터에 대한 OIDC ID 공급자(IdP)를 생성합니다.

    # eksctl utils associate-iam-oidc-provider --region= --cluster= > --approve
    
  2. EKS의 표준 페어링된 IAM 역할 및 서비스 계정(IRSA)인 iamserviceaccount를 만들고 NGINX Plus Ingress Controller 이미지 사용을 모니터링하고 배포를 승인하기 위한 AWSMarketplaceMeteringRegisterUsage IAM 정책을 연결합니다. 이 명령은 iamserviceaccount에 연결되는 주석이 있는 서비스 계정을 자동으로 만듭니다.

    # eksctl create iamserviceaccount --name  --namespace nginx-ingress --cluster  --region  --attach-policy-arn arn:aws:iam::aws:policy/AWSMarketplaceMeteringRegisterUsage --approve
  3. RBAC용 YAML 파일에서 이전 단계에서 설정한 service-account-name과 일치하도록 subjects 필드의 name 값을 편집합니다. 이는 rbac.yaml의 104번째 줄과 ap-rbac.yaml의 23번째 줄에 있습니다. 또한 필요한 경우 namespace 값(105번째 줄 또는 24번째 줄)도 편집하지만 위의 명령은 기본값인 nginx-ingress를 사용합니다.

  4. YAML 파일을 적용합니다(적절한 경우 ap-rbac.yaml로 대체).

    # kubectl apply  –-f rbac.yaml
  5. 로컬 머신에 Docker 클라이언트 소프트웨어를 설치합니다.

  6. Amazon Marketplace for Containers에서 NGINX Plus Ingress Controller(프리미엄 에디션) 목록을 구독하세요.

  7. NGINX Plus Ingress Controller Docker 이미지를 호스팅하는 Amazon ECR로 Docker 클라이언트를 인증합니다.

  8. nginx-ingress.yaml에서 다음 값을 편집하세요.

    • nodeSelector 필드의 kubernetes.io/hostname(23번째 줄) – kubectl get nodes --show-labels 명령에서 얻은 EKS 클러스터의 NGINX Plus Ingress Controller 노드에 대한 레이블
    • serviceAccountName(24번째 줄) - 2단계에서 service-account-name으로 지정된 iamserviceaccount IRSA의 이름입니다.
    • 컨테이너 필드의 이미지(라인 26) – Amazon ECR의 NGINX Plus Ingress Controller Docker 이미지 위치
  9. YAML 매니페스트를 적용합니다.

    # kubectl apply  –-f nginx-ingress.yaml

백엔드 Pod 배포

백엔드 애플리케이션을 배포하려면 다음 단계를 수행하세요.

  1. backend-deployment.yaml에서 nodeSelector 필드(15번째 줄)의 kubernetes.io/hostname 값을 편집하여 kubectl get nodes --show-labels 명령에서 얻은 레이블을 대체합니다.

  2. YAML 매니페스트를 적용합니다.

    # kubectl apply  –-f backend-deployment.yaml 
  3. wrk에서 생성된 부하를 처리할 수 있을 만큼 백엔드 애플리케이션을 최대 3개의 복제본으로 확장합니다.

    # kubectl scale deployment web-server-payload --replicas=3

테스트 방법론

Amazon EC2에 호스팅된 클라이언트 c5n.9xlarge AMI에서 다음 wrk 명령을 실행하고 각 테스트 실행에서 NGINX Plus Ingress Controller 인스턴스의 CPU 사용률이 100%에 도달하도록 필요에 따라 값을 조정합니다.

# wrk -t  -c  -d 180s http[s]://<address-of-NGINX-Plus-Ingress-Controller>
  • –c 옵션은 생성할 TCP 연결 수를 지정합니다. 이 옵션을 필요에 따라 설정하여 최대 500개 연결까지 100% CPU 사용량을 달성합니다.
  • –d 옵션은 트래픽을 생성하는 기간(각 테스트 실행 기간)을 지정합니다. 이 옵션을 180초(3분)로 설정합니다.
  • –t 옵션은 생성할 스레드 수를 지정합니다. 이 옵션을 필요에 따라 설정하여 최대 16개의 스레드(테스트 실행 중 클라이언트에서 사용되는 각 CPU당 하나씩)까지 100% CPU 사용을 달성합니다.
  1. 우리는 2021년 7월 기준 GitHub에서 제공되는 wrk 버전을 사용했으며, 테스트를 재현할 때는 현재 버전을 사용할 것을 권장합니다.

    두 가지 성능 지표를 수집하기 위해 테스트를 실행합니다.

    • 초당 요청(RPS) – NGINX Plus Ingress Controller가 초당 처리할 수 있는 요청 수로, 고정된 기간 동안 평균화합니다. 이 경우 wrk 명령에서 http:// 스킴을 사용합니다.

      NGINX Plus Ingress Controller는 1KB 파일(정적 콘텐츠)에 대한 요청을 수락하고 백엔드 애플리케이션 포드에 걸쳐 로드 밸런싱합니다. 파일 크기는 작은 CSS 또는 JavaScript 파일이나 매우 작은 이미지 크기와 비슷합니다.

    • 초당 SSL/TLS 트랜잭션(TPS) – NGINX Plus Ingress Controller가 초당 설정하고 제공할 수 있는 새로운 HTTPS 연결 수입니다. 이 경우 wrk 명령에서 https:// 스킴을 사용합니다. 2048비트 키 크기와 완벽한 순방향 비밀성을 갖춘 RSA를 사용합니다. SSL 암호는 ECDHE-RSA-AES256-GCM-SHA384입니다.

      클라이언트는 일련의 HTTPS 요청을 각각 새 연결로 보냅니다. 클라이언트와 NGINX Plus Ingress Controller는 TLS 핸드셰이크를 수행하여 보안 연결을 설정한 다음 NGINX Plus Ingress Controller가 요청을 구문 분석하고 0‑KB 응답을 반환합니다. 요청이 충족되면 연결이 닫힙니다.

Amazon EKS 클러스터 생성에서 언급했듯이, 단순성을 위해 모든 테스트 실행에서 c5n.9xlarge 인스턴스에서 NGINX Plus Ingress Controller를 실행할 수 있습니다. 각 테스트 실행 중에 사용 가능한 CPU 수를 제어하려면(성능 분석의 표에 지정된 대로 1~36) 매개변수를 worker_processes 지시문으로 설정합니다.

사용된 소프트웨어

우리는 테스트를 위해 다음 소프트웨어를 사용했습니다.

  • wrk를 실행하는 클라이언트 머신은 Ingress Controller가 프록시한 트래픽을 생성했습니다. 우리는 2021년 7월 GitHub에서 사용 가능한 wrk 버전을 사용했으며 테스트를 재현할 때 현재 버전을 사용하는 것이 좋습니다.
  • NGINX Plus Ingress Controller 버전 1.11.0
  • Amazon Linux 2 LTS는 OpenSSL 1.0.2k–fips를 사용하여 세 대의 모든 머신에서 실행되었습니다.

성과 분석

위에서 언급했듯이, 우리는 모든 테스트 실행에서 c5n.9xlarge 인스턴스에서 NGINX Plus Ingress Controller를 실행했으며, worker_processes 지시문을 사용하여 사용된 CPU 수를 제어했습니다. 아래 표에서 우리는 각 CPU 수를 지원하는 c5n 패밀리의 인스턴스 유형과 해당 인스턴스 유형의 월별 TCO를 보고합니다.

이 표는 테스트 방법론에 설명된 테스트를 통해 NGINX Plus Ingress Controller에서 사용 가능한 CPU 수에 따라 달성한 RPS 및 SSL TPS 수를 보고합니다.

RPS는 CPU 수가 많아질수록 선형적으로 증가하지 않으며, 실제로 CPU 수가 많아질수록 개선 비율이 감소하는 경향이 있습니다. 

c5n.9xlarge 인스턴스는 하이퍼스레딩이 활성화되어 있고 코어당 18개와 스레드 2개가 장착되어 

총 36개 CPU까지 사용할 수 있기 때문에 개선 속도는 16개 코어를 넘어 더욱 떨어집니다. 하이퍼스레딩은 RPS 수를 약간만 개선합니다.

SSL TPS와 CPU 수 사이의 관계도 선형적이지 않지만 16개 CPU를 넘어 확장할 때까지는 극적으로 떨어지지 않습니다. 

하이퍼스레딩은 TLS 핸드셰이크와 같은 CPU 바운드 병렬화 가능한 작업의 성능을 개선합니다. 

이 때문에 SSL TPS의 성능은 18개 CPU를 넘어 확장하더라도 증가합니다.


AWS Instance Type
CPUsRPSSSL TPS (RSA)Average Monthly TCO
c5n.large145,0006,700$100
c5n.large280,00012,600$100
c5n.xlarge4135,00023,000$200
c5n.2xlarge8175,00040,000$400
c5n.4xlarge16237,00068,500$795
c5n.9xlarge32290,00088,800$1790
c5n.9xlarge36300,00092,800$1790

결론

Amazon EKS에서 실행되는 NGINX Plus Ingress Controller의 예상 성능을 결정하는 데 사용할 수 있는 배포 세부 정보를 제공했습니다. 

이를 사용하여 다른 EKS 인스턴스 패밀리를 테스트하고 Kubernetes에서 프로덕션 워크로드에 대한 성능 및 확장 요구 사항을 충족하는 

가성비 있는 솔루션을 프로비저닝 할 수 있습니다.


HTTP RPS에 대한 결과는 CPU 수를 두 배로 늘리면 성능 향상 비율이 감소하여 약 300,000 RPS로 수렴한다는 것을 보여줍니다. 

SSL TPS에 대한 결과는 CPU 수를 두 배로 늘리면 성능이 거의 선형적으로 증가한다는 것을 보여줍니다. 

TLS 핸드셰이크는 CPU에 얽매이기 때문에 하이퍼스레딩(코어당 두 개의 스레드 사용)을 시작하더라도 마찬가지입니다.


솔루션 간략서를 확인하고 NGINX Plus Ingress Controller의 성능을 직접 테스트해 보세요. 오늘 시작하세요!

NGINX 오픈 소스로 NGINX Ingress Controller를 사용해 보려면 소스 코드를 얻거나 DockerHub에서 미리 빌드된 컨테이너를 다운로드하세요.



위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요



전문가에게 상담받기