API Gateway 가이드: 개념부터 구축까지

목차

1. API Gateway란 무엇인가?

1.1 API Gateway의 정의

API Gateway는 클라이언트와 백엔드 서비스 사이에 있는 중간 계층으로, 모든 API 요청의 진입점입니다. 마이크로서비스 아키텍처에서 특히 중요하며, 여러 독립적인 서비스를 하나의 통합된 API로 묶어 제공하는 관문 역할을 합니다.

1.2 API Gateway의 핵심 기능

1.3 API Gateway의 필요성

마이크로서비스 아키텍처의 복잡성 해결

보안 강화

2. 주요 API Gateway 솔루션 비교

2.1 AWS API Gateway

특징

인프라 구성 방법

yaml
# serverless.yml 예시 (Serverless Framework 사용)
service: my-api-gateway

provider:
  name: aws
  runtime: nodejs18.x
  region: ap-northeast-2

functions:
  getUsers:
    handler: handlers/users.get
    events:
      - http:
          path: users
          method: get
          cors: true
          authorizer:
            name: authenticate
            resultTtlInSeconds: 300

  createUser:
    handler: handlers/users.create
    events:
      - http:
          path: users
          method: post
          cors: true

resources:
  Resources:
    GatewayResponseDefault4XX:
      Type: 'AWS::ApiGateway::GatewayResponse'
      Properties:
        ResponseParameters:
          gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
        ResponseType: DEFAULT_4XX
        RestApiId: !Ref RestApi

Terraform을 이용한 구성

hcl
resource "aws_api_gateway_rest_api" "example" {
  name        = "example-api"
  description = "Example API Gateway"
}

resource "aws_api_gateway_resource" "users" {
  rest_api_id = aws_api_gateway_rest_api.example.id
  parent_id   = aws_api_gateway_rest_api.example.root_resource_id
  path_part   = "users"
}

resource "aws_api_gateway_method" "users_get" {
  rest_api_id   = aws_api_gateway_rest_api.example.id
  resource_id   = aws_api_gateway_resource.users.id
  http_method   = "GET"
  authorization = "AWS_IAM"
}

resource "aws_api_gateway_integration" "users_lambda" {
  rest_api_id = aws_api_gateway_rest_api.example.id
  resource_id = aws_api_gateway_resource.users.id
  http_method = aws_api_gateway_method.users_get.http_method

  integration_http_method = "POST"
  type                   = "AWS_PROXY"
  uri                    = aws_lambda_function.users.invoke_arn
}

장점

단점

2.2 Kong Gateway

특징

Docker Compose를 이용한 구성

yaml
version: '3.8'

services:
  kong-database:
    image: postgres:13
    environment:
      POSTGRES_USER: kong
      POSTGRES_PASSWORD: kongpass
      POSTGRES_DB: kong
    volumes:
      - kong_data:/var/lib/postgresql/data
    networks:
      - kong-net

  kong-migrations:
    image: kong:3.4
    command: kong migrations bootstrap
    depends_on:
      - kong-database
    environment:
      KONG_DATABASE: postgres
      KONG_PG_HOST: kong-database
      KONG_PG_USER: kong
      KONG_PG_PASSWORD: kongpass
    networks:
      - kong-net

  kong:
    image: kong:3.4
    depends_on:
      - kong-migrations
    environment:
      KONG_DATABASE: postgres
      KONG_PG_HOST: kong-database
      KONG_PG_USER: kong
      KONG_PG_PASSWORD: kongpass
      KONG_PROXY_ACCESS_LOG: /dev/stdout
      KONG_ADMIN_ACCESS_LOG: /dev/stdout
      KONG_PROXY_ERROR_LOG: /dev/stderr
      KONG_ADMIN_ERROR_LOG: /dev/stderr
      KONG_ADMIN_LISTEN: 0.0.0.0:8001
    ports:
      - "8000:8000"  # Proxy port
      - "8443:8443"  # Proxy SSL port
      - "8001:8001"  # Admin API port
    networks:
      - kong-net

  konga:
    image: pantsel/konga:latest
    depends_on:
      - kong
    environment:
      NODE_ENV: production
    ports:
      - "1337:1337"
    networks:
      - kong-net

