본문 바로가기
카테고리 없음

Kong API Gateway란 (X)

by SuldenLion 2026. 4. 25.
반응형

 

KONG
 
서비스 메시 & 네트워킹 · SM-007 API Gateway
kong-guide.html
 
 
🔑
Key Auth
Authentication
Rate Limiting
Traffic Control
🛡️
IP Restriction
Security
📊
Prometheus
Analytics
🔐
JWT
Authentication
🔄
Request Trans
Transformation
🌐
CORS
Security
📡
OpenTelemetry
Observability
플러그인 생태계 300+개 · Hub에서 검색
서비스 메시 & 네트워킹 · SM-007

KONG API 게이트웨이의 왕. OpenResty(Nginx+Lua) 위에 구축된 고성능 플랫폼으로 인증·Rate Limiting·변환·관찰가능성을 플러그인으로 조합합니다.

API Gateway 300+ Plugins OpenResty K8s Ingress Konnect Admin API
기반
Nginx
+Lua
OpenResty
플러그인
300+
Hub + 커스텀
처리량
수백만
req/s
단일 노드
모드
DB-less
/ DB
PostgreSQL
01 — 핵심 개념

Kong
API 게이트웨이의 구조

Kong은 API 트래픽을 처리하는 중앙 제어점입니다. 모든 API 요청이 Kong을 통과하며, 플러그인 파이프라인에서 인증·변환·Rate Limiting·로깅이 실행됩니다.

01
Service
백엔드 API 추상화
실제 API 서버를 나타냅니다. URL·프로토콜·타임아웃을 정의하며, Route가 매핑됩니다. 하나의 Service에 여러 Route를 연결할 수 있습니다.
02
Route
요청 매칭 규칙
Host·Path·Method·Header 조건으로 요청을 특정 Service로 연결합니다. 하나의 Service에 여러 Route가 가능합니다.
03
Plugin
기능 확장 단위
요청/응답 파이프라인에 기능을 추가합니다. Service·Route·Consumer·Global 4가지 범위에 적용 가능합니다.
04
Consumer
API 소비자
API를 사용하는 주체(사용자·앱·서비스)를 나타냅니다. Consumer별로 인증 정보(API Key·JWT)와 Rate Limit을 다르게 설정합니다.
05
Upstream
로드밸런싱 그룹
여러 Target(백엔드 인스턴스)의 로드밸런싱 그룹. RR·IP Hash·Least Connections·Hash 알고리즘과 헬스체크를 설정합니다.
06
Workspace
테넌트 격리 (Enterprise)
Kong Enterprise의 멀티테넌시 기능. 팀·환경별로 Service·Route·Plugin 설정을 격리합니다. RBAC으로 접근을 제어합니다.
 
ARCHITECTURE
 
02 — 아키텍처

Kong
플러그인 파이프라인

// Kong 요청 처리 흐름 — 플러그인 파이프라인
클라이언트
Kong Proxy (:8000/:8443)
OpenResty · Nginx + Lua · Plugin Engine
↓ Route 매칭 → Plugin Phase 실행
access phase
인증·IP·ACL
rewrite phase
헤더·URL 변환
header_filter
응답 헤더 수정
log phase
로깅·통계
↓ Upstream 로드밸런싱
Target 1
:8080
Target 2
:8080
Target 3
:8080
Admin API :8001
설정 관리
DB: PostgreSQL
또는 DB-less
Kong Manager
GUI 대시보드
모든 플러그인은 Phase 순서대로 실행 — access → rewrite → proxy → header_filter → body_filter → log
 
INSTALL
 
03 — 설치 & 설정

