Kong Gateway

高性能なAPI Gateway・サービス接続プラットフォーム。マイクロサービス、サーバーレス、レガシーワークロードを統合。プラグインエコシステムで拡張可能。

API GatewayマイクロサービスLuaOpenRestyプラグイン高性能レート制限認証モニタリング

概要

Kong Gatewayは、高性能なオープンソースのAPI Gateway・サービス接続プラットフォームです。Nginxベースで構築され、Luaスクリプトによる拡張機能を提供します。マイクロサービス、サーバーレス、レガシーワークロードを統合し、豊富なプラグインエコシステムによる拡張性が特徴です。

2015年にMashapeによって開発され、現在はKong Inc.が開発・保守を行っています。Fortune 500企業の多くが採用する、API Gateway市場のリーダー的存在です。

主要な特徴

  • 高性能・軽量: Nginxベースで非同期処理による高スループットを実現
  • プラグインエコシステム: 50以上の公式プラグインと豊富なサードパーティプラグイン
  • 複数のデプロイメントモード: DB-less、Hybrid、Traditional DBモード
  • マルチプロトコル対応: HTTP/HTTPS、gRPC、GraphQL、WebSocket
  • スケーラビリティ: 水平スケーリングに対応

主要機能

コア機能

  • プロキシとルーティング: 高度なロードバランシングとリクエスト・レスポンス変換
  • 認証・認可: JWT、OAuth 2.0、Basic Auth、APIキー認証
  • レート制限: 柔軟なレート制限ポリシー
  • サービスディスカバリ: 動的なサービス登録・発見
  • ログとモニタリング: 詳細なアクセスログと統計情報

プラグインによる拡張機能

  • セキュリティ: CORS、IP制限、Bot Detection
  • 変換: Request/Response Transformer、XMLからJSONへの変換
  • 分析: Google Analytics、Datadog、Prometheus統合
  • トラフィック制御: Circuit Breaker、Request Size Limiting

インストール・セットアップ

Dockerを使用したインストール

DB-lessモード(推奨)

# Kong Gateway DB-lessモードでの起動
docker run -d --name kong-gateway \
  --network=kong-net \
  -v "$(pwd):/kong/declarative/" \
  -e "KONG_DATABASE=off" \
  -e "KONG_DECLARATIVE_CONFIG=/kong/declarative/kong.yml" \
  -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
  -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
  -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
  -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
  -e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \
  -e "KONG_ADMIN_GUI_URL=http://localhost:8002" \
  -p 8000:8000 \
  -p 8443:8443 \
  -p 8001:8001 \
  -p 8444:8444 \
  -p 8002:8002 \
  -p 8445:8445 \
  -p 8003:8003 \
  -p 8004:8004 \
  kong/kong-gateway:3.8

PostgreSQL使用の場合

# PostgreSQLコンテナ起動
docker run -d --name kong-database \
  --network=kong-net \
  -p 5432:5432 \
  -e "POSTGRES_USER=kong" \
  -e "POSTGRES_DB=kong" \
  -e "POSTGRES_PASSWORD=kongpass" \
  postgres:13

# データベース移行
docker run --rm --network=kong-net \
  -e "KONG_DATABASE=postgres" \
  -e "KONG_PG_HOST=kong-database" \
  -e "KONG_PG_USER=kong" \
  -e "KONG_PG_PASSWORD=kongpass" \
  kong/kong-gateway:3.8 kong migrations bootstrap

# Kong Gateway起動
docker run -d --name kong-gateway \
  --network=kong-net \
  -e "KONG_DATABASE=postgres" \
  -e "KONG_PG_HOST=kong-database" \
  -e "KONG_PG_USER=kong" \
  -e "KONG_PG_PASSWORD=kongpass" \
  -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
  -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
  -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
  -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
  -e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \
  -e "KONG_ADMIN_GUI_URL=http://localhost:8002" \
  -p 8000:8000 \
  -p 8443:8443 \
  -p 8001:8001 \
  -p 8444:8444 \
  -p 8002:8002 \
  -p 8445:8445 \
  -p 8003:8003 \
  -p 8004:8004 \
  kong/kong-gateway:3.8

