Kong Gateway
API Gateway — routing, rate limiting, authentication, load balancing สำหรับ microservices
What I Can Do
- ตั้งค่า Kong Gateway เป็น API Gateway สำหรับ microservices architecture
- ออกแบบ routing rules, service discovery, upstream load balancing
- Configure plugins สำหรับ auth, rate limiting, logging, CORS
- จัดการ consumers, credentials, ACL สำหรับ multi-tenant APIs
- Monitor API traffic ด้วย logging และ metrics plugins
Commands I Use Daily
# run Kong ด้วย Docker (DB-less mode)
docker run -d --name kong \
-e "KONG_DATABASE=off" \
-e "KONG_DECLARATIVE_CONFIG=/kong/kong.yml" \
-e "KONG_PROXY_LISTEN=0.0.0.0:8000" \
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \
-v $(pwd)/kong.yml:/kong/kong.yml \
-p 8000:8000 -p 8001:8001 \
kong:latest
# ดู services ทั้งหมด
curl -s http://localhost:8001/services | jq
# ดู routes ทั้งหมด
curl -s http://localhost:8001/routes | jq
# ดู plugins ที่ active
curl -s http://localhost:8001/plugins | jq
# ตรวจ Kong status
curl -s http://localhost:8001/status | jqArchitecture Overview
Kong ทำงานเป็น reverse proxy ระหว่าง client กับ backend services — ทุก request ผ่าน Kong ก่อนถึง service จริง ทำให้จัดการ cross-cutting concerns (auth, rate limit, logging) ที่จุดเดียว ไม่ต้องใส่ logic ซ้ำในแต่ละ service
DB-less vs Database Mode
- DB-less (Declarative) — config ทั้งหมดอยู่ใน YAML file, ไม่ต้อง database, เหมาะกับ GitOps/CI-CD, restart ก็ reload config
- Database Mode (PostgreSQL/Cassandra) — config เก็บใน DB, แก้ผ่าน Admin API ได้ทันที, เหมาะกับ dynamic environment ที่เปลี่ยน config บ่อย
Declarative Configuration (kong.yml)
DB-less mode ใช้ YAML config file เดียว define ทุกอย่าง:
_format_version: "3.0"
services:
- name: user-service
url: http://user-svc:8080
routes:
- name: user-routes
paths:
- /api/v1/users
strip_path: true
- name: order-service
url: http://order-svc:8080
routes:
- name: order-routes
paths:
- /api/v1/orders
strip_path: true
plugins:
- name: rate-limiting
config:
minute: 100
policy: local
- name: cors
config:
origins: ["*"]
methods: ["GET", "POST", "PUT", "PATCH", "DELETE"]Services & Routes
- Service — upstream backend ที่ Kong proxy ไป เช่น
http://user-svc:8080 - Route — กฎที่ match incoming request เข้า service เช่น path
/api/v1/users, methodGET, hostapi.example.com - หนึ่ง service มีได้หลาย routes — ใช้
paths,methods,hosts,headersmatch request
Admin API
Kong มี Admin API (default port 8001) สำหรับจัดการ config แบบ dynamic:
POST /services— สร้าง service ใหม่POST /services/{id}/routes— เพิ่ม route ให้ servicePOST /plugins— เปิด pluginPOST /consumers— สร้าง consumer (API user)- production ต้องปิด Admin API จาก public — expose เฉพาะ internal network
Plugins
Plugin คือ core ของ Kong — เพิ่ม functionality โดยไม่ต้องแก้ code, apply ได้ทั้ง global, per-service, per-route, per-consumer
Authentication:
key-auth— API key ใน header/queryjwt— validate JWT tokenoauth2— OAuth 2.0 flowbasic-auth— username/password
Traffic Control:
rate-limiting— จำกัด requests per second/minute/hourrequest-size-limiting— จำกัด request body sizeproxy-cache— cache response ลด load ไป upstream
Logging & Monitoring:
file-log— log ลง filehttp-log— ส่ง log ไป HTTP endpointprometheus— expose metrics สำหรับ Prometheus scrape
Transformations:
request-transformer— แก้ headers/body ก่อนส่งไป upstreamresponse-transformer— แก้ response ก่อนส่งกลับ clientcors— จัดการ CORS headers
Consumers & Credentials
Consumer = API user ที่ Kong track — สร้าง consumer แล้วผูก credentials (API key, JWT, OAuth)
- ใช้จัดการ rate limit per consumer
- ใช้กับ ACL plugin กำหนดสิทธิ์ access per group
- ใช้ track API usage per consumer
Upstreams & Load Balancing
Kong ทำ load balancing ได้ในตัว — กำหนด upstream + targets (backend instances):
- Round-robin — default, กระจาย request เท่าๆ กัน
- Consistent hashing — route request ไป target เดิมตาม header/cookie/IP
- Least connections — ส่งไป target ที่มี active connections น้อยสุด
- Health checks: active (Kong probe targets) + passive (ดูจาก response)
Rate Limiting
rate-limiting plugin — กำหนด limit per second/minute/hour/day/month/year
- Apply per consumer, per route, หรือ global
- Policy:
local(in-memory per node),cluster(shared across nodes ผ่าน DB),redis(shared ผ่าน Redis) - Production ใช้
redispolicy สำหรับ consistent rate limiting across Kong nodes
Authentication Plugins
Key Auth — ง่ายสุด client ส่ง apikey header:
- สร้าง consumer → สร้าง key-auth credential → client ใช้ key นั้น
- เหมาะกับ internal services, server-to-server
JWT — validate JWT token โดยไม่ต้อง forward ไป backend:
- Kong verify signature + expiry → ถ้าผ่านก็ forward request ไป upstream
- ลด load จาก backend ที่ไม่ต้อง validate JWT ทุก request
Request/Response Transformation
แก้ไข request/response ระหว่างทาง — ไม่ต้องแก้ code ของ backend:
- เพิ่ม/ลบ/แก้ headers
- เพิ่ม/ลบ/แก้ query parameters
- เพิ่ม/ลบ/แก้ body fields
- เช่น inject
X-Request-IDheader, strip internal headers ก่อนส่งกลับ client
Health Checks
- Active — Kong ส่ง request ไป health endpoint ของ target เป็นระยะ ถ้าไม่ตอบก็ mark unhealthy
- Passive — ดูจาก actual traffic ถ้า response error เกิน threshold ก็ mark unhealthy
- Unhealthy targets ถูก remove จาก load balancer อัตโนมัติ — กลับมาเมื่อ healthy
Kong with Docker Compose
services:
kong:
image: kong:latest
environment:
KONG_DATABASE: "off"
KONG_DECLARATIVE_CONFIG: /kong/kong.yml
KONG_PROXY_LISTEN: 0.0.0.0:8000
KONG_ADMIN_LISTEN: 0.0.0.0:8001
KONG_LOG_LEVEL: info
volumes:
- ./kong.yml:/kong/kong.yml
ports:
- "8000:8000"
- "8001:8001"
networks:
- backend
user-service:
build: ./services/user
networks:
- backend
order-service:
build: ./services/order
networks:
- backend
networks:
backend:Kong in Production
- ปิด Admin API จาก public —
KONG_ADMIN_LISTEN=127.0.0.1:8001หรือ expose เฉพาะ internal network - เปิด access logs + error logs สำหรับ monitoring
- ใช้ Prometheus plugin + Grafana dashboard monitor API traffic
- ตั้ง rate limiting ป้องกัน abuse
- ใช้ DB-less mode + GitOps สำหรับ config management ที่ traceable
ปัญหาที่เจอบ่อย & วิธีแก้
502 Bad Gateway — Kong เชื่อมต่อ upstream ไม่ได้
Request ผ่าน Kong แล้วได้ 502 กลับมา
สาเหตุ: service URL ผิด, upstream service ยังไม่ start, Docker network ไม่ตรงกัน (Kong กับ service อยู่คนละ network), DNS resolve ไม่ได้
วิธีแก้:
- ตรวจ service URL ว่าถูก:
curl http://localhost:8001/servicesดูhostและport - ตรวจว่า upstream service running:
docker psดู container status - ตรวจ Docker network: Kong กับ service ต้องอยู่ network เดียวกัน
- ลอง exec เข้า Kong container แล้ว curl ไป upstream ตรงๆ:
docker exec kong curl http://user-svc:8080/health
Route match ไม่ถูก — request ไปผิด service
Request ไป path หนึ่งแต่ Kong route ไปอีก service
สาเหตุ: หลาย routes มี overlapping paths, strip_path ตั้งไม่ถูก ทำให้ upstream ได้ path ผิด, route priority ไม่ตรงที่คิด
วิธีแก้:
- ตรวจ routes ทั้งหมด:
curl http://localhost:8001/routesดู paths ที่ซ้ำกัน - เข้าใจ
strip_path: ถ้าเป็นtrueKong จะตัด matched path ออก เช่น/api/v1/users/123→ upstream ได้/123 - Kong match route ที่ specific ที่สุดก่อน —
/api/v1/usersmatch ก่อน/api - ใช้
curl -i http://localhost:8000/pathดู response headersX-Kong-Upstream-*ตรวจว่าไป service ไหน
Rate limiting ไม่ sync ข้าม nodes
Run Kong หลาย instances แต่ rate limit counter ไม่ตรงกัน
สาเหตุ: ใช้ policy: local ซึ่งเก็บ counter ใน memory ของแต่ละ node — ถ้ามี 3 nodes client จะ get 3x limit
วิธีแก้:
- เปลี่ยนเป็น
policy: redis+ ตั้ง Redis connection — ทุก node share counter เดียวกัน policy: clusterใช้ได้ถ้า run database mode (PostgreSQL) — แต่ Redis เร็วกว่า- สำหรับ single node ใช้
localได้ปกติ
Plugin ไม่ทำงาน — enable แล้วแต่ไม่มีผล
เปิด plugin แล้วแต่ request ยังผ่านได้โดยไม่ถูก enforce
สาเหตุ: plugin apply ผิด scope (global vs service vs route), plugin config ผิด, plugin enabled แต่ route ที่ต้องการไม่ได้ผูก
วิธีแก้:
- ตรวจ plugin scope:
curl http://localhost:8001/pluginsดูservice.idและroute.idว่าตรงไหม - ตรวจ plugin config: field ที่ required ใส่ครบไหม
- ทดสอบด้วย
curl -iดู response headers — Kong จะใส่ headers บอกว่า plugin ไหนทำงาน - DB-less mode: ตรวจว่า reload config แล้ว —
kong reloadหรือ restart container
Admin API ถูก expose สู่ public
Admin API (port 8001) เข้าถึงได้จาก internet — ใครก็แก้ config ได้
สาเหตุ: ตั้ง KONG_ADMIN_LISTEN=0.0.0.0:8001 แล้ว expose port ออก public, firewall ไม่ได้ block
วิธีแก้:
- ตั้ง
KONG_ADMIN_LISTEN=127.0.0.1:8001— listen เฉพาะ localhost - Docker: ไม่ expose port 8001 ออก host หรือ map เป็น
127.0.0.1:8001:8001 - ใช้ firewall rules block port 8001 จาก external traffic
- ถ้าต้องการ remote access: ใช้ SSH tunnel หรือ VPN
Config reload ไม่ apply — DB-less mode
แก้ kong.yml แล้ว reload แต่ config ไม่เปลี่ยน
สาเหตุ: YAML syntax error ทำให้ Kong reject config ใหม่แต่ยังใช้ config เก่า, volume mount ไม่ถูก ทำให้ container ยังเห็นไฟล์เก่า
วิธีแก้:
- ตรวจ YAML syntax:
kong config parse /kong/kong.ymlก่อน reload - ดู Kong error logs:
docker logs kongหา config parse errors - ตรวจ volume mount:
docker exec kong cat /kong/kong.ymlดูว่าไฟล์ update จริงไหม - ถ้า reload ไม่ work: restart container
docker restart kong
Related Skills
- Docker — containerize Kong Gateway
- Gin — Go backend services หลัง Kong
- Fiber — Go backend services หลัง Kong
- REST API Design — API design ที่ route ผ่าน Kong
- Redis — shared rate limiting store สำหรับ Kong cluster