---
title: "Kong GatewayのUpstream設定と負荷分散：Service・Routeの作り方を3.9.4で実測"
url: "https://www.issoh.co.jp/tech/details/4483/"
published: 2024-12-12
updated: 2026-10-29
categories: ["API"]
publisher: "株式会社一創"
---

# Kong GatewayのUpstream設定と負荷分散：Service・Routeの作り方を3.9.4で実測

Kong Gatewayは、NGINXにLuaJITを組み込んだOpenResty上で動くAPIゲートウェイです。リクエストをServiceとRouteで振り分け、複数のバックエンドへはUpstreamとTargetで負荷を分散し、認証やレート制限はプラグインで足します。この記事では、OSS版の最新である `kong/kong:3.9.4`（2026年10月12日公開）をDockerで起動し、Admin APIとdecKのコマンドを実際に実行した結果をもとに、Upstreamの設定と挙動を中心に解説します。

## まとめ：Kong GatewayのUpstreamとServiceの要点

- **Serviceは宛先、Routeは入口、UpstreamとTargetは振り分け先**。単一バックエンドへの転送だけならServiceにURLを指定でき、負荷分散やヘルスチェックを設定する場合は、台数にかかわらずServiceの`host`にUpstream名を入れます。
- **重みは比率どおりに効きます**。weight 100と50で300回送ると199回と101回でした。weightを0にしたTargetには送られません。
- **パッシブヘルスチェックは切り離すだけで、自動では戻しません**。バックエンドが復旧しても、アクティブヘルスチェックを有効にするか、Admin APIで`healthy`を送るまでトラフィックは戻りませんでした。
- **Upstreamから使えるTargetを選べないと503**（`failure to get a peer from the ring-balancer`）、ホスト名が引けないと503（`name resolution failed`）が返ります。
- **OSS版は3.9系で止まっています**。`sticky-sessions`は3.11以降の機能で、OSS 3.9.4では設定自体が拒否されます。最新のKong Gatewayは3.16.0.1（2026年10月12日）です。
- **DB-lessモードではAdmin APIやdecK syncでUpstreamを作れません**（405）。宣言ファイルを`/config`へ送るか、DBありモードでdecKを使います。

## Kong Gatewayの仕組みと2026年10月時点の版

Kong Gatewayは、NGINXを含むOpenResty上にAPI管理機能を実装した製品です。プロキシの土台はNGINX（OpenResty）で、その上でLuaのプラグインが認証・レート制限・ログ出力などを担います。APIゲートウェイそのものの役割は[APIゲートウェイとは？役割・機能とリバースプロキシ／サービスメッシュとの違い・導入判断を解説](/tech/details/13210/)で整理しているので、ここではKong固有の構成と設定に絞ります。

### OSS版とKong Gateway（Enterprise）の版の違い