Kubernetesでのインストール

# Kong Helm chart追加
helm repo add kong https://charts.konghq.com
helm repo update

# Kong Gateway インストール
helm install kong kong/kong \
  --set ingressController.enabled=true \
  --set image.repository=kong/kong-gateway \
  --set image.tag=3.8 \
  --set env.database=off \
  --set env.admin_gui_url=http://localhost:8002 \
  --set admin.enabled=true \
  --set admin.http.enabled=true \
  --set manager.enabled=true \
  --set manager.http.enabled=true

パッケージマネージャーでのインストール

Ubuntu/Debian

# Kong公式リポジトリ追加
curl -fsSL https://download.konghq.com/gateway-3.x-ubuntu-$(lsb_release -cs)/gpg | sudo gpg --dearmor -o /usr/share/keyrings/kong-gateway-3.x-ubuntu-$(lsb_release -cs)-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/kong-gateway-3.x-ubuntu-$(lsb_release -cs)-keyring.gpg] https://download.konghq.com/gateway-3.x-ubuntu-$(lsb_release -cs)/ default all" | sudo tee /etc/apt/sources.list.d/kong-gateway-3.x-ubuntu-$(lsb_release -cs).list

# インストール
sudo apt update
sudo apt install kong-enterprise-edition

CentOS/RHEL

# YUMリポジトリ設定
curl https://download.konghq.com/gateway-3.x-centos-8/config.repo | sudo tee /etc/yum.repos.d/kong-gateway-3.x-centos-8.repo

# インストール
sudo yum install kong-enterprise-edition

基本的な使い方

サービスとルートの設定

Admin APIによる設定

# サービス作成
curl -i -X POST http://localhost:8001/services/ \
  --data "name=example-service" \
  --data "url=http://httpbin.org"

# ルート作成
curl -i -X POST http://localhost:8001/services/example-service/routes \
  --data "hosts[]=example.com" \
  --data "paths[]=/api"

# テスト
curl -i -X GET http://localhost:8000/api/get \
  --header "Host: example.com"

宣言的設定(DB-lessモード)

# kong.yml
_format_version: "3.0"
_transform: true

services:
  - name: example-service
    url: http://httpbin.org
    routes:
      - name: example-route
        hosts:
          - example.com
        paths:
          - /api

  - name: backend-api
    url: http://backend.internal:8080
    routes:
      - name: api-route
        hosts:
          - api.example.com
        paths:
          - /v1

plugins:
  - name: rate-limiting
    config:
      minute: 100
      hour: 1000

  - name: cors
    config:
      origins:
        - "*"
      methods:
        - "GET"
        - "POST"
        - "PUT"
        - "DELETE"
      headers:
        - "Accept"
        - "Accept-Version"
        - "Content-Length"
        - "Content-MD5"
        - "Content-Type"
        - "Date"
        - "X-Auth-Token"

decKによる管理

# decKインストール
curl -sL https://github.com/Kong/deck/releases/latest/download/deck_linux_amd64.tar.gz -o deck.tar.gz
tar -xf deck.tar.gz -C /tmp
sudo cp /tmp/deck /usr/local/bin/

# 設定ファイルから同期
deck sync kong.yml

# 現在の設定をエクスポート
deck dump

# 設定の差分確認
deck diff kong.yml

設定例

ロードバランシング設定

services:
  - name: load-balanced-service
    host: upstream-service
    routes:
      - name: lb-route
        paths:
          - /balanced

upstreams:
  - name: upstream-service
    algorithm: round-robin
    healthchecks:
      active:
        healthy:
          interval: 5
          successes: 3
        unhealthy:
          interval: 5
          tcp_failures: 3
          http_failures: 3
    targets:
      - target: server1.example.com:8080
        weight: 100
      - target: server2.example.com:8080
        weight: 100
      - target: server3.example.com:8080
        weight: 50

プラグイン設定