Kong 설치 &
DB-less 모드

 
yaml + bash — Docker Compose 설치 + DB-less 설정
# ─── Docker Compose — Kong + PostgreSQL ──────────────────────
version: "3.9"
services:
  kong-database:
    image: postgres:15
    environment:
      POSTGRES_DB: kong
      POSTGRES_USER: kong
      POSTGRES_PASSWORD: kong_secret
    volumes: [kong_data:/var/lib/postgresql/data]

  kong-migration:
    image: kong:3.7
    command: kong migrations bootstrap
    depends_on: [kong-database]
    environment:
      KONG_DATABASE: postgres
      KONG_PG_HOST: kong-database
      KONG_PG_DATABASE: kong
      KONG_PG_USER: kong
      KONG_PG_PASSWORD: kong_secret

  kong:
    image: kong:3.7
    depends_on: [kong-migration]
    environment:
      KONG_DATABASE:     postgres
      KONG_PG_HOST:      kong-database
      KONG_PG_DATABASE:  kong
      KONG_PG_USER:      kong
      KONG_PG_PASSWORD:  kong_secret

      KONG_PROXY_LISTEN:       0.0.0.0:8000, 0.0.0.0:8443 ssl http2
      KONG_ADMIN_LISTEN:       127.0.0.1:8001   # 외부 노출 금지
      KONG_ADMIN_GUI_URL:      http://localhost:8002
      KONG_LOG_LEVEL:          info
      KONG_PROXY_ACCESS_LOG:   /dev/stdout
      KONG_ADMIN_ACCESS_LOG:   /dev/stdout
      KONG_PROXY_ERROR_LOG:    /dev/stderr
      KONG_PLUGINS:            bundled   # 모든 번들 플러그인 활성화

    ports:
      - "8000:8000"   # HTTP Proxy
      - "8443:8443"   # HTTPS Proxy
      - "8002:8002"   # Kong Manager UI
    healthcheck:
      test: [CMD, kong, health]
      interval: 10s

# ─── DB-less 모드 (설정 파일 기반) ──────────────────────────
# declarative 설정 — Git에서 관리 가능
  kong-dbless:
    image: kong:3.7
    environment:
      KONG_DATABASE:     off          # DB 없음
      KONG_DECLARATIVE_CONFIG: /kong/declarative/kong.yaml
      KONG_PROXY_LISTEN: 0.0.0.0:8000
    volumes:
      - ./kong.yaml:/kong/declarative/kong.yaml:ro

# ─── kong.yaml — DB-less 선언적 설정 ─────────────────────────
_format_version: "3.0"
_transform: true

services:
  - name: order-api
    url: http://order-service:8080
    connect_timeout: 5000
    read_timeout: 60000
    routes:
      - name: order-routes
        paths: [/api/orders]
        methods: [GET, POST, PUT, DELETE]
        strip_path: false
    plugins:
      - name: rate-limiting
        config:
          minute: 100
          hour: 5000
          policy: redis
          redis_host: redis
      - name: jwt
        config: {}

consumers:
  - username: mobile-app
    keyauth_credentials:
      - key: mobile-app-key-secret-xxxxx
    jwt_secrets:
      - secret: jwt-signing-secret-key
 
SERVICES & ROUTES
 
04 — Services & Routes

Admin API
Service & Route 관리

 
bash — Admin API로 Service·Route·Upstream 설정
# ─── 1. Service 생성 ──────────────────────────────────────────
curl -X POST http://localhost:8001/services \
  --data name=order-service \
  --data url=http://order-backend:8080 \
  --data connect_timeout=5000 \
  --data read_timeout=60000 \
  --data write_timeout=60000 \
  --data retries=3

# {"id":"uuid","name":"order-service","host":"order-backend","port":8080,...}

# ─── 2. Route 생성 ───────────────────────────────────────────
curl -X POST http://localhost:8001/services/order-service/routes \
  --data "name=order-api" \
  --data "paths[]=/api/orders" \
  --data "methods[]=GET" \
  --data "methods[]=POST" \
  --data "methods[]=PUT" \
  --data "methods[]=DELETE" \
  --data "hosts[]=api.acme.com" \
  --data "strip_path=false" \
  --data "preserve_host=true"

# ─── 3. Upstream + Target 설정 (로드밸런싱) ──────────────────
# Upstream 생성
curl -X POST http://localhost:8001/upstreams \
  --data name=order-upstream \
  --data algorithm=round-robin \
  --data healthchecks.active.unhealthy.http_failures=3 \
  --data healthchecks.active.unhealthy.interval=10 \
  --data healthchecks.active.healthy.interval=5 \
  --data healthchecks.active.http_path=/health

# Target 추가
curl -X POST http://localhost:8001/upstreams/order-upstream/targets \
  --data target=10.0.1.1:8080 --data weight=100
curl -X POST http://localhost:8001/upstreams/order-upstream/targets \
  --data target=10.0.1.2:8080 --data weight=100
curl -X POST http://localhost:8001/upstreams/order-upstream/targets \
  --data target=10.0.1.3:8080 --data weight=50   # 절반 가중치

# Service를 Upstream으로 연결
curl -X PATCH http://localhost:8001/services/order-service \
  --data host=order-upstream

# ─── 4. 현재 설정 조회 ───────────────────────────────────────
curl http://localhost:8001/services               # 전체 서비스 목록
curl http://localhost:8001/routes                 # 전체 라우트 목록
curl http://localhost:8001/upstreams/order-upstream/health  # 헬스체크 상태
# {"data":{"available":{"weight":200},"unavailable":{},...}}