volumes:
  kong_data:

networks:
  kong-net:

Kubernetes를 이용한 구성

yaml
apiVersion: v1
kind: Namespace
metadata:
  name: kong
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kong
  namespace: kong
spec:
  replicas: 2
  selector:
    matchLabels:
      app: kong
  template:
    metadata:
      labels:
        app: kong
    spec:
      containers:
      - name: kong
        image: kong:3.4
        env:
        - name: KONG_DATABASE
          value: "off"
        - name: KONG_DECLARATIVE_CONFIG
          value: "/kong/declarative/kong.yml"
        - name: KONG_PROXY_ACCESS_LOG
          value: "/dev/stdout"
        - name: KONG_ADMIN_ACCESS_LOG
          value: "/dev/stdout"
        - name: KONG_PROXY_ERROR_LOG
          value: "/dev/stderr"
        - name: KONG_ADMIN_ERROR_LOG
          value: "/dev/stderr"
        - name: KONG_ADMIN_LISTEN
          value: "0.0.0.0:8001"
        ports:
        - containerPort: 8000
        - containerPort: 8443
        - containerPort: 8001
        volumeMounts:
        - name: kong-config
          mountPath: /kong/declarative/
      volumes:
      - name: kong-config
        configMap:
          name: kong-declarative-config
---
apiVersion: v1
kind: Service
metadata:
  name: kong-proxy
  namespace: kong
spec:
  type: LoadBalancer
  ports:
  - name: proxy
    port: 80
    targetPort: 8000
  - name: proxy-ssl
    port: 443
    targetPort: 8443
  selector:
    app: kong

장점

단점

2.3 Istio

특징

Kubernetes 환경에서의 구성

yaml
# istio-gateway.yaml
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: api-gateway
  namespace: default
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - api.example.com
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: api-tls-secret
    hosts:
    - api.example.com
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: api-routes
  namespace: default
spec:
  hosts:
  - api.example.com
  gateways:
  - api-gateway
  http:
  - match:
    - uri:
        prefix: /users
    route:
    - destination:
        host: user-service
        port:
          number: 8080
    fault:
      delay:
        percentage:
          value: 0.1
        fixedDelay: 5s
  - match:
    - uri:
        prefix: /orders
    route:
    - destination:
        host: order-service
        port:
          number: 8080
      weight: 90
    - destination:
        host: order-service-v2
        port:
          number: 8080
      weight: 10

보안 정책 설정

yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: api-authz
  namespace: default
spec:
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/api-client"]
    to:
    - operation:
        methods: ["GET", "POST"]
    when:
    - key: request.headers[version]
      values: ["v1", "v2"]

장점

단점

3. 솔루션별 상세 비교

3.1 성능 비교

항목 AWS API Gateway Kong Gateway Istio
지연시간 낮음-중간 매우 낮음 낮음
처리량 높음 매우 높음 높음
메모리 사용량 N/A (관리형) 중간 높음
CPU 사용량 N/A (관리형) 낮음 중간

3.2 기능 비교

기능 AWS API Gateway Kong Gateway Istio
인증/권한부여 ✅ 완전 지원 ✅ 완전 지원 ✅ 완전 지원
로드 밸런싱 ✅ 지원 ✅ 완전 지원 ✅ 고급 지원
API 버전 관리 ✅ 지원 ✅ 지원 ✅ 지원
모니터링 ✅ CloudWatch ✅ 다양한 옵션 ✅ Prometheus
캐싱 ✅ 지원 ✅ 플러그인 ✅ 지원
요청 변환 ✅ 지원 ✅ 완전 지원 ✅ 지원
서비스 디스커버리 ✅ AWS 통합 ✅ 다양한 백엔드 ✅ Kubernetes 통합

3.3 비용 비교

AWS API Gateway

Kong Gateway

Istio

3.4 커뮤니티 크기 및 생태계

AWS API Gateway

Kong Gateway

Istio

4. 선택 기준 및 권장사항

4.1 AWS API Gateway를 선택해야 하는 경우

4.2 Kong Gateway를 선택해야 하는 경우

4.3 Istio를 선택해야 하는 경우

5. 모범 사례 및 주의사항

5.1 공통 모범 사례

보안