plugins:
  # レート制限
  - name: rate-limiting
    service: example-service
    config:
      minute: 100
      hour: 1000
      policy: local

  # JWT認証
  - name: jwt
    service: example-service
    config:
      secret_is_base64: false
      key_claim_name: iss
      claims_to_verify:
        - exp
        - iat

  # リクエスト変換
  - name: request-transformer
    service: example-service
    config:
      add:
        headers:
          - "X-Backend-Version:v1"
        querystring:
          - "source:kong"
      remove:
        headers:
          - "X-Internal-Header"

  # レスポンス変換
  - name: response-transformer
    service: example-service
    config:
      add:
        headers:
          - "X-Powered-By:Kong"
        json:
          - "timestamp:$(date)"

認証・セキュリティ

JWT認証の実装

# JWT プラグイン有効化
curl -X POST http://localhost:8001/services/example-service/plugins \
  --data "name=jwt" \
  --data "config.secret_is_base64=false"

# Consumer作成
curl -X POST http://localhost:8001/consumers \
  --data "username=user1"

# JWT認証情報作成
curl -X POST http://localhost:8001/consumers/user1/jwt \
  --data "key=my-key" \
  --data "secret=my-secret"

JWT認証用のPythonサンプル:

import jwt
import requests
from datetime import datetime, timedelta

# JWTトークン生成
def generate_jwt_token():
    payload = {
        'iss': 'my-key',  # Kong consumerのkey
        'exp': datetime.utcnow() + timedelta(hours=1),
        'iat': datetime.utcnow()
    }
    
    token = jwt.encode(payload, 'my-secret', algorithm='HS256')
    return token

# API呼び出し
token = generate_jwt_token()
headers = {'Authorization': f'Bearer {token}'}
response = requests.get('http://localhost:8000/api/get', 
                       headers=headers,
                       headers={'Host': 'example.com'})
print(response.json())

OAuth 2.0設定

plugins:
  - name: oauth2
    service: example-service
    config:
      scopes:
        - read
        - write
      mandatory_scope: true
      provision_key: provision123
      token_expiration: 3600
      enable_authorization_code: true
      enable_client_credentials: true
      enable_implicit_grant: true
      enable_password_grant: true

Basic認証

# Basic Auth プラグイン有効化
curl -X POST http://localhost:8001/services/example-service/plugins \
  --data "name=basic-auth" \
  --data "config.hide_credentials=true"

# Consumer作成と認証情報設定
curl -X POST http://localhost:8001/consumers \
  --data "username=api-user"

curl -X POST http://localhost:8001/consumers/api-user/basic-auth \
  --data "username=user1" \
  --data "password=password123"

# 認証付きリクエスト
curl -X GET http://localhost:8000/api/get \
  --header "Host: example.com" \
  --header "Authorization: Basic $(echo -n 'user1:password123' | base64)"

API Key認証

# Key Auth プラグイン有効化
curl -X POST http://localhost:8001/services/example-service/plugins \
  --data "name=key-auth" \
  --data "config.key_names[]=apikey"

# Consumer作成とAPIキー発行
curl -X POST http://localhost:8001/consumers \
  --data "username=api-client"

curl -X POST http://localhost:8001/consumers/api-client/key-auth \
  --data "key=my-api-key-123"

# APIキー認証付きリクエスト
curl -X GET http://localhost:8000/api/get \
  --header "Host: example.com" \
  --header "apikey: my-api-key-123"

レート制限・トラフィック管理

レート制限の設定

plugins:
  # 基本的なレート制限
  - name: rate-limiting
    config:
      minute: 100
      hour: 1000
      day: 10000
      policy: local
      fault_tolerant: true
      hide_client_headers: false

  # Consumerレベルでのレート制限
  - name: rate-limiting
    consumer: premium-user
    config:
      minute: 1000
      hour: 10000
      policy: redis
      redis_host: redis.example.com
      redis_port: 6379

  # IPアドレスベースのレート制限
  - name: rate-limiting
    config:
      minute: 50
      policy: local
      limit_by: ip

Response Rate Limiting

plugins:
  - name: response-ratelimiting
    config:
      limits:
        video:
          minute: 200
        image:
          minute: 500
      header_name: x-rate-limit

Request Size Limiting

plugins:
  - name: request-size-limiting
    config:
      allowed_payload_size: 1024  # 1KB

Circuit Breaker設定