# ─── 5. Target 동적 비활성화 (배포 시 드레인) ────────────────
curl -X DELETE http://localhost:8001/upstreams/order-upstream/targets/10.0.1.3:8080
 
PLUGINS
 
05 — 플러그인 시스템

300+ 플러그인
생태계

카테고리 플러그인 주요 기능 적용 범위
인증 key-auth · jwt · oauth2 · basic-auth · ldap-auth · openid-connect API Key · JWT 검증 · OAuth2 흐름 · LDAP/OIDC SSO Global·Service·Route
보안 ip-restriction · bot-detection · cors · acl · mtls IP 허용/차단 · 봇 차단 · CORS · ACL 그룹 · mTLS Global·Service·Route
트래픽 제어 rate-limiting · request-size-limiting · response-ratelimiting · proxy-cache Rate Limit · 요청 크기 제한 · 응답 캐싱 Global·Service·Route·Consumer
변환 request-transformer · response-transformer · grpc-transcode · degraphql 헤더·바디·URL 조작 · gRPC→HTTP · GraphQL→REST Service·Route
관찰가능성 prometheus · opentelemetry · http-log · file-log · tcp-log · statsd Prometheus 메트릭 · OTel 트레이싱 · 다양한 로깅 백엔드 Global·Service·Route
AI (Kong AI) ai-proxy · ai-rate-limiting · ai-request-transformer · ai-prompt-guard LLM API 프록시 · AI 요청 변환 · 프롬프트 보안 Service·Route
 
AUTH PLUGINS
 
06 — 인증 플러그인

API 인증
Key Auth & JWT

 
bash — Key Auth + JWT + OAuth2 + OIDC 플러그인 설정
# ─── 1. Key Authentication (API Key) ─────────────────────────
# 플러그인 활성화 (Service 레벨)
curl -X POST http://localhost:8001/services/order-service/plugins \
  --data name=key-auth \
  --data config.key_names=apikey \
  --data config.hide_credentials=true   # 백엔드에 API Key 전달 숨기기

# Consumer 생성 + API Key 발급
curl -X POST http://localhost:8001/consumers \
  --data username=mobile-app \
  --data custom_id=app-001

curl -X POST http://localhost:8001/consumers/mobile-app/key-auth \
  --data key=my-super-secret-api-key   # 미지정 시 자동 생성

# 테스트 — Header 또는 Query 파라미터로 전달
curl http://localhost:8000/api/orders -H "apikey: my-super-secret-api-key"
curl "http://localhost:8000/api/orders?apikey=my-super-secret-api-key"

# ─── 2. JWT Authentication ────────────────────────────────────
curl -X POST http://localhost:8001/services/order-service/plugins \
  --data name=jwt \
  --data config.header_names=Authorization \
  --data config.claims_to_verify=exp   # 만료 시간 검증

# Consumer에 JWT Secret 발급
curl -X POST http://localhost:8001/consumers/mobile-app/jwt \
  --data algorithm=HS256 \
  --data secret=jwt-signing-secret-key

# 응답:
# {"key":"issuer-key","secret":"jwt-signing-secret-key","algorithm":"HS256"}

# JWT 토큰 생성 예시 (iss=issuer-key, exp=미래 타임스탬프)
# Header: {"alg":"HS256","typ":"JWT"}
# Payload: {"iss":"issuer-key","exp":1999999999,"user_id":"123"}

curl http://localhost:8000/api/orders \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.xxx.yyy"

# ─── 3. OpenID Connect (OIDC) ─────────────────────────────────
curl -X POST http://localhost:8001/services/order-service/plugins \
  --data name=openid-connect \
  --data config.issuer=https://accounts.google.com \
  --data config.client_id=google-client-id \
  --data config.client_secret=google-client-secret \
  --data config.redirect_uri=https://api.acme.com/callback \
  --data config.scopes=openid,email,profile \
  --data config.auth_methods[]=authorization_code \
  --data config.auth_methods[]=bearer    # Bearer 토큰도 허용

# ─── 4. Consumer별 Rate Limit 차별화 ──────────────────────────
# 일반 Consumer: 분당 100 요청
curl -X POST http://localhost:8001/consumers/mobile-app/plugins \
  --data name=rate-limiting \
  --data config.minute=100

# Enterprise Consumer: 분당 10000 요청
curl -X POST http://localhost:8001/consumers/enterprise-partner/plugins \
  --data name=rate-limiting \
  --data config.minute=10000
 
