TestForge | 📊 Plogger ✍️ Blog 📚 Docs
TestForge Blog

AI DevOps Korea

AI 서비스 운영과 성능개선을 위한 실전 허브

aidevops.kr에서 LLMOps, RAG, AI Agent, 평가, 관측성, 비용-성능 튜닝을 운영팀 관점으로 정리합니다.

← 전체 포스트

API Gateway 아키텍처 설계 — 마이크로서비스 진입점 구성

API Gateway의 역할과 설계 패턴. Kong, AWS API Gateway, Nginx 비교와 인증, Rate Limiting, 라우팅, 서킷 브레이커 구성 방법.

TestForge Team ·

API Gateway란

마이크로서비스의 단일 진입점(Single Entry Point).

클라이언트

API Gateway ← 인증/인가, Rate Limit, 라우팅, 로깅

┌───────────────────────────────────────┐
│ User Service │ Order Service │ Payment │
└───────────────────────────────────────┘

Gateway 없이 클라이언트가 직접 서비스를 호출하면:

  • 각 서비스마다 인증 로직 중복
  • 클라이언트가 내부 서비스 주소를 알아야 함
  • CORS, Rate Limit 설정 분산

핵심 기능

기능설명
라우팅URL 패턴 → 백엔드 서비스 매핑
인증/인가JWT 검증, API Key 확인
Rate LimitingIP/사용자별 요청 수 제한
로드밸런싱여러 인스턴스에 부하 분산
서킷 브레이커장애 서비스 격리
로깅/추적분산 트레이싱 (Jaeger, Zipkin)
캐싱자주 요청되는 응답 캐시
변환요청/응답 데이터 변환

솔루션 비교

KongAWS API GatewayNginxTraefik
유형오픈소스매니지드오픈소스오픈소스
설정Admin API콘솔/Terraformnginx.confYAML
플러그인풍부제한적Lua 확장Middleware
비용무료(OSS)요청당 과금무료무료
K8s 통합Kong Ingress-Nginx Ingress기본 지원

1. Kong Gateway 설정

# Kong + PostgreSQL (docker-compose)
services:
  kong-db:
    image: postgres:16
    environment:
      POSTGRES_DB: kong
      POSTGRES_USER: kong
      POSTGRES_PASSWORD: kong

  kong:
    image: kong:3.6
    environment:
      KONG_DATABASE: postgres
      KONG_PG_HOST: kong-db
      KONG_ADMIN_LISTEN: 0.0.0.0:8001
    ports:
      - "8000:8000"   # 프록시
      - "8001:8001"   # Admin API
# 서비스 등록
curl -X POST http://localhost:8001/services \
  -d name=user-service \
  -d url=http://user-service:8080

# 라우트 등록
curl -X POST http://localhost:8001/services/user-service/routes \
  -d "paths[]=/api/users" \
  -d "methods[]=GET" \
  -d "methods[]=POST"

# JWT 인증 플러그인
curl -X POST http://localhost:8001/services/user-service/plugins \
  -d name=jwt

# Rate Limiting 플러그인
curl -X POST http://localhost:8001/plugins \
  -d name=rate-limiting \
  -d config.minute=100 \
  -d config.hour=10000 \
  -d config.policy=redis \
  -d config.redis_host=redis

2. Kubernetes Ingress + Nginx

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-gateway
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
    # Rate Limiting
    nginx.ingress.kubernetes.io/limit-rps: "100"
    nginx.ingress.kubernetes.io/limit-connections: "20"
    # CORS
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://testforge.kr"
    # JWT 검증 (외부 auth 서비스)
    nginx.ingress.kubernetes.io/auth-url: "http://auth-service/validate"
    nginx.ingress.kubernetes.io/auth-signin: "https://testforge.kr/login"
spec:
  ingressClassName: nginx
  tls:
  - hosts: [api.testforge.kr]
    secretName: api-tls
  rules:
  - host: api.testforge.kr
    http:
      paths:
      - path: /api/users(/|$)(.*)
        pathType: ImplementationSpecific
        backend:
          service: { name: user-service, port: { number: 8080 } }
      - path: /api/orders(/|$)(.*)
        pathType: ImplementationSpecific
        backend:
          service: { name: order-service, port: { number: 8080 } }

3. 서킷 브레이커 패턴

# Kong Circuit Breaker 플러그인
curl -X POST http://localhost:8001/services/payment-service/plugins \
  -d name=request-termination \
  -d config.status_code=503 \
  -d config.message="Service temporarily unavailable"

# 또는 Resilience4j (Spring Boot 백엔드)
@CircuitBreaker(name = "payment", fallbackMethod = "paymentFallback")
public PaymentResponse processPayment(PaymentRequest request) {
    return paymentClient.pay(request);
}

public PaymentResponse paymentFallback(PaymentRequest request, Exception e) {
    // 장애 시 대기 큐에 저장
    pendingQueue.add(request);
    return PaymentResponse.pending("결제 처리 중입니다");
}

4. 분산 트레이싱

# Kong OpenTelemetry 플러그인
curl -X POST http://localhost:8001/plugins \
  -d name=opentelemetry \
  -d config.endpoint=http://jaeger:4318/v1/traces \
  -d config.resource_attributes.service.name=api-gateway

모든 요청에 X-Trace-Id 헤더가 자동으로 추가되어 Jaeger에서 전체 흐름을 추적합니다.

설계 원칙

  1. Gateway는 얇게: 비즈니스 로직은 백엔드 서비스에, Gateway는 횡단 관심사만
  2. 장애 격리: 하나의 서비스 장애가 Gateway 전체를 마비시키지 않도록
  3. 버전 관리: /v1/, /v2/ 경로로 API 버전 분리
  4. 보안: 내부 서비스는 외부에서 직접 접근 불가 (NetworkPolicy)
  5. 모니터링: 모든 요청/응답 로깅 + 레이턴시 추적

라우팅 전략

/api/v1/users/**  → user-service:8080
/api/v1/orders/** → order-service:8080
/api/v1/pay/**    → payment-service:8080  (TLS 강제)
/api/internal/**  → 외부 접근 차단 (403)
/health           → 인증 우회 (헬스체크용)