8.5 KiB
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
모든 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.
A/B test (header / cookie)
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.