Nginx keyval モジュールによる動的トラフィック管理手法

導入前の確認事項

この機能を利用するには、Nginx に ngx_http_keyval_module が正しくコンパイルされている必要があります。バージョン情報の出力から確認できます。

nginx -V 2>&1 | grep ngx_http_keyval_module

結果に該当する文字列が表示されない場合は、商用版である NGINX Plus のライセンスが必要か、カスタムビルド時にモジュールを有効化する処理を行ってください。また、状態を永続化させるためのストレージディレクトリを用意します。

sudo mkdir -p /var/lib/nginx/kv_state
sudo chown -R nginx:nginx /var/lib/nginx/kv_state

基本的な構成設定

nginx.confhttp ブロック内に以下の記述を追加し、共有メモリ領域と検索ルールを定義します。

# 共有メモリ領域の定義(名前:pool_zone, 容量:48k, 永続化ファイル指定)
keyval_zone zone=pool_zone:48k state=/var/lib/nginx/kv_state/pool.json;

# 変数マップの定義(クエリパラメータ<service>を検索キーとする)
keyval $arg_service $upstream_name zone=pool_zone;

server {
    listen 8080;
    server_name backend.local;

    # メインロケーション:決定されたアップストリーム名を使用
    location / {
        # $upstream_name が空の場合はデフォルト動作またはエラーを返す
        return 200 "Service: $upstream_name";
    }

    # 管理用エンドポイント
    # write=on を設定することで外部からの書き込みを許可
    location /kv-admin {
        api write=on;
    }
}

主な設定ポイントは以下の通りです。

  • keyval_zone: メモリ上のインデックス領域を確保します。
  • keyval: リクエストデータに基づいて変数値を取得するためのマッピングルールの宣言です。
  • api write=on: HTTP API 経由でのデータの追加・変更を有効化します。

運用と検証手順

1. 設定適用

設定ファイルの構文チェックを行い、問題なければサービスを再起動せず反映させます。

sudo nginx -t && sudo systemctl reload nginx

2. キーバリューペアの登録

HTTP POST リクエストを使用して、メモリ上にデータを投入します。

要素内容
MethodPOST
Path/kv-admin
HeaderContent-Type: application/json

サンプルコマンド:

curl -X POST http://backend.local:8080/kv-admin \
     -H "Content-Type: application/json" \
     -d '{"key":"payment","value":"server_pool_payment"}'

成功時、ステータスコード 204(No Content)が返されます。

3. 検索動作の確認

登録したキーでアクセスを試みます。

curl "http://backend.local:8080/?service=payment"

レスポンスボディに server_pool_payment が含まれている場合、正常に参照されています。

4. データの削除

不要なエントリーを消去したい場合は DELETE リクエストを送ります。

curl -X DELETE http://backend.local:8080/kv-admin \
     -H "Content-Type: application/json" \
     -d '{"key":"payment"}'

再度上記テストを実行すると、戻り値は空または初期値となります。

高度なユースケース

IP ベースのブランチ処理

CIDR 形式のネットワークアドレスをキーとして、特定クライアントのみを対象とした配信を行います。

# IP タイプ専用ゾーン(有効期限:60分,同期あり)
keyval_zone zone=ip_router:16k type=ip timeout=60m sync \
            state=/var/lib/nginx/kv_state/ip_router.json;

keyval $remote_addr $is_vip zone=ip_router;

server {
    listen 443 ssl;
    
    location /exclusive-content {
        if ($is_vip = "true") {
            proxy_pass https://premium_server/;
        }
        return 404;
    }
}

API から {"key": "10.0.0.0/24", "value": "true"} を送付すれば、そのサブネット内からアクセスしたリクエストのみ特別経路に誘導されます。

プレフィックス一致による AB テスト

ユーザー ID の接頭辞を鍵とし、異なるバックエンドへ振り分けます。

# プレフィックス型ゾーン(24時間保持)
keyval_zone zone=user_bucket:32k type=prefix timeout=24h \
            state=/var/lib/nginx/kv_state/user_bucket.json;

keyval $arg_uid $experiment_group zone=user_bucket;

location /app-stream {
    if ($experiment_group ~ "^ver_A") {
        proxy_pass http://stream_backend_vA;
    }
    else_if ($experiment_group ~ "^ver_B") {
        proxy_pass http://stream_backend_vB;
    }
    proxy_pass http://standard_backend;
}

設定オプション一覧

keyval_zonekeyval で利用可能な主要パラメータは以下の通りです。

指令パラメータ説明
keyval_zonezone=name:size共有メモリの識別名とサイズ指定
state=pathディスクへのダンプ先パス
timeout=durationエントリの有効期間(例:10m)
type=string|ip|prefixキーのマッチング方式(完全一致/IP 範囲/先頭一致)
syncクラスタ間での削除情報の同期(タイムアウト必須)
keyvalkey_var検索元の Nginx 変数(例:$remote_addr
dst_var結果格納先の Nginx 変数
zone=name紐付けるゾーン名

トラブルシューティング

  • API 書き込み失敗時の確認
    error.log を監視し、権限不足や API モジュールの読み込み忘れを確認してください。
    tail -f /var/log/nginx/error.log
  • 永続化ファイルの破損
    不正な編集により JSON が壊れた場合、起動時またはロード時にエラーが発生します。一時的にファイルを移動させ、新規生成させると復旧可能です。
    mv /var/lib/nginx/kv_state/pool.json /var/lib/nginx/kv_state/pool.json.bak
  • メモリ制限超過
    大量のキーを追加してエラーが出る場合、keyval_zone のサイズを大きく再設定してください(例:128k)。

タグ: nginx keyval-module dynamic-routing http-api load-balancing

6月17日 22:57 投稿