본문 바로가기
개발/MSA

[API Gateway - KrakenD] KrakenD 소개 및 구성해보기

by 궁즉변 변즉통 통즉구 2024. 5. 19.
반응형

MSA를 구성할 때 API Gateway는 필수적으로 구성을 한다. MSA 패턴에서도 외부 API 패턴으로 API Gateway에 대한 중요성을 강조하고 있다. API Gateway가 필요한 이유는 네트워크 지연 경감(클라이언트와 서비스 간 통신 빈도 최소화 필요), 클라이언트 프로그램 복잡성 방지(서비스 호출 처리 최소화), 서비스 변경에 따른 클라이언트 영향도 최소화, 인증, 로깅 등 많은 이유가 있다. 

 

기존에는 Kong API Gateway가 많이 언급되고 적용이 되었는데 이번에 KrakenD라는 것도 알게되서 정리해본다. 

출처: https://tommypagy.tistory.com/174

 

KrakenD 특징

1. KrakenD는 API Gateway 기능을 수행

출처: https://uploads-ssl.webflow.com/5f3b26c2b3bde9e2894607e8/634de4f62a7716a245c0c81c_KrakenD%20Product%20Presentation%20KR%2016Oct2022.pdf

 

2. 현존하는 API Gateway중 가장 빠른 성능(3,479 requests/sec)

출처: https://www.krakend.io/

 

3. Go 언어기반, 플러그인 기반의 기능 확장이 용이

 

4. 노드간 Coordination 이나 중앙화된 Configuration 관리없이 독립적으로 동작함으로 Stateless한 구조로 ScaleOut이 용이

 

5. 다양한 배포 방식 제공(CloudNative, On-Prem)

출처: https://www.krakend.io/download/

 

6. Community Edition과 함께 Enterprise Edition 제공

     Enterprise에서만 제공하는 기능은 아래와 같다.

출처: https://uploads-ssl.webflow.com/5f3b26c2b3bde9e2894607e8/634de4f62a7716a245c0c81c_KrakenD%20Product%20Presentation%20KR%2016Oct2022.pdf

 

 

Kong API Gateway와 비교

API Gateway로 많이 사용되는 kong API Gateway와 비교를 하면 아래와 같다.

구분 KrakenD Kong
최초 Release 2016년 2011년
구축 복잡성 낮음
API Gateway Only(Binary + Config)
높음
Kong Gateway + Datastore
DB 없음  Cassandra or PostgreSQL
오픈소스 Apache2.0 / Enterprise Apache2.0 / Enterprise
사용 언어 및 기술 Go Nginx/ LUA
인가 지원 지원
관리 대시보드 Designer, Studio (Enterprise)
기타 3rd-Party Logging, Metrics, Tracing 연계
Konga GUI (오픈소스)
Enterprise Edition: UI 지원
성능 3,479 requests/sec 1,753 requests/sec
장점 높은 성능, 다양한 기능, 쉬운 확장성 준수한 성능, 관리용이성, 넓은 사용자층
단점 모니터링을 위한 3rd-party 별도 구성 필요 - NGINX Proxy 기반으로 무거운 스택
- 필요한 플러그인 수동으로 설치함으로 초기설정에 시간이 소요
- End-Point와 Backend 1:1 맵핑으로 Aggregation 구현에 제약
확장성 쉬운 확장 (별도 DB 없음) 제한된 확장 및 성능 영향 (DB 연계 필요)
커스텀 Plugin Go, CEL, Martian Transformation, LUA LUA, Go

출처: https://uploads-ssl.webflow.com/5f3b26c2b3bde9e2894607e8/634de4f62a7716a245c0c81c_KrakenD%20Product%20Presentation%20KR%2016Oct2022.pdf

 

KrakenD 구성

krakeD를 한번 설치해서 테스트 해본다. 간단하게 Docker로 설치할 예정이다. 먼저 아래 사이트에서 우측 상단의 'Download config'를 클릭해서 초기 설정 정보를 다운로드 받는다. 사이트에서 필요한 설정을 구성하고 다운로드 받을 수도 있다.

https://designer.krakend.io/#!/

 

 

다운로드 받은 설정 파일(krakend.json)을 Docker Volume으로 지정할 디렉토리에 위치 시킨다.

 

docker 명령으로 실행한다.

docker run -p 8080:8080 -v $PWD:/etc/krakend/ devopsfaith/krakend run --config /etc/krakend/krakend.json

아래와 같이 docker-compose.yml 파일로 생성해서 실행해도 된다. 

version: "3"
services:
  krakend:
    image: devopsfaith/krakend 
    volumes:
      - ".:/etc/krakend"
    ports:
      - "8080:8080"
    command: [ "run", "-dc", "krakend.json" ]

 

 

헬스체크 URL로 호출해서 동작을 확인한다.

http://localhost:8080/__health

 

 

krakend.json 설정

기본 라우팅

기본 라우팅부터 테스트해본다. 먼저 백엔드 API로는 Dummy API https://jsonplaceholder.typicode.com/ 사용할 예정이다. 전체적인 설정 정보는 다음을 참조한다.

https://www.krakend.io/docs/configuration/