yaml
# 보안 헤더 설정 예시
response:
  headers:
    - name: "X-Content-Type-Options"
      value: "nosniff"
    - name: "X-Frame-Options"
      value: "DENY"
    - name: "X-XSS-Protection"
      value: "1; mode=block"

모니터링

API 설계

5.2 주의사항

단일 장애점 방지

성능 최적화

보안 강화

6. 실습 예제: 간단한 API Gateway 구축

6.1 Kong Gateway 실습

1단계: Docker로 Kong 실행

bash
# 네트워크 생성
docker network create kong-net

# PostgreSQL 데이터베이스 실행
docker run -d --name kong-database \
  --network=kong-net \
  -p 5432:5432 \
  -e "POSTGRES_USER=kong" \
  -e "POSTGRES_DB=kong" \
  -e "POSTGRES_PASSWORD=kongpass" \
  postgres:13

# Kong 마이그레이션 실행
docker run --rm --network=kong-net \
  -e "KONG_DATABASE=postgres" \
  -e "KONG_PG_HOST=kong-database" \
  -e "KONG_PG_USER=kong" \
  -e "KONG_PG_PASSWORD=kongpass" \
  kong:3.4 kong migrations bootstrap

# Kong 실행
docker run -d --name kong \
  --network=kong-net \
  -e "KONG_DATABASE=postgres" \
  -e "KONG_PG_HOST=kong-database" \
  -e "KONG_PG_USER=kong" \
  -e "KONG_PG_PASSWORD=kongpass" \
  -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
  -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
  -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
  -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
  -e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \
  -p 8000:8000 \
  -p 8443:8443 \
  -p 8001:8001 \
  kong:3.4

2단계: 서비스 및 라우트 등록

bash
# 백엔드 서비스 등록
curl -i -X POST http://localhost:8001/services/ \
  --data "name=example-service" \
  --data "url=http://httpbin.org"

# 라우트 등록
curl -i -X POST http://localhost:8001/services/example-service/routes \
  --data "hosts[]=example.com"

# 테스트
curl -i -X GET http://localhost:8000/get \
  --header "Host: example.com"

6.2 AWS API Gateway 실습 (AWS CLI 사용)

bash
# API 생성
aws apigateway create-rest-api \
  --name "example-api" \
  --description "Example API Gateway"

# 리소스 생성
aws apigateway create-resource \
  --rest-api-id {api-id} \
  --parent-id {root-resource-id} \
  --path-part "users"

# 메서드 생성
aws apigateway put-method \
  --rest-api-id {api-id} \
  --resource-id {resource-id} \
  --http-method GET \
  --authorization-type NONE

# 통합 설정
aws apigateway put-integration \
  --rest-api-id {api-id} \
  --resource-id {resource-id} \
  --http-method GET \
  --type HTTP \
  --integration-http-method GET \
  --uri "http://httpbin.org/get"

# 배포
aws apigateway create-deployment \
  --rest-api-id {api-id} \
  --stage-name prod

7. 성능 최적화 및 모니터링

7.1 성능 최적화 전략

캐싱 전략

연결 풀링

yaml
# Kong 연결 풀 설정 예시
upstream:
  healthchecks:
    active:
      http_path: "/health"
      healthy:
        interval: 10
        successes: 3
      unhealthy:
        interval: 10
        http_failures: 3

요청 제한

yaml
# Rate Limiting 플러그인 설정
plugins:
- name: rate-limiting
  config:
    minute: 100
    hour: 1000
    policy: local

7.2 모니터링 및 알림

주요 메트릭

Grafana 대시보드 예시

json
{
  "dashboard": {
    "title": "API Gateway Metrics",
    "panels": [
      {
        "title": "Request Rate",
        "type": "graph",
        "targets": [
          {
            "expr": "sum(rate(kong_http_requests_total[5m]))",
            "legendFormat": "Total Requests/sec"
          }
        ]
      },
      {
        "title": "Response Time",
        "type": "graph",
        "targets": [
          {
            "expr": "histogram_quantile(0.95, sum(rate(kong_request_duration_ms_bucket[5m])) by (le))",
            "legendFormat": "95th percentile"
          }
        ]
      }
    ]
  }
}

8. 보안 강화 방안