# プロキシキャッシュプラグインでCircuit Breaker的動作
curl -X POST http://localhost:8001/services/example-service/plugins \
  --data "name=proxy-cache" \
  --data "config.strategy=memory" \
  --data "config.memory.dictionary_name=kong_cache" \
  --data "config.content_type[]=application/json" \
  --data "config.cache_ttl=300" \
  --data "config.cache_control=false"

モニタリング・ログ

Prometheusメトリクス

plugins:
  - name: prometheus
    config:
      per_consumer: true
      status_code_metrics: true
      latency_metrics: true
      bandwidth_metrics: true

メトリクスの取得:

# Prometheusメトリクス取得
curl http://localhost:8001/metrics

Datadogモニタリング

plugins:
  - name: datadog
    config:
      host: "datadog-agent.monitoring.svc.cluster.local"
      port: 8125
      metrics:
        - request_count
        - latency
        - request_size
        - response_size
        - upstream_latency
      tags:
        - "env:production"
        - "service:api-gateway"

カスタムログ設定

plugins:
  - name: file-log
    config:
      path: "/var/log/kong/access.log"
      reopen: true

  - name: http-log
    config:
      http_endpoint: "https://logs.example.com/webhook"
      method: "POST"
      timeout: 1000
      keepalive: 1000
      content_type: "application/json"
      flush_timeout: 2
      retry_count: 15

StatsD統合

plugins:
  - name: statsd
    config:
      host: "statsd.monitoring.svc.cluster.local"
      port: 8125
      metrics:
        - request_count
        - latency
        - request_size
        - response_size
        - upstream_latency
      prefix: "kong"

高度な機能

GraphQL支援

plugins:
  - name: graphql-proxy-cache-advanced
    config:
      strategy: memory
      ttl: 300
      cache_introspection: true
      vary_headers:
        - "Authorization"

  - name: graphql-rate-limiting-advanced
    config:
      max_query_complexity: 1000
      max_query_depth: 10
      score_factor: 1.0
      introspection: true

gRPCサポート

services:
  - name: grpc-service
    protocol: grpc
    host: grpc-backend.example.com
    port: 9000
    routes:
      - name: grpc-route
        protocols:
          - grpc
        hosts:
          - grpc.example.com

plugins:
  - name: grpc-gateway
    service: grpc-service
    config:
      proto: |
        syntax = "proto3";
        package hello;
        service Greeter {
          rpc SayHello (HelloRequest) returns (HelloReply) {}
        }
        message HelloRequest {
          string name = 1;
        }
        message HelloReply {
          string message = 1;
        }

WebSocketプロキシ

services:
  - name: websocket-service
    protocol: http
    host: ws-backend.example.com
    port: 8080
    routes:
      - name: websocket-route
        protocols:
          - http
        hosts:
          - ws.example.com
        paths:
          - /ws

plugins:
  - name: websocket-size-limit
    config:
      max_payload_size: 1048576  # 1MB

AI Gateway機能(Kong 3.8新機能)

plugins:
  - name: ai-semantic-prompt-guard
    config:
      llm_provider: "openai"
      llm_model: "gpt-4"
      max_tokens: 1000
      deny_patterns:
        - "malicious_prompt"
        - "injection_attempt"

  - name: ai-semantic-cache
    config:
      llm_provider: "openai"
      cache_ttl: 3600
      similarity_threshold: 0.8

  - name: ai-semantic-routing
    config:
      llm_provider: "openai"
      routes:
        - name: "customer-service"
          description: "Customer service related queries"
          upstream: "customer-service.internal"
        - name: "technical-support"
          description: "Technical support questions"
          upstream: "tech-support.internal"

パフォーマンス最適化

Nginx設定の最適化

# /etc/kong/nginx-kong.conf
worker_processes auto;
worker_connections 1024;
worker_rlimit_nofile 65535;

events {
    use epoll;
    multi_accept on;
}

http {
    keepalive_timeout 65;
    keepalive_requests 1000;
    
    # バッファサイズ最適化
    client_body_buffer_size 128k;
    client_max_body_size 50m;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 4k;
    
    # gzip圧縮
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/xml+rss
        application/atom+xml
        image/svg+xml;
}

Kong設定の最適化

