파트 1: OpenResty를 사용하여 마이크로서비스 API 게이트웨이를 구축하는 방법
API7.ai
January 20, 2023
이번 글에서는 OpenResty를 활용한 실습 챕터로 넘어가 보겠습니다. 저는 세 개의 챕터를 통해 마이크로서비스 API 게이트웨이를 구현하는 방법을 소개할 예정입니다. 이 과정에서 우리는 이전에 배운 OpenResty 지식을 활용할 뿐만 아니라, 산업, 제품, 기술 선택 등 다양한 차원에서 새로운 제품과 오픈소스 프로젝트를 처음부터 구축하는 방법도 보여드리겠습니다.
마이크로서비스 API 게이트웨이는 무엇을 하나요?
먼저 마이크로서비스 API 게이트웨이의 역할을 살펴보겠습니다. 아래 그림은 간략한 설명입니다:
알다시피, API 게이트웨이는 새로운 개념이 아닙니다. 10년 이상 전부터 존재해 왔으며, 주로 트래픽의 입구 역할을 하며 비즈니스 관련 요청을 통합적으로 처리합니다. 이를 통해 요청을 더 안전하고 빠르며 정확하게 처리할 수 있습니다. API 게이트웨이의 전통적인 기능은 다음과 같습니다:
- 리버스 프록시와 로드 밸런싱: NGINX의 위치와 기능과 일치합니다.
- 동적 기능: 동적 업스트림, 동적 SSL 인증서, 런타임에서의 동적 트래픽 및 속도 제한 등은 오픈소스 NGINX 버전에는 없는 기능입니다.
- 업스트림의 활성 및 수동 상태 점검, 서비스 서킷 브레이커.
- API 게이트웨이를 기반으로 확장하여 전체 라이프사이클 API 관리 플랫폼으로 발전.
최근 몇 년 동안 비즈니스 관련 트래픽은 더 이상 PC 클라이언트와 브라우저에서만 발생하지 않으며, 모바일과 IoT 기기에서 더 많이 발생합니다. 앞으로 5G가 보급되면 이러한 트래픽은 더욱 증가할 것입니다. 동시에 마이크로서비스 아키텍처 구조가 변화함에 따라 서비스 간 트래픽도 폭발적으로 증가하기 시작했습니다. 이러한 새로운 비즈니스 시나리오에서 API 게이트웨이의 더 많은 고급 기능이 자연스럽게 등장했습니다:
- 클라우드 네이티브 친화적: 아키텍처가 경량화되고 컨테이너화하기 쉬워야 합니다.
Prometheus
,Zipkin
,SkyWalking
등의 통계 및 모니터링 컴포넌트와 연동.gRPC
프록시 지원,HTTP
와gRPC
간의 프로토콜 변환, 사용자의HTTP
요청을 내부 서비스gRPC
요청으로 변환.- OpenID Relying Party 역할 수행, Auth0 및 Okta와 같은 인증 제공자의 서비스와 연결, 트래픽 보안을 최우선으로 처리.
- 런타임에서 사용자 함수를 동적으로 실행하여 Serverless 구현, 게이트웨이의 에지 노드를 더 유연하게 만듦.
- 사용자를 잠그지 않고 하이브리드 클라우드 배포 아키텍처 지원.
- 게이트웨이 노드는 상태를 유지하지 않아야 하며, 자유롭게 확장 및 축소 가능.
마이크로서비스 API 게이트웨이가 위와 같은 기능을 갖추면, 사용자의 서비스는 비즈니스 자체에만 집중할 수 있습니다. 비즈니스 구현과 무관한 기능들은 독립적인 게이트웨이 레벨에서 해결할 수 있습니다. 예를 들어, 서비스 발견, 서킷 브레이커, 인증, 속도 제한, 통계, 성능 분석 등이 있습니다.
이러한 관점에서 API 게이트웨이는 NGINX의 모든 기능을 대체하고 남북 트래픽을 처리할 수 있으며, Istio
컨트롤 플레인과 Envoy
데이터 플레인의 역할을 수행하여 동서 트래픽을 처리할 수도 있습니다.
왜 새로운 바퀴를 발명하나요?
마이크로서비스 API 게이트웨이의 중요성 때문에 이 분야는 항상 치열한 경쟁의 장이었고, 전통적인 IT 대기업들도 오랫동안 이 분야에서 활동해 왔습니다. Gartner가 2018년에 발표한 API 라이프사이클 보고서에 따르면, Google, CA, IBM, Red Hat, Salesforce 등이 선두 기업이며, 개발자들에게 더 친숙한 Apache APISIX는 비전리어로 분류되었습니다.
그렇다면, 왜 우리는 새로운 바퀴를 발명해야 할까요?
간단히 말해, 현재의 마이크로서비스 API 게이트웨이 중 우리의 요구를 충족시킬 수 있는 제품이 없기 때문입니다. 먼저 폐쇄형 상용 제품을 살펴보겠습니다. 이들은 API 설계, 다국어 SDK, 문서화, 테스트, 릴리스 등 전체 라이프사이클 관리를 포함한 완전한 기능을 제공하며, SaaS 서비스도 제공합니다. 일부는 퍼블릭 클라우드와 통합되어 있어 사용이 매우 편리합니다. 하지만 동시에 두 가지 문제점을 안고 있습니다.
첫 번째 문제는 플랫폼 잠금 문제입니다. API 게이트웨이는 비즈니스 트래픽의 입구입니다. 이미지와 비디오와 같은 비즈니스와 무관한 트래픽을 가속화하는 CDN과 달리, API 게이트웨이는 많은 비즈니스 관련 로직을 바인딩합니다. 폐쇄형 솔루션을 사용하면 다른 플랫폼으로 원활하고 저비용으로 마이그레이션하기 어렵습니다.
두 번째 문제는 재개발이 불가능하다는 점입니다. 일반적으로 대중기업은 고유한 요구사항이 있으며 맞춤형 개발이 필요하지만, 이때는 제조업체에만 의존해야 하며 재개발이 불가능합니다.
이것이 오픈소스 API 게이트웨이 솔루션이 인기를 끌게 된 이유 중 하나입니다. 그러나 기존의 오픈소스 제품들도 완벽하지 않으며 많은 단점이 있습니다:
- PostgreSQL 및 MySQL과 같은 관계형 데이터베이스에 의존. 이 경우 게이트웨이 노드는 구성이 변경될 때만 데이터베이스를 폴링할 수 있습니다. 이는 구성이 느리게 적용될 뿐만 아니라 코드 복잡성을 증가시켜 이해하기 어렵게 만듭니다. 동시에 데이터베이스는 시스템의 단일 장애점 및 성능 병목 현상이 되어 전체 고가용성을 보장할 수 없습니다. Kubernetes 환경에서 API 게이트웨이를 사용하는 경우 관계형 데이터베이스는 더 번거로워 빠른 확장에 불리합니다.
- 플러그인을 핫로드할 수 없음. 새로운 플러그인을 추가하거나 기존 플러그인의 코드를 수정할 때 서비스를 재로드해야 합니다. 이는 NGINX 구성 수정 후 재로드해야 하는 것과 같아 사용자 요청에 영향을 미칩니다.
- 코드 구조가 복잡하고 이해하기 어려움. 일부 오픈소스 프로젝트는 다층 객체 지향 캡슐화를 수행하여 간단한 로직이 흐려졌습니다. 그러나 API 게이트웨이 시나리오에서는 직관적인 표현이 더 명확하고 효율적이며, 재개발에도 더 유리합니다.
따라서 우리는 더 가볍고 클라우드 네이티브하며 개발자 친화적인 API 게이트웨이가 필요합니다. 물론, 우리는 문을 닫고 차를 만들 수는 없습니다. 기존 API 게이트웨이의 특성을 깊이 이해해야 합니다. 이때 Cloud Native Software Foundation(CNCF)의 파노라마는 좋은 참고 자료입니다:
API 게이트웨이의 핵심 구성 요소와 개념
물론, 구현하기 전에 API 게이트웨이의 핵심 구성 요소를 이해해야 합니다. 앞서 언급한 API 게이트웨이의 기능에 따라 최소한 다음과 같은 구성 요소가 필요합니다.
첫 번째는 Route
입니다. 일부 규칙을 정의하여 클라이언트의 요청을 매칭한 후, 매칭 결과에 따라 해당 플러그인을 로드하고 실행하며, 요청을 지정된 업스트림으로 전달합니다. 이러한 라우팅 매칭 규칙은 host
, uri
, header
등으로 구성될 수 있습니다. NGINX의 익숙한 location은 라우팅의 한 구현입니다.
두 번째는 플러그인입니다. API 게이트웨이의 영혼이라고 할 수 있습니다. 인증, 트래픽 및 속도 제한, IP 제한, Prometheus, Zipkin 등의 기능은 모두 플러그인을 통해 구현됩니다. 플러그인이므로 플러그 앤 플레이여야 하며, 플러그인 간 상호작용은 없어야 합니다. 레고 블록을 조립하듯이, 통일된 규칙과 약속된 개발 인터페이스를 사용하여 하위 계층과 상호작용해야 합니다.
다음은 schema
입니다. API를 처리하는 게이트웨이이므로 API의 형식을 검증해야 합니다. 예를 들어 데이터 타입, 허용된 필드 내용, 필수 업로드 필드 등이 있습니다. 이때 schema
계층이 필요하여 통일되고 독립적인 정의와 검사를 수행합니다.
마지막으로 저장소입니다. 사용자의 다양한 구성을 저장하고, 변경 시 모든 게이트웨이 노드로 푸시하는 역할을 합니다. 이는 하위 계층의 매우 중요한 기본 구성 요소입니다. 이 선택은 상위 플러그인이 어떻게 작성되는지, 시스템이 고가용성과 확장성을 유지할 수 있는지 등을 결정하므로 신중하게 결정해야 합니다.
또한, 이러한 핵심 구성 요소 위에 API 게이트웨이의 일반적인 개념을 추상화해야 합니다. 이는 다양한 API 게이트웨이 간에 공통적으로 적용됩니다.
Route
먼저 Route
에 대해 이야기해 보겠습니다. 라우트는 매칭 조건, 바인딩된 플러그인 및 업스트림 세 부분으로 구성됩니다. 다음 그림과 같습니다:
Route
에서 직접 모든 구성을 완료할 수 있으며, 이는 가장 쉬운 방법입니다. 그러나 API와 업스트림이 많은 경우, 이렇게 하면 많은 중복 구성이 발생합니다. 이때 Service
와 Upstream
이라는 두 개념을 사용하여 추상화 계층을 만들어야 합니다.
Service
다음으로 Service
를 살펴보겠습니다. 이는 특정 유형의 API에 대한 추상화이며, 일종의 Route
그룹에 대한 추상화로 이해할 수도 있습니다. 일반적으로 업스트림 서비스와 1:1
대응 관계를 가지며, Route
와 Service
간의 관계는 일반적으로 N:1
입니다. 이를 그림으로 표현했습니다:
Service
의 이 추상화 계층을 통해 중복된 Plugin
과 Upstream
을 분리할 수 있습니다. 이렇게 하면 Plugin
과 Upstream
이 변경될 때 Service
만 수정하면 되며, 여러 Route
에 바인딩된 데이터를 수정할 필요가 없습니다.
Upstream
마지막으로 Upstream
에 대해 이야기해 보겠습니다. 위의 예를 계속 이어가면, 두 Route
의 업스트림이 동일하지만 바인딩된 플러그인이 다른 경우, 업스트림을 별도로 추상화할 수 있습니다. 다음 그림과 같습니다:
이렇게 하면 업스트림 노드가 변경될 때 Route
는 전혀 알지 못하며, 모든 처리는 Upstream
내부에서 이루어집니다.
이 세 가지 주요 개념의 도출 과정에서 볼 수 있듯이, 이러한 추상화는 상상이 아닌 실제 사용 시나리오를 기반으로 합니다. 이는 특정 기술 솔루션에 관계없이 모든 API 게이트웨이에 적용됩니다.
요약
이 글에서는 마이크로서비스 API 게이트웨이의 역할, 기능, 핵심 구성 요소 및 추상 개념을 소개했습니다. 이는 API 게이트웨이의 기초입니다.
여기서 생각해 볼 질문이 있습니다: "전통적인 남북 트래픽과 마이크로서비스 간의 동서 트래픽에 대해, API 게이트웨이가 둘 다 처리할 수 있다고 생각하시나요?" 이미 API 게이트웨이를 사용 중이라면, 기술 선택에 대한 생각도 적어보세요. 의견을 나누고 토론하며, 이 글을 동료와 친구들과 공유하여 함께 배우고 성장해 보세요.
다음: 2부: OpenResty를 사용하여 마이크로서비스 API 게이트웨이 구축하기 3부: OpenResty를 사용하여 마이크로서비스 API 게이트웨이 구축하기