8.1 인증 및 권한 부여

JWT 인증 예시 (Kong)

bash
# JWT 플러그인 활성화
curl -X POST http://localhost:8001/services/example-service/plugins \
  --data "name=jwt"

# Consumer 생성
curl -X POST http://localhost:8001/consumers \
  --data "username=testuser"

# JWT 자격 증명 생성
curl -X POST http://localhost:8001/consumers/testuser/jwt \
  --data "key=a36c3049b36249a3c9f8891cb127243c" \
  --data "secret=e71829c351aa4242c2719cbfbe671c09"

OAuth 2.0 설정 (AWS API Gateway)

json
{
  "authorizerUri": "arn:aws:apigateway:region:lambda:path/2015-03-31/functions/function-arn/invocations",
  "authorizerCredentials": "arn:aws:iam::account-id:role/role-name",
  "authorizerResultTtlInSeconds": 300,
  "identitySource": "method.request.header.Authorization",
  "type": "TOKEN"
}

8.2 API 보안 모범 사례

입력 검증

yaml
# Kong Request Validation 플러그인
plugins:
- name: request-validator
  config:
    version: draft4
    body_schema: |
      {
        "type": "object",
        "properties": {
          "name": {"type": "string"},
          "email": {"type": "string", "format": "email"}
        },
        "required": ["name", "email"]
      }

CORS 설정

yaml
# CORS 플러그인 설정
plugins:
- name: cors
  config:
    origins:
    - "https://myapp.com"
    methods:
    - GET
    - POST
    headers:
    - Accept
    - Content-Type
    - Authorization
    exposed_headers:
    - X-Auth-Token
    max_age: 3600
    credentials: true

9. 트러블슈팅 가이드

9.1 일반적인 문제들

높은 지연시간 문제

인증 실패 문제

성능 저하 문제

bash
# Kong 성능 모니터링
curl -s http://localhost:8001/status | jq

# 연결 상태 확인
curl -s http://localhost:8001/services/example-service/health

# 업스트림 타겟 확인
curl -s http://localhost:8001/upstreams/example-upstream/targets

9.2 로그 분석

구조화된 로깅

json
{
  "timestamp": "2024-01-15T10:30:00Z",
  "level": "INFO",
  "service": "api-gateway",
  "method": "GET",
  "path": "/api/users",
  "status": 200,
  "duration": 150,
  "user_id": "user123",
  "correlation_id": "req-abc123"
}

로그 집계 및 분석

yaml
# Fluentd 설정 예시
<source>
  @type tail
  tag kong.access
  path /var/log/kong/access.log
  pos_file /var/log/fluentd/kong-access.log.pos
  format json
</source>

<match kong.access>
  @type elasticsearch
  host elasticsearch.example.com
  port 9200
  index_name kong-logs
</match>

10. 미래 전망 및 발전 방향

10.1 기술 트렌드

서버리스 통합

AI/ML 통합

GraphQL 지원

10.2 업계 동향

클라우드 네이티브

보안 강화

결론

API Gateway는 현대 애플리케이션 아키텍처의 필수 구성 요소입니다. 솔루션마다 장단점이 다르므로, 선택할 때는 아래 요소를 고려해야 합니다.

초기 프로젝트나 빠른 개발이 필요한 경우 AWS API Gateway를, 높은 성능과 유연성이 필요한 경우 Kong Gateway를, 복잡한 마이크로서비스 환경에서는 Istio를 고려해 볼 수 있습니다.

무엇보다 현재 요구사항을 정확히 파악하고, 앞으로의 확장 가능성까지 고려해 솔루션을 선택하는 게 중요합니다. 구현할 때는 각 도구의 공식 문서와 커뮤니티를 적극 활용하시기 바랍니다.


이 가이드는 2024년 기준으로 작성되었으며, 각 솔루션의 최신 버전과 기능을 반영하고 있습니다. 실제 구현 시에는 최신 문서를 참조하시기 바랍니다.

도식

100%

끌어서 이동, 두 손가락이나 휠로 확대·축소. 키보드: 화살표 이동, + − 확대·축소, 0 맞춤, Esc 닫기. 같은 내용은 그림 아래 “그림 관계를 글로 읽기”에 있다.