# 環境変数での最適化
export KONG_WORKER_PROCESSES=auto
export KONG_WORKER_CONNECTIONS=1024
export KONG_MAX_FILES_LIMIT=65535

# Lua設定
export KONG_LUA_PACKAGE_PATH="/opt/?.lua;;"
export KONG_LUA_PACKAGE_CPATH="/opt/?.so;;"

# メモリ最適化
export KONG_MEM_CACHE_SIZE=256m
export KONG_UPSTREAM_KEEPALIVE_POOL_SIZE=512
export KONG_UPSTREAM_KEEPALIVE_MAX_REQUESTS=1000
export KONG_UPSTREAM_KEEPALIVE_IDLE_TIMEOUT=60

データベース最適化

-- PostgreSQL設定例
-- postgresql.conf
shared_buffers = 256MB
effective_cache_size = 1GB
work_mem = 4MB
maintenance_work_mem = 64MB
max_connections = 200

-- インデックス作成
CREATE INDEX CONCURRENTLY idx_services_name ON services(name);
CREATE INDEX CONCURRENTLY idx_routes_service_id ON routes(service_id);
CREATE INDEX CONCURRENTLY idx_plugins_service_id ON plugins(service_id);

キャッシング戦略

plugins:
  - name: proxy-cache
    config:
      strategy: redis
      redis:
        host: redis-cluster.example.com
        port: 6379
        database: 0
        password: "redis-password"
        sentinel_master: "master"
        sentinel_role: "master"
        sentinel_addresses:
          - "sentinel1.example.com:26379"
          - "sentinel2.example.com:26379"
          - "sentinel3.example.com:26379"
      content_type:
        - "application/json"
        - "text/plain"
      cache_ttl: 300
      cache_control: true
      storage_ttl: 3600

トラブルシューティング

ログ解析とデバッグ

エラーログの確認

# Kong エラーログ
docker logs kong-gateway

# アクセスログの確認
tail -f /var/log/kong/access.log

# プロキシエラーログ
tail -f /var/log/kong/error.log

デバッグログの有効化

# デバッグログレベル設定
export KONG_LOG_LEVEL=debug
export KONG_PROXY_ERROR_LOG=/dev/stderr
export KONG_ADMIN_ERROR_LOG=/dev/stderr

# Kong再起動
kong restart

よくある問題と解決法

502 Bad Gateway エラー

# アップストリーム接続確認
curl -I http://upstream-service:8080/health

# Kong設定確認
curl http://localhost:8001/services/example-service

# プラグイン設定確認
curl http://localhost:8001/services/example-service/plugins

認証エラーのデバッグ

plugins:
  - name: request-termination
    config:
      status_code: 200
      content_type: "application/json"
      body: '{"debug": "authentication bypass for testing"}'

パフォーマンス問題の診断

# Kong Admin APIでの統計情報
curl http://localhost:8001/status

# プロメテウスメトリクス詳細
curl http://localhost:8001/metrics | grep kong_request_latency

# アップストリームヘルスチェック状況
curl http://localhost:8001/upstreams/upstream-service/health

ヘルスチェック設定

upstreams:
  - name: backend-upstream
    healthchecks:
      active:
        type: "http"
        http_path: "/health"
        healthy:
          interval: 5
          http_statuses: [200, 302]
          successes: 3
        unhealthy:
          interval: 5
          http_statuses: [429, 500, 502, 503, 504]
          tcp_failures: 3
          http_failures: 3
          timeouts: 3
      passive:
        type: "http"
        healthy:
          http_statuses: [200, 201, 202, 203, 204, 205, 206, 300, 301, 302, 303, 304, 305, 306, 307, 308]
          successes: 5
        unhealthy:
          http_statuses: [429, 500, 502, 503, 504]
          tcp_failures: 2
          http_failures: 5
          timeouts: 7

設定のバックアップと復元

# decKでの設定バックアップ
deck dump --output-file kong-backup-$(date +%Y%m%d).yaml

# 設定の復元
deck sync kong-backup-20241218.yaml

# 設定の検証
deck validate kong.yaml

参考リンク

公式ドキュメント

ツールとリソース

コミュニティ

学習リソース