API网关完整部署指南:Kong在香港VPS上实现限流、鉴权与日志管理实

随着业务发展,后端API数量增多,逐个管理鉴权、限流、日志变得越来越复杂。API网关统一处理这些横切关注点,让后端服务专注于业务逻辑。Kong是目前最流行的开源API网关,本文给出在香港VPS上的完整部署方案。

一、API网关解决的核心问题

问题没有API网关有API网关
身份鉴权每个后端服务自己实现网关统一处理,后端只接受已鉴权请求
速率限制各服务各自实现或没有网关按IP/用户/API Key统一限流
请求日志分散在各服务统一记录所有API请求
SSL终止各服务自己处理HTTPS网关统一处理,后端走HTTP
跨域(CORS)各服务各自配置网关统一配置CORS头
请求转换后端需要额外代码处理网关层转换请求头/参数

二、Kong部署(Docker Compose)

mkdir -p /srv/kong && cd /srv/kong
# docker-compose.yml
version: '3.8'

services:
  kong-db:
    image: postgres:15
    restart: always
    environment:
      POSTGRES_USER: kong
      POSTGRES_DB: kong
      POSTGRES_PASSWORD: 你的数据库密码
    volumes:
      - kong_db:/var/lib/postgresql/data

  kong-migration:
    image: kong:3.5
    depends_on:
      - kong-db
    environment:
      KONG_DATABASE: postgres
      KONG_PG_HOST: kong-db
      KONG_PG_USER: kong
      KONG_PG_PASSWORD: 你的数据库密码
      KONG_PG_DATABASE: kong
    command: kong migrations bootstrap

  kong:
    image: kong:3.5
    restart: always
    depends_on:
      - kong-db
    environment:
      KONG_DATABASE: postgres
      KONG_PG_HOST: kong-db
      KONG_PG_USER: kong
      KONG_PG_PASSWORD: 你的数据库密码
      KONG_PG_DATABASE: kong
      KONG_PROXY_LISTEN: 0.0.0.0:8000, 0.0.0.0:8443 ssl
      KONG_ADMIN_LISTEN: 127.0.0.1:8001   # 管理API只监听本地
      KONG_PROXY_ACCESS_LOG: /dev/stdout
      KONG_ADMIN_ACCESS_LOG: /dev/stdout
      KONG_PROXY_ERROR_LOG: /dev/stderr
      KONG_ADMIN_ERROR_LOG: /dev/stderr
    ports:
      - "8000:8000"    # HTTP入口
      - "8443:8443"    # HTTPS入口
    healthcheck:
      test: ["CMD", "kong", "health"]
      interval: 30s
      timeout: 10s
      retries: 3

  konga:
    image: pantsel/konga:latest
    restart: always
    depends_on:
      - kong
    environment:
      NODE_ENV: production
      DB_ADAPTER: postgres
      DB_HOST: kong-db
      DB_USER: kong
      DB_PASSWORD: 你的数据库密码
      DB_DATABASE: konga
    ports:
      - "1337:1337"

volumes:
  kong_db:
# 初始化并启动
docker compose up -d kong-db
sleep 10
docker compose run --rm kong-migration
docker compose up -d kong konga

三、配置服务与路由

Kong使用REST API(Admin API)进行配置,也可以通过Konga图形界面操作:

# 创建一个Service(指向后端API服务器)
curl -i -X POST http://127.0.0.1:8001/services \
  --data name=user-api \
  --data url=http://后端服务器内网IP:3000

# 为该Service创建路由(定义外部访问路径)
curl -i -X POST http://127.0.0.1:8001/services/user-api/routes \
  --data 'paths[]=/api/v1/users' \
  --data methods[]=GET \
  --data methods[]=POST

# 验证路由生效
curl http://localhost:8000/api/v1/users

四、JWT鉴权插件配置

# 为user-api Service开启JWT鉴权
curl -i -X POST http://127.0.0.1:8001/services/user-api/plugins \
  --data name=jwt \
  --data config.claims_to_verify=exp

# 创建Consumer(API使用方)
curl -i -X POST http://127.0.0.1:8001/consumers \
  --data username=frontend-app

# 为Consumer生成JWT凭证
curl -i -X POST http://127.0.0.1:8001/consumers/frontend-app/jwt

# 返回:
# {
#   "key": "xxxxxxxxxx",          ← JWT的iss(issuer)
#   "secret": "yyyyyyyyyy",       ← 签名密钥
#   "algorithm": "HS256"
# }

生成JWT Token(Node.js示例)

const jwt = require('jsonwebtoken');

const token = jwt.sign(
  {
    iss: 'xxxxxxxxxx',    // 上面返回的key
    exp: Math.floor(Date.now() / 1000) + (60 * 60)  // 1小时过期
  },
  'yyyyyyyyyy'           // 上面返回的secret
);

// 请求时在Header中携带
// Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

五、速率限制插件

# 全局限流:每个IP每分钟最多100次请求
curl -i -X POST http://127.0.0.1:8001/plugins \
  --data name=rate-limiting \
  --data config.minute=100 \
  --data config.hour=1000 \
  --data config.policy=local

# 针对特定Service限流(更严格)
curl -i -X POST http://127.0.0.1:8001/services/user-api/plugins \
  --data name=rate-limiting \
  --data config.minute=20 \
  --data config.limit_by=consumer  # 按Consumer(API Key)限流

六、请求日志插件

# HTTP日志插件(发送到日志收集服务)
curl -i -X POST http://127.0.0.1:8001/plugins \
  --data name=http-log \
  --data config.http_endpoint=http://日志收集服务IP:端口/logs \
  --data config.method=POST \
  --data config.timeout=1000 \
  --data config.keepalive=1000

# 文件日志插件(写入本地文件)
curl -i -X POST http://127.0.0.1:8001/plugins \
  --data name=file-log \
  --data config.path=/var/log/kong/requests.log

七、Nginx反向代理Kong

<code">server {
    listen 443 ssl http2;
    server_name api.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

# Konga管理界面(限制IP访问)
server {
    listen 443 ssl;
    server_name kong-admin.yourdomain.com;

    allow 你的办公室IP;
    deny all;

    location / {
        proxy_pass http://127.0.0.1:1337;
    }
}

八、总结

Kong API网关将鉴权、限流、日志等横切关注点从业务代码中剥离,让后端服务更专注于业务逻辑,同时提供统一的安全防线。IDC.Net的香港VPS配合内网多节点互通,是部署Kong + 后端服务分离架构的理想基础设施,2核4G配置即可流畅运行Kong网关服务。

THE END