[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -0,0 +1,412 @@
|
||||
---
|
||||
id: api-gateway-kong-envoy
|
||||
title: API Gateway — Kong / Envoy / Tyk
|
||||
category: Coding
|
||||
status: draft
|
||||
source_trust_level: B
|
||||
verification_status: conceptual
|
||||
created_at: 2026-05-09
|
||||
updated_at: 2026-05-09
|
||||
tags: [api, gateway, infrastructure, vibe-coding]
|
||||
tech_stack: { language: "Lua / YAML", applicable_to: ["Backend", "Infrastructure"] }
|
||||
applied_in: []
|
||||
aliases: [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)
|
||||
```yaml
|
||||
# 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
|
||||
```
|
||||
|
||||
```bash
|
||||
# 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)
|
||||
```yaml
|
||||
# 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
|
||||
```bash
|
||||
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)
|
||||
```json
|
||||
{
|
||||
"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)
|
||||
```yaml
|
||||
plugins:
|
||||
- name: jwt
|
||||
config:
|
||||
uri_param_names: [token]
|
||||
claims_to_verify: [exp]
|
||||
```
|
||||
|
||||
```bash
|
||||
# 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)
|
||||
```yaml
|
||||
plugins:
|
||||
- name: rate-limiting
|
||||
config:
|
||||
second: 5
|
||||
minute: 30
|
||||
hour: 1000
|
||||
policy: redis
|
||||
redis_host: redis
|
||||
```
|
||||
|
||||
→ Local (per node) vs cluster (redis).
|
||||
|
||||
### Request transform
|
||||
```yaml
|
||||
- name: request-transformer
|
||||
config:
|
||||
add:
|
||||
headers: ["X-User: $(jwt.sub)"]
|
||||
remove:
|
||||
headers: ["Authorization"]
|
||||
```
|
||||
|
||||
### gRPC gateway
|
||||
```yaml
|
||||
# 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
|
||||
```yaml
|
||||
# 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)
|
||||
```yaml
|
||||
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
|
||||
```bash
|
||||
# Envoy
|
||||
envoy --hot-restart
|
||||
|
||||
# Kong
|
||||
kong reload
|
||||
```
|
||||
|
||||
→ Config 변경 — connection drop X.
|
||||
|
||||
### mTLS
|
||||
```yaml
|
||||
# Service mesh (Istio + Envoy)
|
||||
mtls:
|
||||
mode: STRICT
|
||||
```
|
||||
|
||||
→ Service-to-service 자동 TLS.
|
||||
|
||||
### Header injection (request 추적)
|
||||
```yaml
|
||||
- name: correlation-id
|
||||
config:
|
||||
header_name: X-Request-ID
|
||||
generator: uuid
|
||||
echo_downstream: true
|
||||
```
|
||||
|
||||
### CORS
|
||||
```yaml
|
||||
- name: cors
|
||||
config:
|
||||
origins: ["https://app.com"]
|
||||
methods: ["GET", "POST"]
|
||||
credentials: true
|
||||
max_age: 3600
|
||||
```
|
||||
|
||||
### Bot / DDoS
|
||||
```yaml
|
||||
- name: ip-restriction
|
||||
config:
|
||||
deny: ["192.168.1.0/24"]
|
||||
|
||||
- name: bot-detection
|
||||
config:
|
||||
deny:
|
||||
- "(?i)(bot|crawler|spider)"
|
||||
```
|
||||
|
||||
### Body / response cache
|
||||
```yaml
|
||||
- name: proxy-cache
|
||||
config:
|
||||
response_code: [200]
|
||||
request_method: [GET]
|
||||
content_type: ["application/json"]
|
||||
cache_ttl: 300
|
||||
strategy: memory
|
||||
```
|
||||
|
||||
### GraphQL
|
||||
```yaml
|
||||
- name: graphql-rate-limiting
|
||||
config:
|
||||
cost_strategy: node_quantifier # query complexity
|
||||
max_cost: 1000
|
||||
```
|
||||
|
||||
### AWS API Gateway
|
||||
```yaml
|
||||
# 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
|
||||
```ts
|
||||
// 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)
|
||||
```nginx
|
||||
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)
|
||||
```ts
|
||||
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.
|
||||
|
||||
## 🔗 관련 문서
|
||||
- [[Backend_API_Gateway_BFF]]
|
||||
- [[DevOps_Service_Mesh_Deep]]
|
||||
- [[Backend_Rate_Limiting]]
|
||||
Reference in New Issue
Block a user