Skip to content
← All Skills
🦍

Kong Gateway

InfrastructureOfficial Site ›

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

bash
# 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 | jq

Architecture 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 ทุกอย่าง:

yaml
_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, method GET, host api.example.com
  • หนึ่ง service มีได้หลาย routes — ใช้ paths, methods, hosts, headers match request

Admin API

Kong มี Admin API (default port 8001) สำหรับจัดการ config แบบ dynamic:

  • POST /services — สร้าง service ใหม่
  • POST /services/{id}/routes — เพิ่ม route ให้ service
  • POST /plugins — เปิด plugin
  • POST /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/query
  • jwt — validate JWT token
  • oauth2 — OAuth 2.0 flow
  • basic-auth — username/password

Traffic Control:

  • rate-limiting — จำกัด requests per second/minute/hour
  • request-size-limiting — จำกัด request body size
  • proxy-cache — cache response ลด load ไป upstream

Logging & Monitoring:

  • file-log — log ลง file
  • http-log — ส่ง log ไป HTTP endpoint
  • prometheus — expose metrics สำหรับ Prometheus scrape

Transformations:

  • request-transformer — แก้ headers/body ก่อนส่งไป upstream
  • response-transformer — แก้ response ก่อนส่งกลับ client
  • cors — จัดการ 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 ใช้ redis policy สำหรับ 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-ID header, 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

yaml
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: ถ้าเป็น true Kong จะตัด matched path ออก เช่น /api/v1/users/123 → upstream ได้ /123
  • Kong match route ที่ specific ที่สุดก่อน — /api/v1/users match ก่อน /api
  • ใช้ curl -i http://localhost:8000/path ดู response headers X-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