TRAFFIC
 
07 — 트래픽 제어

Rate Limiting
& 요청 변환

 
bash — Rate Limiting (Redis) + Proxy Cache + Request Transformer
# ─── 1. Rate Limiting (Redis 분산 카운터) ────────────────────
curl -X POST http://localhost:8001/services/order-service/plugins \
  --data name=rate-limiting \
  --data config.second=10       # 초당 10
  --data config.minute=100     # 분당 100
  --data config.hour=5000      # 시간당 5000
  --data config.day=100000     # 일당 10만
  --data config.policy=redis    # redis: 분산 카운터 (클러스터 동기화)
  --data config.redis_host=redis.acme.internal \
  --data config.redis_port=6379 \
  --data config.limit_by=consumer \    # consumer·ip·service·path
  --data config.error_code=429 \
  --data config.error_message="Rate limit exceeded"

# Rate Limit 응답 헤더:
# X-RateLimit-Limit-Minute: 100
# X-RateLimit-Remaining-Minute: 87
# X-RateLimit-Reset: 1700000060

# ─── 2. Proxy Cache (응답 캐싱) ──────────────────────────────
curl -X POST http://localhost:8001/services/order-service/plugins \
  --data name=proxy-cache \
  --data config.response_code=200 \
  --data config.request_method=GET \
  --data config.content_type=application/json \
  --data config.cache_ttl=300 \              # 5분 캐시
  --data config.strategy=memory \         # memory 또는 redis
  --data config.vary_headers=Accept       # 헤더 기반 캐시 분리

# ─── 3. Request Transformer ──────────────────────────────────
curl -X POST http://localhost:8001/services/order-service/plugins \
  --data name=request-transformer \
  --data config.add.headers=X-Service-Version:v2 \
  --data config.add.headers=X-Request-Start:$(date) \
  --data config.remove.headers=X-Internal-Debug \
  --data config.replace.uri=/v2/orders \   # URI 재작성
  --data config.rename.headers=X-Old:X-New

# ─── 4. Request Size Limiting ────────────────────────────────
curl -X POST http://localhost:8001/services/order-service/plugins \
  --data name=request-size-limiting \
  --data config.allowed_payload_size=10 \  # 10MB
  --data config.size_unit=megabytes

# ─── 5. Bot Detection ─────────────────────────────────────────
curl -X POST http://localhost:8001/plugins \
  --data name=bot-detection \
  --data config.deny=default \   # 알려진 봇 차단
  --data config.allow=googlebot,bingbot   # 특정 봇 허용
 
KUBERNETES
 
08 — Kubernetes

Kong Ingress
Controller

 
yaml — KIC (Kong Ingress Controller) 설정 + KongPlugin CRD
# ─── 1. Helm 설치 ─────────────────────────────────────────────
helm repo add kong https://charts.konghq.com
helm repo update

helm install kong kong/ingress \
  --namespace kong --create-namespace \
  --set controller.ingressClass=kong \
  --set proxy.type=LoadBalancer

# ─── 2. KongPlugin CRD — 플러그인 정의 ─────────────────────
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: rate-limit-api
  namespace: production
plugin: rate-limiting
config:
  minute: 100
  hour: 5000
  policy: redis
  redis_host: redis.production.svc
---
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata: {name: jwt-auth, namespace: production}
plugin: jwt
---
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata: {name: cors-policy, namespace: production}
plugin: cors
config:
  origins: ["https://app.acme.com", "https://admin.acme.com"]
  methods: [GET, POST, PUT, DELETE, OPTIONS]
  headers: [Authorization, Content-Type, X-Request-ID]
  max_age: 3600

# ─── 3. Ingress 리소스 + 플러그인 어노테이션 ─────────────────
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: order-api-ingress
  namespace: production
  annotations:
    kubernetes.io/ingress.class: kong
    # 쉼표로 여러 플러그인 체이닝
    konghq.com/plugins: rate-limit-api,jwt-auth,cors-policy
    konghq.com/strip-path: "false"
    konghq.com/connect-timeout: "5000"
    konghq.com/read-timeout: "60000"
spec:
  rules:
    - host: api.acme.com
      http:
        paths:
          - path: /api/orders
            pathType: Prefix
            backend:
              service: {name: order-service, port: {number: 8080}}
  tls:
    - {hosts: [api.acme.com], secretName: api-tls}

# ─── 4. KongConsumer CRD ─────────────────────────────────────
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
  name: mobile-app
  namespace: production
  annotations:
    kubernetes.io/ingress.class: kong