krakend.json 파일을 아래와 같이 수정한다. 설명을 위해 각 항목 별 주석(//)을 작성했지만, json 파일에는 주석(//)이 안됨으로 주석 제거 후 실행해야 한다. 설정 파일 변경 후 krakend를 재실행한다.

{
  "$schema": "https://www.krakend.io/schema/krakend.json", // 옵션으로 IDE툴 json 설정 자동완성 등에 활용 가능
  "version": 3,
  "name": "KrakenD - API Gateway",
  "timeout": "3000ms",
  "cache_ttl": "500s",
  "endpoints": [
    {
      "endpoint": "/users", // KrakenD 접속 Endpoint URL 
      "method": "GET",  // KrakenD Endpoint HTTP 메소드
      "backend": [
        {
          "url_pattern": "/users", // 라우팅 대상 백엔드 URL 
          "method": "GET",
          "host": ["https://jsonplaceholder.typicode.com/"], // 라우팅 대상 호스트, 여러개 등록시 로드발란싱 동작
          "is_collection": true, // 라우팅 대상 응답이 json 배열([..])로 시작될 경우 설정 필요(기본적으로 {"collection":[..]})로 응답 됨 
          "mapping": {
            "collection": "users" // {"collection":[..]} 응답을 {"users":[..]}로 변경 시킴
          }
        }
      ]
    }
  ]
}

다음으로 호출해서 테스트 해본다. 

http://localhost:8080/users

왼쪽 그림과 같이 결과가 응답되는데 krakend를 통한 호출 결과(왼쪽 그림)는 기본 백엔드 직접 호출(오른쪽 그림)할 때와 달리 json구조가 변경된 것을 확인할 수 있다(“users”에 Collection 구조가 매핑 됨)

 

백엔드 API 추가 

여기서 백엔드 API를 추가해본다. 또다른 백엔드 Dummy API로 https://dummyjson.com/ 추가해 줄것이다. krakend.json을 다음과 같이 수정한다. 기존 설정 하단에 백엔드 Host만 추가해준것이다.

{
  "$schema": "https://www.krakend.io/schema/krakend.json", // 옵션으로 IDE툴 json 설정 자동완성 등에 활용 가능
  "version": 3,
  "name": "KrakenD - API Gateway",
  "timeout": "3000ms",
  "cache_ttl": "500s",
  "endpoints": [
    {
      "endpoint": "/users", // KrakenD 접속 Endpoint URL 
      "method": "GET",  // KrakenD Endpoint HTTP 메소드
      "backend": [
        {
          "url_pattern": "/users", // 라우팅 대상 백엔드 URL 
          "method": "GET",
          "host": ["https://jsonplaceholder.typicode.com/"], // 라우팅 대상 호스트, 여러개 등록시 로드발란싱 동작
          "is_collection": true, // 라우팅 대상 응답이 json 배열([..])로 되어 있을 경우 설정 필요(기본적으로 {"collection":[..]})로 응답 됨 
          "mapping": {
            "collection": "users" // {"collection":[..]} 응답을 {"users":[..]}로 변경 시킴
          }
        }
      ]
    },
    {
      "endpoint": "/products",
      "method": "GET",
      "backend": [
        {
          "url_pattern": "/products",
          "method": "GET",
          "host": ["https://dummyjson.com/"] // 백엔드 host 추가 
        }
      ]
    }
  ]
}

 

아래 URL로 테스트해보자. 정상적으로 호출되면 KrakenD를 통해 여러 백엔드를 호출할 수 있는 구조(라우팅)가 확인된 것이다.

http://localhost:8080/products

 

백엔드 API 통합(Merge) 테스트

KrakenD는 백엔드가 여러개일 경우 자동 Merge를 실행한다. 사용자 상세 API를 호출했을 때 사용자 상세 정보와 해당 사용자의 Post글을 함께 조회해서 응답하는 API Merge를 테스트해본다. 

{
  "$schema": "https://www.krakend.io/schema/krakend.json",
  "version": 3,
   ...
  "endpoints": [
    ... 생량 ...
    {
      "endpoint": "/users/{id}",  // 사용자 상세 조회 
      "method": "GET",
      "backend": [
        {
          "url_pattern": "/users/{id}", // 백엔드 사용자 상세 조회 
          "method": "GET",
          "host": ["https://jsonplaceholder.typicode.com/"]
        },
        {
          "url_pattern": "/posts?userId={id}", // 백엔드 사용자 POST 목록 조회 
          "method": "GET",
          "host": ["https://jsonplaceholder.typicode.com/"],
          "is_collection": true,
          "mapping": {
            "collection": "posts" // POST 목록을 posts로 매핑 
          }
        }
      ]
    }
  ]
}

 

아래 URL로 호출해본다. 

http://localhost:8080/users/1

왼쪽 그림과 같이 결과가 응답된다. krakend를 통한 호출 결과(왼쪽 그림)에는 posts라는 정보가 추가 되었다. 기본 백엔드 직접 호출(오른쪽 그림)할때는 posts라는 정보가 없다.

 

Summary

여기까지 테스트해본 결과 Community 버전은 아래와 같은 단점이 있다. 

1. Wildcard(*) Endpoint 설정이 지원되지 않는다(ex. /foo/* ) 엔터프라이즈 버전에서만 지원되서 설정하기 많이 어려울것 같다. 아래와 같은 대안이 있기는 하다. 

https://www.krakend.io/docs/endpoints/#endpoints-with-multiple-nesting-levels

endpoints: /user/{id}, /user/{id}/{level2}, /user/{id}/{level2}/{level3} 등

 

 

2. URL이 동일하고 HTTP 메소드만 다른 경우에도 모든 개별적으로 선언이 필요하다. 설정에 중복이 많이 발생할 수 있고 가독성도 떨어질수 있을것 같다.

https://www.krakend.io/docs/endpoints/#endpoints-listening-to-multiple-methods

 

간단한게 기본 테스트는 여기서 마무리하고 다음에 추가 테스트하게 되면 정리할 예정이다.

 

 

도움받은 자료: https://uploads-ssl.webflow.com/5f3b26c2b3bde9e2894607e8/634de4f62a7716a245c0c81c_KrakenD%20Product%20Presentation%20KR%2016Oct2022.pdf

 

반응형

댓글