Files
2nd/10_Wiki/Topics/Coding/API_Gateway_Kong_Envoy.md
T
2026-05-09 22:47:42 +09:00

8.5 KiB

id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
id title category status source_trust_level verification_status created_at updated_at tags tech_stack applied_in aliases
api-gateway-kong-envoy API Gateway — Kong / Envoy / Tyk Coding draft B conceptual 2026-05-09 2026-05-09
api
gateway
infrastructure
vibe-coding
language applicable_to
Lua / YAML
Backend
Infrastructure
API gateway
Kong
Envoy
Tyk
Apigee
Krakend
Traefik

API Gateway

모든 API request 의 entry point. Auth, rate limit, transform, route, observability 한 곳. Kong / Envoy / Tyk / Krakend / Apigee.

📖 핵심 개념

  • L7 proxy + plugins.
  • Service discovery + routing.
  • Cross-cutting concern (auth, rate, log).
  • Backend service 가 비즈니스만.

💻 코드 패턴

Kong (declarative)

# kong.yaml
_format_version: "3.0"

services:
  - name: user-api
    url: http://users:8080
    routes:
      - name: user-route
        paths: [/api/users]
    plugins:
      - name: rate-limiting
        config: { minute: 100 }
      - name: jwt
      - name: prometheus
# DB-less mode
kong start -c kong.conf --vv

→ DB-less = config file. DB mode = postgres / cassandra.

Kong Konnect / Enterprise

  • Managed control plane
  • Multi-region
  • Plugin marketplace
  • DevPortal

Envoy (xDS)

# envoy.yaml
static_resources:
  listeners:
    - address:
        socket_address: { address: 0.0.0.0, port_value: 8080 }
      filter_chains:
        - filters:
            - name: envoy.filters.network.http_connection_manager
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                route_config:
                  virtual_hosts:
                    - name: backend
                      domains: ["*"]
                      routes:
                        - match: { prefix: "/" }
                          route: { cluster: backend }
                http_filters:
                  - name: envoy.filters.http.jwt_authn
                  - name: envoy.filters.http.ratelimit
                  - name: envoy.filters.http.router
  clusters:
    - name: backend
      load_assignment:
        cluster_name: backend
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address: { address: backend, port_value: 8080 }

→ Istio / service mesh 의 데이터 plane.

Tyk

curl -H "X-Tyk-Authorization: $KEY" \
  -X POST http://gateway:8080/tyk/apis \
  -d @api.json

curl -X POST http://gateway:8080/tyk/reload

→ API 별 JSON config + hot reload.

Krakend (declarative, fast)

{
  "version": 3,
  "endpoints": [
    {
      "endpoint": "/api/user/{id}",
      "method": "GET",
      "backend": [
        { "url_pattern": "/users/{id}", "host": ["http://users:8080"] }
      ],
      "extra_config": {
        "qos/ratelimit/router": { "max_rate": 100, "client_max_rate": 10 }
      }
    }
  ]
}

→ Aggregator (여러 backend 합쳐 1 response).

Plugin / filter

- Authentication (JWT, OAuth, API key)
- Rate limiting
- Request / response transform
- Logging / tracing
- Caching
- CORS
- Body validation
- IP filtering
- Bot detection

JWT validation (Kong)

plugins:
  - name: jwt
    config:
      uri_param_names: [token]
      claims_to_verify: [exp]
# Consumer 등록
curl -X POST http://kong:8001/consumers -d "username=alice"
curl -X POST http://kong:8001/consumers/alice/jwt -d "key=alice-key"

Rate limiting (Kong)

plugins:
  - name: rate-limiting
    config:
      second: 5
      minute: 30
      hour: 1000
      policy: redis
      redis_host: redis

→ Local (per node) vs cluster (redis).

Request transform

- name: request-transformer
  config:
    add:
      headers: ["X-User: $(jwt.sub)"]
    remove:
      headers: ["Authorization"]

gRPC gateway

# Envoy
- name: envoy.filters.http.grpc_web
- name: envoy.filters.http.grpc_json_transcoder
  typed_config:
    proto_descriptor: "/etc/proto.pb"
    services: ["user.UserService"]

→ gRPC 가 REST / web 으로.

Canary deploy

# Envoy weighted_clusters
routes:
  - match: { prefix: "/" }
    route:
      weighted_clusters:
        clusters:
          - { name: backend-v1, weight: 90 }
          - { name: backend-v2, weight: 10 }

→ 10% 트래픽 v2.