username: mobile-app
credentials:
  - mobile-app-key-secret   # Secret 리소스 이름
 
ADMIN API
 
09 — Admin API & 운영

Admin API &
Deck 선언적 관리

Kong의 모든 설정은 Admin API REST로 관리됩니다. deck(Kong Declarative Configuration) 도구를 사용하면 Git에서 Kong 설정을 선언적으로 관리하고 CI/CD로 배포할 수 있습니다.

 
bash — deck 선언적 설정 관리 + 헬스체크 + 모니터링
# ─── deck 설치 & 기본 사용 ────────────────────────────────────
brew install kong/deck/deck    # macOS

# 현재 Kong 설정을 파일로 덤프
deck gateway dump --output-file kong-state.yaml

# 변경사항 미리 확인 (dry-run)
deck gateway diff kong-state.yaml
# + creating service order-service
# ~ updating plugin rate-limiting on service order-service
# Summary: 1 creates, 1 updates, 0 deletes

# 실제 적용
deck gateway sync kong-state.yaml

# ─── 설정 유효성 검증 (CI에서 활용) ─────────────────────────
deck validate kong-state.yaml
# valid

# ─── Admin API — 상태 확인 ────────────────────────────────────
# Kong 인스턴스 상태
curl http://localhost:8001/status
# {"database":{"reachable":true},"memory":{"lua_shared_dicts":{...}}}

# 활성 플러그인 목록
curl http://localhost:8001/plugins | jq '.data[].name'

# Upstream 헬스체크 상태
curl http://localhost:8001/upstreams/order-upstream/health
# {"data":{"available":{"weight":200,"http_statuses":{"200":{"weight":100}}},...}}

# Target 강제 UP/DOWN (무중단 배포)
curl -X PUT http://localhost:8001/upstreams/order-upstream/targets/10.0.1.3:8080/healthy
curl -X PUT http://localhost:8001/upstreams/order-upstream/targets/10.0.1.1:8080/unhealthy

# ─── Prometheus 메트릭 핵심 쿼리 ─────────────────────────────
# 서비스별 총 요청 수
sum(kong_http_requests_total{service="order-service"}) by (status)

# 서비스별 에러율
sum(rate(kong_http_requests_total{service="order-service",status=~"5.."}[5m]))
/ sum(rate(kong_http_requests_total{service="order-service"}[5m]))

# p99 업스트림 레이턴시
histogram_quantile(0.99,
  sum(rate(kong_latency_ms_bucket{type="upstream",service="order-service"}[5m]))
  by (le, service)
)

# Rate Limit 초과 카운트
sum(increase(kong_http_requests_total{
  service="order-service", status="429"
}[1h]))
 
CHECKLIST
 
10 — 체크리스트

Kong
완전 점검

설치 & 기본 보안

  •  
    Admin API 외부 노출 금지 — KONG_ADMIN_LISTEN=127.0.0.1:8001
  •  
    Admin API 접근 제어 — 내부 네트워크만 허용 또는 키 인증 설정
  •  
    Global 기본 인증 플러그인 활성화 — 모든 Route에 기본 보호
  •  
    DB 모드: PostgreSQL 복제 + 백업 설정 (단일 DB는 SPOF)
  •  
    DB-less 모드 + deck GitOps — 설정 변경 이력 Git으로 관리

플러그인 & 트래픽

  •  
    Rate Limiting 정책 redis — 클러스터 모드에서 카운터 동기화
  •  
    Consumer별 차별화 Rate Limit — Enterprise 파트너 상위 한도
  •  
    인증 없이 Route 노출 — 모든 Route에 최소 key-auth 또는 JWT 적용
  •  
    Proxy Cache 플러그인 — GET 요청 캐싱으로 백엔드 부하 감소
  •  
    플러그인 Phase 순서 이해 — access→rewrite 순서 충돌 주의

Kubernetes & 운영

  •  
    deck CI/CD 통합 — PR에서 deck diff로 변경사항 미리 검토
  •  
    Prometheus + Grafana Kong 공식 대시보드 구성
  •  
    Upstream 액티브 헬스체크 설정 — 장애 백엔드 자동 제외
  •  
    KIC replicas 2+ — 단일 Ingress Controller 장애 방지
  •  
    Kong AI 플러그인 검토 — LLM API 프록시·Rate Limit·보안
Kong API Gateway OpenResty Key Auth JWT Rate Limiting KIC deck Kong AI

반응형

댓글