OSS版（Apache 2.0）のリリースは3.9系で止まっています。GitHubのタグは[3.9.4のCHANGELOG](https://github.com/Kong/kong/blob/3.9.4/CHANGELOG.md)が最新で、3.9.4ではクラスタリングRPC処理のSQLインジェクション（CVE-2026-1907）が修正されました。Docker Hubの[公式イメージkong](https://hub.docker.com/%5F/kong)でも`latest`は3.9.4を指します。一方、商用版のイメージ`kong/kong-gateway`は[Kong Gatewayのchangelog](https://developer.konghq.com/gateway/changelog/)のとおり3.16.0.1（2026年10月12日）まで進んでいます。OSSからEnterpriseへの移行ガイドが対象とするOSS版も3.9.3までです。

ライセンスにも注意が要ります。Kong Gateway 3.10.0.0のchangelogには「Free mode is no longer available」とあり、ライセンス無しで起動した`kong/kong-gateway`は期限切れライセンスと同じ扱いになります。ただし[breaking-changesのページ](https://developer.konghq.com/gateway/breaking-changes/)は同じ3.10.0.0の項で「将来の3.xで削除予定の非推奨」と書いており、公式資料の記述がそろっていません。ライセンス無しで3.10以降を動かす前提は置かないほうが安全です。[ライセンスの説明](https://developer.konghq.com/gateway/entities/license/)では、期限切れ後は既存の設定でプロキシは続くものの、エンティティの設定は読み取り専用になり、DB-lessモードとKubernetes Ingress Controllerでは新しいノードが起動できず再起動も失敗すると書かれています。ライセンスなしで検証するなら、OSSの`kong/kong:3.9.4`を使うのが確実です。この記事の実測もすべて3.9.4で行いました。

### DBありモードとDB-lessモードの違い

設定の保存先で2つのモードがあり、設定の変え方がまったく違います。DBありモードはPostgreSQLに設定を保存し、Admin APIのPOSTやPATCHでその場で変更できます。DB-lessモードはkong.yamlをメモリに読み込んで動き、Admin APIは参照専用になります。DB-lessのKongに`POST /upstreams`相当の変更を送ると、次のように405で拒否されました。

```
Update upstream echo-upstream failed: HTTP status 405 (message: "cannot create or update 'upstreams' entities when not using a database")
```

DB-lessで設定を変えるには、宣言ファイル全体を`POST /config`で送り直すか、コンテナを再起動します。手作業で試しながら設定を詰める段階はDBあり、CIから同じ設定を配る段階はDB-less、と使い分けると迷いません。

## DockerでKong Gatewayを起動する手順（DB-less）

最小の構成は、kong.yamlを1枚書いてKongのコンテナにマウントする形です。ここでは検証用のバックエンドに`traefik/whoami`を2台立て、Upstreamで振り分けます。

```
_format_version: "3.0"
services:
  - name: echo-service
    host: echo-upstream      # Upstream 名を host に書く
    port: 80
    protocol: http
    routes:
      - name: echo-route
        paths:
          - /echo
upstreams:
  - name: echo-upstream
    algorithm: round-robin
    targets:
      - target: whoami1:80
        weight: 100
      - target: whoami2:80
        weight: 50
```

```
docker network create kongnet
docker run -d --name whoami1 --network kongnet traefik/whoami
docker run -d --name whoami2 --network kongnet traefik/whoami

docker run -d --name kong --network kongnet \
  -v "$(pwd):/kong/declarative" \
  -e KONG_DATABASE=off \
  -e KONG_DECLARATIVE_CONFIG=/kong/declarative/kong.yaml \
  -e KONG_ADMIN_LISTEN=0.0.0.0:8001 \
  -p 127.0.0.1:8000:8000 -p 127.0.0.1:8001:8001 \
  kong/kong:3.9.4

curl -sI http://localhost:8000/ | grep -i ^server   # Server: kong/3.9.4（Route 未一致の 404 でも返る）
```

`KONG_ADMIN_LISTEN`は省略できません。3.9.4の既定値は`admin_listen = 127.0.0.1:8001`で、コンテナ内のループバックにしか待ち受けないため、ポートを公開してもホストからAdmin APIに届きません（プロキシ側の`proxy_listen`は既定で`0.0.0.0:8000`）。Admin APIには認証が無いので、コンテナ内は`0.0.0.0`で待ち受けさせつつ、ホスト側の公開は`-p 127.0.0.1:8001:8001`のように自分のマシンだけに絞ります。

## ServiceとRouteでAPIを公開する設定

APIの公開はServiceとRouteの組で成り立ちます。Serviceにはバックエンドのプロトコル・ホスト・ポート・パスを、RouteにはそのServiceへ流す条件（パス・ホスト名・メソッド・ヘッダー）を書きます。1つのServiceに複数のRouteを付けられます。

### DBありモードでのService・Route作成

ここからは前章のDB-lessのコンテナを止め、PostgreSQLに接続するDBありモードのKongを立てて進めます。3.9.4で実行した手順は次のとおりです。

```
docker stop kong
docker rm kong
docker run -d --name kong-db --network kongnet \
  -e POSTGRES_USER=kong -e POSTGRES_DB=kong -e POSTGRES_PASSWORD=kongpass \
  postgres:16

# スキーマを作成（初回のみ）
docker run --rm --network kongnet \
  -e KONG_DATABASE=postgres -e KONG_PG_HOST=kong-db -e KONG_PG_PASSWORD=kongpass \
  kong/kong:3.9.4 kong migrations bootstrap

docker run -d --name kong --network kongnet \
  -e KONG_DATABASE=postgres -e KONG_PG_HOST=kong-db -e KONG_PG_PASSWORD=kongpass \
  -e KONG_ADMIN_LISTEN=0.0.0.0:8001 \
  -p 127.0.0.1:8000:8000 -p 127.0.0.1:8001:8001 \
  kong/kong:3.9.4
```

DBありモードのKongなら、Admin API（既定ポート8001）へのPOSTで作れます。以下は3.9.4で実行し、すべて201が返ったコマンドです。

```
# Service を作成（host には後で作る Upstream 名を指定）
curl -i -X POST http://localhost:8001/services \
  --data name=example-service \
  --data host=example-upstream

# Service に Route を追加（/api で始まるパスを受ける）
curl -i -X POST http://localhost:8001/services/example-service/routes \
  --data name=example-route \
  --data 'paths[]=/api'
```

DBありモードでは、Admin APIで入れた変更がプロキシに反映されるまで数秒かかります。作成直後の1回目のリクエストが404になっても、設定の誤りとは限りません。

### strip\_pathとpreserve\_hostの既定値

Routeの`strip_path`は既定で`true`、`preserve_host`は既定で`false`です（[routes.lua](https://github.com/Kong/kong/blob/3.9.4/kong/db/schema/entities/routes.lua)）。上のRouteへ`/api/users`を送ると、バックエンドには`GET /users`が届き、Hostヘッダーはクライアントが送った値ではなくTarget名の`whoami1`になっていました。バックエンドが`/api`付きのパスを期待しているなら`strip_path=false`を、元のHostヘッダーで仮想ホストを切り替えているなら`preserve_host=true`を明示します。

### 複数のRouteが一致したときの優先順位

3.9.4の既定ルーターは`traditional_compatible`です。[公式のルーティング解説](https://developer.konghq.com/gateway/routing/traditional/)によると、優先順位はまず「match weight」で決まります。`methods`・`hosts`・`headers`・`paths`などを指定した項目の数が多いRouteほど先に評価され、パスの長さが効くのはその後です。正規表現パスは`regex_priority`の大きい順に評価され、`priority`フィールドが効くのは`expressions`ルーターのRouteだけです。

実際に、`paths=/api`＋`methods=GET`のRouteと、`paths=/api/users`だけのRouteを並べて試しました。`GET /api/users`は短いパスの`/api`側（match weight 2）に吸われ、`POST /api/users`だけが`/api/users`側へ流れました。「長いパスが勝つ」と思い込んでRouteを足すと、メソッドやホストを指定した既存のRouteに横取りされます。条件の数をそろえるか、限定したいRouteにも同じ`methods`を付けてください。

## UpstreamとTargetで負荷分散する設定

Upstreamは振り分け先を束ねる仮想ホストで、その下に実際のサーバーをTargetとして登録します。ServiceのhostにUpstream名を書くと、そのServiceへのリクエストがUpstreamのアルゴリズムで各Targetへ分散されます。前段のロードバランサーとしてNGINXやHAProxyを置く構成と比べたい場合は、[HAProxyとは：L4/L7ロードバランサーの仕組みと設定・nginxとの違いを実装目線で解説](/tech/details/13807/)が参考になります。

### UpstreamとTargetの作成と重みの効き方

```
# Upstream を作成
curl -i -X POST http://localhost:8001/upstreams \
  --data name=example-upstream

# Target を2台登録（weight の既定値は 100、範囲は 0〜65535）
curl -i -X POST http://localhost:8001/upstreams/example-upstream/targets \
  --data target=whoami1:80 --data weight=100
curl -i -X POST http://localhost:8001/upstreams/example-upstream/targets \
  --data target=whoami2:80 --data weight=50

# Target を振り分け対象から外す（weight=0）
curl -i -X PATCH http://localhost:8001/upstreams/example-upstream/targets/whoami2:80 \
  --data weight=0
```

round-robinでweight 100と50のまま300回リクエストすると、whoami1が199回、whoami2が101回で、ほぼ2対1でした。whoami2のweightを0にした後は30回すべてwhoami1へ送られました。メンテナンスで1台を抜くときは、Targetを消さずにweightを0にすれば、戻すときもPATCH 1回で済みます。

### 負荷分散アルゴリズムの選び方

Upstreamの`algorithm`で方式を選びます。[公式のUpstreamの説明](https://developer.konghq.com/gateway/entities/upstream/)では5種類ですが、`sticky-sessions`は3.11以降の機能です。

| algorithm          | 振り分けの基準         | OSS 3.9.4    | 向く場面            |
| ------------------ | --------------- | ------------ | --------------- |
| round-robin（既定）    | 重み付きの順番         | 使える          | 均質なステートレスAPI    |
| consistent-hashing | hash\_onの値のハッシュ | 使える          | 同じ利用者を同じTargetへ |
| least-connections  | 処理中のリクエスト数      | 使える          | 処理時間がばらつくAPI    |
| latency            | 応答時間の指数移動平均     | 使える          | 性能が不ぞろいなTarget  |
| sticky-sessions    | Kongが発行するCookie | 使えない（3.11以降） | セッションを持つアプリ     |

OSS 3.9.4で`algorithm=sticky-sessions`を指定すると、`schema violation (algorithm: expected one of: consistent-hashing, least-connections, round-robin, latency)`で拒否されます。OSSで同じ利用者を同じTargetへ寄せたいなら、consistent-hashingで`hash_on=cookie`か`hash_on=ip`を使います。

least-connectionsは、同時に処理中のリクエストが無いと重みの大きいTargetに偏ります。直列に300回送ったときは300回すべてweight 100のwhoami1へ流れ、30並列で300回送ったときに初めて234回と66回に分かれました。低負荷の検証環境で「片方にしか届かない」と見えても、故障ではありません。

もう1つ、`hash_on`には注意点があります。`hash_on`に`none`以外を入れるとalgorithmが自動で`consistent-hashing`に変わり、その後に`algorithm=round-robin`だけをPATCHしても`consistent-hashing`のまま戻りませんでした。round-robinに戻すには`hash_on=none`を送ります。また`hash_on=header`は`hash_on_header`（ヘッダー名）が必須で、省くとschema violationになります。`hash_on`に指定できる値は`none`・`consumer`・`ip`・`header`・`cookie`・`path`・`query_arg`・`uri_capture`で、取れなかったときの代わりを`hash_fallback`に指定できます。

## ヘルスチェックとサーキットブレーカーの設定

Kongのヘルスチェックには、プローブを送るアクティブと、実際のトラフィックの応答を見るパッシブ（サーキットブレーカー）があります。3.9.4の既定値では、どちらも判定回数が0で**無効**です（[upstreams.lua](https://github.com/Kong/kong/blob/3.9.4/kong/db/schema/entities/upstreams.lua)）。Upstreamを作っただけでは、落ちたTargetは切り離されません。サーキットブレーカーの考え方自体は[サーキットブレーカーとは？マイクロサービスの障害連鎖を止める仕組みと実装・導入判断を解説](/tech/details/13216/)で扱っています。

### パッシブヘルスチェックの設定と復帰の手順

```
# HTTP 500または503を3回、またはTCP接続失敗を2回検出したTargetを切り離す
curl -i -X PATCH http://localhost:8001/upstreams/example-upstream \
  --data 'healthchecks.passive.unhealthy.http_statuses[]=500' \
  --data 'healthchecks.passive.unhealthy.http_statuses[]=503' \
  --data healthchecks.passive.unhealthy.http_failures=3 \
  --data healthchecks.passive.unhealthy.tcp_failures=2

# Target ごとの状態を確認
curl -s http://localhost:8001/upstreams/example-upstream/health

# 復旧した Target を手動で戻す（204 が返る）
curl -i -X PUT http://localhost:8001/upstreams/example-upstream/targets/whoami2:80/healthy
```

weightを100と50にした2台構成（前節のweight 0の操作をする前の状態）でwhoami2のコンテナを止めると、2回の接続失敗でwhoami2がUNHEALTHYになりました。このときサービスの`retries`（既定5）が別のTargetへ再送するため、利用者側の20回のリクエストはすべて200でした。問題は復旧時です。whoami2を起動し直しても状態はUNHEALTHYのままで、30回のリクエストはすべてwhoami1へ流れました。`PUT …/healthy`を送ると204が返って状態がHEALTHYに戻り、ようやくwhoami2にも振り分けられました。公式ドキュメントにも「Passive health checks can only disable unhealthy Targets, they never re-enable Targets automatically.」と明記されています。パッシブだけで運用するなら、復旧手順に`PUT …/healthy`を入れておくか、次のアクティブヘルスチェックを併用してください。

### アクティブヘルスチェックとthreshold

アクティブ側は`healthchecks.active.healthy.interval`と`unhealthy.interval`（秒）を0より大きくしたときだけ動きます。既定のプローブ先は`http_path=/`で、正常とみなすステータスは200と302、異常とみなすのは429・404・500〜505です。プローブ間隔に加えてHTTP失敗回数の閾値も正数に設定した場合、バックエンドに`/`が無く404を返すアプリでは、`http_path`をヘルスチェック用のパスに変えないと全Targetが異常扱いになります。

```
upstreams:
  - name: echo-upstream
    healthchecks:
      threshold: 50            # 健全な重みが50%を切ったら Upstream ごと停止
      active:
        http_path: /health
        healthy:
          interval: 5          # 5秒ごとにプローブ
          successes: 2         # 2回成功で HEALTHY へ戻す
        unhealthy:
          interval: 5
          tcp_failures: 2
          http_failures: 2
      passive:
        unhealthy:
          tcp_failures: 2
          http_failures: 3
```

`threshold`（既定0、範囲0〜100）は、Upstream全体を止める下限です。[公式の例](https://developer.konghq.com/gateway/traffic-control/health-checks-circuit-breakers/)では、weight 100のTargetが5台でthreshold 55なら、2台落ちても60%で動き続け、3台目が落ちて40%になるとUpstream自体が異常になり503を返します。残りのTargetに負荷が集中して共倒れになるのを防ぐ仕組みで、Targetが回復して割合が戻れば自動で再開します。台数が少ない構成でthresholdを高くすると、1台の障害で全停止になる点に気をつけてください。

## Kongのupstreamで出る502・503エラーの切り分け

Upstream設定後に502や503が返る場合は、レスポンスのmessageとTargetのヘルス状態を照合して原因を切り分けます。3.9.4で実際に起こしたエラーと、ソース（`kong/runloop/balancer/init.lua`）上の発生条件を並べます。

| ステータス | message                                                   | 起きた条件                 | 確認すること                    |
| ----- | --------------------------------------------------------- | --------------------- | ------------------------- |
| 503   | failure to get a peer from the ring-balancer              | 全Target異常・threshold未満 | /upstreams/{名前}/health    |
| 503   | name resolution failed                                    | Serviceのhostが名前解決できない | host名・Upstream名の綴り        |
| 502   | An invalid response was received from the upstream server | Targetへの接続や応答に失敗      | Targetのポート・TLS設定          |
| 504   | The upstream server is timing out                         | read\_timeout等を超過     | Serviceのタイムアウト（既定60000ms） |

Targetを2台とも止めた実験では、1回目のリクエストは502、2回目以降は503（`failure to get a peer from the ring-balancer`）に変わりました。1回目の失敗でパッシブヘルスチェックが両方をUNHEALTHYにし、以後はKongがTargetを選べなくなったためです。この503が続くときは、Targetが復旧していても前章で見たとおりパッシブの判定が残っている可能性が高いので、まず`/health`の結果を見ます。

もう1つの`name resolution failed`は、Upstreamを作り忘れたか名前を打ち間違えたときに出ます。Serviceのhostに書いた名前と同じUpstreamが無いと、KongはそれをDNSのホスト名として引きにいき、見つからずに503を返します。Upstreamの名前はDNS名と同じ扱いなので、`example-upstream`のように実在しない名前を付けておくと、作り忘れたときにこのエラーですぐ気づけます。

## ConsumerとプラグインでAPIを保護する設定

プラグインはService・Route・Consumerの単位で有効にできます。Consumerは「APIの利用者」を表すエンティティで、APIキーなどの資格情報と、利用者ごとのレート制限をここに結び付けます。Routeに`key-auth`を付け、Consumerに`rate-limiting`を付けた例です。

```
curl -X POST http://localhost:8001/routes/example-route/plugins --data name=key-auth
curl -X POST http://localhost:8001/consumers --data username=app-a
curl -X POST http://localhost:8001/consumers/app-a/key-auth --data key=demo-key-a
curl -X POST http://localhost:8001/consumers/app-a/plugins \
  --data name=rate-limiting --data config.minute=5 --data config.policy=local

curl -i http://localhost:8000/api/ -H 'apikey: demo-key-a'
```

キー無しでは401（`No API key found in request`）、キー付きでは5回目まで200、6回目から429（`API rate limit exceeded`）になり、応答には`RateLimit-Limit: 5`や`Retry-After`が付きました。`config.policy=local`はノードごとに数えるため、同じ利用者のリクエストが複数ノードへ分散すると、同一時間枠で許可される総数は最大で設定上限のノード台数倍になり得ます。全体で数えたいときは`redis`を選びます。レート制限の方式の比較は[APIレート制限（レートリミット）とは？5方式の比較と429設計・分散実装【2026年版】](/tech/details/16179/)、リクエストの書き換えは[Kong request-transformerとAI版の違い｜PIIマスキングの落とし穴](/tech/details/2849/)で詳しく扱っています。

どのプラグインよりも先に守るべきなのはAdmin APIです。Admin APIは設定を丸ごと書き換えられる管理面で、ここが外から届くと、プロキシ側にどれだけプラグインを付けても設定ごと差し替えられます。既定の`127.0.0.1`待受を変えるときは、ネットワークで到達元を絞ってください。

## decKによる設定ファイル管理とGitOps運用

decKはKongの設定をYAMLで書き出し、ファイルとの差分をKongへ反映するCLIです。設定をGitで管理し、レビューを通った変更だけをCIから反映する運用に使います。Kubernetes上で同じ考え方を取る仕組みとしては[ArgoCDとは？GitOpsの仕組みとインストール・Sync設定をコード付きで解説](/tech/details/15438/)も参考になります。

### deck gateway sync・apply・diffの違い

```
# 稼働中の設定を書き出す
deck gateway dump -o kong.yaml

# 反映せずに差分だけ見る（CI のレビュー用）
deck gateway diff kong.yaml

# ファイルどおりにそろえる（ファイルに無いエンティティは削除）
deck gateway sync kong.yaml

# ファイルの分だけ作成・更新する（削除はしない）
deck gateway apply kong.yaml
```

decK 1.69.0とDBありのKong 3.9.4で試すと、`diff`は`"algorithm": "least-connections"`から`"round-robin"`への変更を`Updated: 1`として表示しました。違いが出たのは削除です。Admin APIで手作業のService（manual-svc）を足した状態で`apply`を実行するとmanual-svcは残り、`sync`を実行すると`deleting service manual-svc`と出て消えました。syncは「ファイルが正」なので、手作業で入れた設定は次のsyncで消えます。チームで使うなら、Admin APIでの直接変更を禁止するか、変更を必ずファイルにも書き戻すルールが要ります。

### DB-lessモードへの反映方法

decKのsyncはAdmin APIでエンティティを作るため、DB-lessモードのKongには使えません。先に挙げた405の拒否はこのときのものです。DB-lessでは、ファイル全体を`/config`へ送ると201が返り、設定が入れ替わります。

```
curl -i -X POST http://localhost:8001/config -F config=@kong.yaml
```

送る前の検査には`deck file validate kong.yaml`が使えます。存在しないalgorithmなどの誤りは、`/config`に送った時点でも`declarative config is invalid`として拒否され、それまでの設定はそのまま残ります。

## KubernetesでのUpstream設定（KongUpstreamPolicy）

Kubernetesでは、Kong Ingress Controller（KIC）がIngressやGateway APIのリソースを読み、Kongの設定に変換します。最新は3.5.14（2026年10月22日）です。Upstreamのアルゴリズムやヘルスチェックは、KIC 3.5で非推奨になった`KongIngress`の代わりに`KongUpstreamPolicy`で宣言し、Serviceのアノテーションで紐付けます。[公式の手順](https://developer.konghq.com/kubernetes-ingress-controller/load-balancing/)にある例は次のとおりです。

```
apiVersion: configuration.konghq.com/v1beta1
kind: KongUpstreamPolicy
metadata:
  name: sample-customization
  namespace: kong
spec:
  algorithm: consistent-hashing
  hashOn:
    header: demo
  hashOnFallback:
    input: ip
---
# 同じnamespace（この例ではkong）の対象Serviceに付けるアノテーション
# konghq.com/upstream-policy: sample-customization
```

KongUpstreamPolicyでも`algorithm: sticky-sessions`を書けますが、KIC 3.5以上に加えてKong Gateway 3.11以上が必要です。OSSの3.9.4をデータプレーンにしているクラスタでは使えません。KICの導入は[Helmとは？チャート・リポジトリ・リリースの基本とhelm repo addなど主要コマンド解説](/tech/details/7694/)の手順でHelmチャートから入れるのが一般的で、Ingressの代わりにGateway APIを使う場合は[Gateway APIとは：Kubernetesの設定手順とHTTPRoute・Ingressからの移行【v1.6系】](/tech/details/18889/)も参照してください。

## NGINX・Traefikとの違いと選び方

KongはOpenResty（NGINX）の上に作られているので、NGINXと競合するのではなく「NGINXにAPI管理の層を足したもの」です。[リバースプロキシとは？仕組み・フォワードプロキシとの違いと導入判断を実装目線で解説](/tech/details/13554/)で扱うような、振り分けとTLS終端だけで足りるならNGINX単体のほうが部品が少なく済みます。利用者ごとのAPIキー・レート制限・ログを、設定ファイルの書き換えでなくAPIやYAMLで管理したくなった時点でKongを入れる価値が出ます。

| 観点       | Kong Gateway     | NGINX            | Traefik        |
| -------- | ---------------- | ---------------- | -------------- |
| 主な用途     | APIゲートウェイ        | Webサーバー・リバースプロキシ | コンテナ向けリバースプロキシ |
| 設定の変え方   | Admin API・宣言ファイル | 設定ファイル＋reload    | ラベル・CRDの自動検出   |
| 負荷分散     | Upstream＋Target  | upstreamディレクティブ  | サービス検出と連動      |
| ヘルスチェック  | アクティブ・パッシブ       | OSS版はパッシブのみ      | アクティブ          |
| 利用者単位の制御 | Consumer＋プラグイン   | 変数をキーに制限設定       | ミドルウェアで一部      |

表の「OSS版はパッシブのみ」は、NGINXのアクティブヘルスチェック（[ngx\_http\_upstream\_hc\_module](https://nginx.org/en/docs/http/ngx%5Fhttp%5Fupstream%5Fhc%5Fmodule.html)）が商用版の機能であるためです。Traefikはコンテナのラベルから経路を自動で組み立てるので、Docker ComposeやKubernetesのサービス検出に経路設定を連動させたい構成では、Traefikを選択肢にできます。Kongを選ぶのは、利用者（Consumer）単位でキーや上限を管理したい場合や、Kubernetesの外の仮想マシンと中のサービスを同じプラグインで扱いたい場合です。逆に、利用者管理や共通プラグインが不要で、経路もほとんど変わらない社内APIでは、Kongを採用せずNGINX単体を選ぶ判断ができます。DB-lessならPostgreSQLもdecKも必須ではありませんが、Kong本体と宣言ファイルの保守は増えます。

APIゲートウェイを含めたAPI基盤の設計や、既存システムとの連携の実装を外部に任せたい場合は、[API開発・システム連携](/service/system/api/)の支援内容をご覧ください。

## よくある質問

### Kong Gatewayとは何ですか？

OpenResty（NGINX＋LuaJIT）上で動くAPIゲートウェイです。ServiceとRouteでリクエストを振り分け、Upstreamで負荷を分散し、認証やレート制限をプラグインで足します。2026年10月時点で、OSS版の最新は3.9.4、商用のKong Gatewayは3.16.0.1です。

### KongのUpstreamとServiceの違いは何ですか？

Serviceはバックエンドの宛先の定義で、Upstreamは複数のTargetをまとめる振り分け先です。単一バックエンドへの転送だけならServiceにURLを指定できます。負荷分散やヘルスチェックを設定する場合は、Targetが1台でもServiceのhostにUpstream名を書きます。

### Kong Gatewayは無料で使えますか？

OSS版（kong/kong）はApache 2.0で無料ですが、リリースは3.9.4で止まっています。商用イメージkong/kong-gatewayは、3.10.0.0のchangelogでfree modeの廃止が告知され、ライセンス無しでは期限切れと同じ扱い（設定は読み取り専用）になると書かれています（breaking-changesのページは「将来削除予定」と記載）。

### KongでUpstreamに振り分けると503になるのはなぜですか？

message が「failure to get a peer from the ring-balancer」なら、Targetを選択できない状態です。全Targetの利用不可に加え、健全なTargetの重みがhealthchecks.thresholdを下回っていないかも確認します。パッシブヘルスチェックで切り離されたTargetは自動では戻らないため、/upstreams/{名前}/health で状態を確かめ、必要なら PUT …/healthy で戻します。

### KongのRouteの優先順位はどう決まりますか？

既定のtraditional\_compatibleルーターでは、methods・hosts・headers・pathsなどを指定した項目の数（match weight）が多いRouteが先に評価され、パスの長さはその後です。priorityフィールドが効くのはexpressionsルーターだけです。

## 関連記事

- [APIゲートウェイとは？役割・機能とリバースプロキシ／サービスメッシュとの違い・導入判断を解説](/tech/details/13210/)
- [API管理とは？APIマネジメントの仕組み・構成要素とゲートウェイとの違いを実装者向けに解説【2026年】](/tech/details/13795/)
- [Kong request-transformerとAI版の違い｜PIIマスキングの落とし穴](/tech/details/2849/)
- [APIレート制限（レートリミット）とは？5方式の比較と429設計・分散実装【2026年版】](/tech/details/16179/)
- [サーキットブレーカーとは？マイクロサービスの障害連鎖を止める仕組みと実装・導入判断を解説](/tech/details/13216/)

---

出典: [Kong GatewayのUpstream設定と負荷分散：Service・Routeの作り方を3.9.4で実測](<https://www.issoh.co.jp/tech/details/4483/>)（株式会社一創）