routes:
  - match:
      prefix: "/"
      headers: [{ name: "x-user-segment", exact_match: "beta" }]
    route: { cluster: backend-beta }
  - match: { prefix: "/" }
    route: { cluster: backend-prod }

Observability

- Access log → ELK / Loki
- Metrics → Prometheus (RED / USE)
- Tracing → Jaeger / Zipkin / OTel
- Audit log (auth events)

→ Gateway 가 모두 한 곳.

Hot reload

# Envoy
envoy --hot-restart

# Kong
kong reload

→ Config 변경 — connection drop X.

mTLS

# Service mesh (Istio + Envoy)
mtls:
  mode: STRICT

→ Service-to-service 자동 TLS.

Header injection (request 추적)

- name: correlation-id
  config:
    header_name: X-Request-ID
    generator: uuid
    echo_downstream: true

CORS

- name: cors
  config:
    origins: ["https://app.com"]
    methods: ["GET", "POST"]
    credentials: true
    max_age: 3600

Bot / DDoS

- name: ip-restriction
  config:
    deny: ["192.168.1.0/24"]

- name: bot-detection
  config:
    deny:
      - "(?i)(bot|crawler|spider)"

Body / response cache

- name: proxy-cache
  config:
    response_code: [200]
    request_method: [GET]
    content_type: ["application/json"]
    cache_ttl: 300
    strategy: memory

GraphQL

- name: graphql-rate-limiting
  config:
    cost_strategy: node_quantifier  # query complexity
    max_cost: 1000

AWS API Gateway

# Serverless framework
functions:
  api:
    handler: handler.api
    events:
      - http:
          path: users/{id}
          method: get
          cors: true
          authorizer: aws_iam

→ Managed, Lambda 친화. 큰 traffic 비쌈.

Cloudflare Workers + WAF

// Cloudflare Worker = edge gateway
export default {
  async fetch(req: Request) {
    if (await isBot(req)) return new Response('blocked', { status: 403 });
    return fetch('https://backend' + new URL(req.url).pathname, req);
  },
};

→ Edge 의 가벼운 gateway.

NGINX (간단 gateway)

upstream backend { server backend:8080; }

location /api/ {
    auth_jwt "Realm" token=$arg_token;
    auth_jwt_key_file /etc/nginx/jwt.key;
    
    limit_req zone=api burst=10;
    proxy_pass http://backend/;
}

→ NGINX Plus = enterprise feature.

Service mesh vs gateway

Gateway: north-south (외부 → 내부)
Service mesh: east-west (서비스 간)

→ 큰 system 가 둘 다.
Service mesh = Istio / Linkerd / Consul.

Custom gateway (Hono / Bun)

import { Hono } from 'hono';
const app = new Hono();

app.use('*', async (c, next) => {
  // JWT validate
  const token = c.req.header('authorization')?.replace('Bearer ', '');
  if (!verifyJwt(token)) return c.text('unauthorized', 401);
  await next();
});

app.use('*', rateLimit({ max: 100, window: 60 }));

app.all('/api/users/*', async (c) => {
  return fetch('http://users:8080' + c.req.path, c.req.raw);
});

→ 작은 / 특화 gateway.

Cost / 선택

Kong: 큰 ecosystem, 가장 인기
Envoy: 가장 빠름, complex config
Tyk: 좋은 UI, dashboard
Krakend: simple, 빠름, declarative
Traefik: K8s 친화, automatic
NGINX: legacy 강함
AWS API Gateway: serverless 친화
Cloudflare: edge

🤔 의사결정 기준

상황 추천
일반 API Kong / Tyk
가장 빠름 Envoy / Krakend
Service mesh Istio (Envoy)
K8s 친화 Traefik / Kong K8s
Serverless AWS API Gateway
Edge Cloudflare Workers
작은 / custom Hono / NGINX
Aggregator Krakend / Apollo gateway

안티패턴

  • 모든 logic 가 gateway: 비즈니스 분리.
  • No rate limit: DDoS 취약.
  • No auth at gateway: 매 service 다.
  • Hot reload 없음: 매번 down.
  • No observability: blind.
  • DB mode + single Postgres: SPOF.
  • Plugin 너무 많음: latency 누적.

🤖 LLM 활용 힌트

  • Kong / Envoy 가 default 후보.
  • Auth + rate + log = baseline plugin.
  • Hot reload 필수 (zero-downtime).
  • Service mesh 가 east-west.

🔗 관련 문서