- Published on
Apache APISIX Ingress Controller — etcd ベースの動的ルーティング徹底解説
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- はじめに
- Ingress 地形の変化 — なぜ今 APISIX なのか
- APISIX の正体 — データプレーンとコントロールプレーンの分離
- etcd ベースの動的ルーティングが無停止である理由
- デプロイモード — 2 つの動作方式
- 中核となるカスタムリソースの解剖
- プラグイン — ゲートウェイの本当の力
- 標準 Ingress と Gateway API のサポート
- Helm でデプロイする — 実習
- 運用とチューニング
- よく遭遇する落とし穴とトラブルシューティング
- おわりに
- 参考資料
はじめに
Kubernetes 環境で外部トラフィックをクラスタ内へ取り込む入り口は、長らく Ingress リソースと ingress-nginx コントローラが事実上の標準でした。しかし 2026 年現在の状況はかなり変わっています。標準の Ingress API はもう新機能が追加されない凍結(frozen)状態であり、後継標準である Gateway API は GA を過ぎて急速に定着し、ingress-nginx は事実上メンテナンスモードに入りつつ、相次いでセキュリティ問題が報告される流れが続きました。
このような移行期に再び注目されているのが、API ゲートウェイの性格も兼ねる Ingress コントローラです。単に「どのホストのどのパスをどのサービスへ送るか」を超えて、認証・レートリミット・カナリア・可観測性といったゲートウェイ機能をデータプレーンで直接処理したいという要求が高まったからです。Apache APISIX はその中でも、etcd を設定ストアとして使いながら無停止の動的ルーティングを強みとして掲げるプロジェクトです。
本記事では、APISIX Ingress Controller が内部的にどのように動作するのか、なぜ etcd ベースの動的ルーティングがリロードなしの無停止変更を可能にするのか、ApisixRoute のようなカスタムリソースをどう設計しプラグインをどう付与するのか、そして標準 Ingress と Gateway API をどう同時にサポートするのかを、コードと図を中心に深く扱います。最後に Helm による導入実習と、運用現場で頻繁に遭遇する落とし穴をまとめます。基準バージョンは 2026 年上半期時点の APISIX 3.x 系と、APISIX Ingress Controller 1.8 以降の系を想定します。
Ingress 地形の変化 — なぜ今 APISIX なのか
まず 2026 年の Ingress / ゲートウェイ地形を整理しておきます。この文脈を理解してこそ、APISIX がどの空白を狙っているのかが見えてきます。
標準の Ingress API は v1 で安定化された後、意図的に凍結されました。つまりホスト / パスのルーティングと TLS 終端という最小限の機能だけを標準として残し、それ以上はコントローラごとのアノテーションで解決させる形にしたのです。このアノテーションの乱立はコントローラ間の移植性を事実上なくしてしまい、ingress-nginx の巨大なアノテーション表面はセキュリティ脆弱性の温床にもなりました。2025 年前後に報告された一連の ingress-nginx のセキュリティ問題とメンテナンス負担は、多くの組織に代替案の検討を迫りました。
その代替の標準的な方向が Gateway API です。Gateway API は役割分離(インフラ運用者と アプリ開発者)、表現力のあるルーティング(ヘッダー / メソッド / クエリのマッチング、トラフィック分割)、そして移植可能なコア仕様を目標に設計された後継標準です。APISIX Ingress Controller はこの 3 つのモードをすべてサポートします。
| 区分 | 標準 Ingress | APISIX ネイティブ CRD | Gateway API |
|---|---|---|---|
| 標準化レベル | CNCF 標準(凍結) | APISIX 専用 | CNCF 標準(活発) |
| ルーティング表現力 | ホスト / パス中心 | 非常に高い(メソッド / ヘッダー / 優先度) | 高い(フィルタ / マッチ / 重み) |
| 移植性 | アノテーション依存で低い | なし(APISIX 依存) | 高い |
| ゲートウェイ機能 | アノテーションで回避 | CRD で第一級表現 | 一部は拡張で |
| 推奨される用途 | レガシー移行 | APISIX 高度機能のフル活用 | 新規標準の採用 |
要約するとこうです。新規に始めるなら Gateway API を標準経路とし、APISIX の豊富なプラグインと細かなルーティング制御が必要ならネイティブ CRD を併用し、既存の Ingress 資産があるなら標準 Ingress モードで無理なく移行できます。APISIX はこの 3 つの道筋を一つのデータプレーンで処理するという点が核心的な魅力です。
APISIX の正体 — データプレーンとコントロールプレーンの分離
Apache APISIX は OpenResty(Nginx と LuaJIT)の上に構築されたクラウドネイティブな API ゲートウェイです。核心となる設計思想は「設定と実行の分離」であり、これが無停止動的ルーティングの土台になります。
APISIX は大きく 2 つの部分に分かれます。
- データプレーン(apisix): 実際のトラフィックを受け取り、ルーティング・プラグイン・アップストリームへの転送を行う OpenResty ベースのプロセスです。
- 設定ストア(etcd): ルート、アップストリーム、コンシューマ、プラグイン設定といったすべての構成情報を保存するキーバリューストアです。
Kubernetes ではここにもう一層が加わります。
- APISIX Ingress Controller: Kubernetes API サーバを監視(watch)し、ApisixRoute のようなカスタムリソースや標準 Ingress、Gateway API リソースが変わると、それを APISIX の設定へ変換して etcd(または APISIX Admin API)へ反映するコントローラです。
全体構造を ASCII で描くと次のようになります。
+---------------------------------------------------------------+
| Kubernetes クラスタ |
| |
| +-------------------+ watch +----------------+ |
| | kube-apiserver | <------------------ | APISIX Ingress | |
| | - ApisixRoute | | Controller | |
| | - Ingress | 変換して同期 -> | (コントロール) | |
| | - Gateway API | +-------+--------+ |
| +-------------------+ | |
| | Admin |
| | API |
| v |
| +---------------+ |
| 外部トラフィック | etcd | |
| | | (設定ストア) | |
| v +-------+-------+ |
| +---------+ ルート / アップストリーム watch | |
| | apisix | <--------------------------------+ |
| | (データ | |
| | プレーン)| --> バックエンド Service / Pod (アップストリーム) |
| +---------+ |
+---------------------------------------------------------------+
ここで決定的な部分は、データプレーンの apisix が etcd を直接 watch するという点です。etcd の watch メカニズムのおかげで、設定が変わると apisix ワーカーはその変更をほぼリアルタイムでメモリに反映します。新しいルートが追加されたり、アップストリームの重みが変わったりしても、Nginx プロセスをリロードしたり再起動したりする必要がありません。これが「無停止動的ルーティング」の正体です。
etcd ベースの動的ルーティングが無停止である理由
従来の Nginx ベースのゲートウェイでルーティングを変えるということは、通常 nginx.conf を書き直して reload シグナルを送ることを意味しました。reload はマスタープロセスが新しい設定を読み込んで新しいワーカーを起動し、既存のワーカーを優雅に終了させる過程ですが、頻繁な reload は次のようなコストを生みます。
- ワーカー交代の過程で、一時的にメモリやコネクションが 2 倍になることがあります。
- ロングリビングなコネクション(WebSocket、gRPC ストリーム)が切れたり、ドレイニングの遅延が発生したりします。
- 1 秒あたり数十件もルートが変わる環境では、reload 自体がボトルネックになります。
APISIX はこのモデルを根本から変えます。ルートマッチングテーブル、アップストリーム一覧、プラグイン設定が nginx.conf ではなく etcd に保存され、apisix ワーカーはこれを watch しながら LuaJIT ランタイム内の共有メモリ(radixtree ベースのルータ)に読み込みます。設定が変わるとそのメモリ構造だけが更新されるため、プロセスの再起動は起こりません。
流れをステップで描くと次のようになります。
[開発者] kubectl apply -f apisixroute.yaml
|
v
[kube-apiserver] ApisixRoute オブジェクトを保存 + watch イベント発行
|
v
[APISIX Ingress Controller]
- ApisixRoute を APISIX Route/Upstream スキーマへ変換
- 検証(サービスの存在、ポート、プラグインスキーマ)
- Admin API または etcd へ PUT
|
v
[etcd] /apisix/routes/<id> キーを更新 -> watch イベント
|
v
[apisix データプレーンワーカー]
- watch イベントを受信
- radixtree ルータのメモリを更新(reload なし)
|
v
[次のリクエストから新ルーティング適用 — 既存コネクションに影響なし]
このアーキテクチャの実務的な利点は明確です。カナリアデプロイでアップストリームの重みを 5 秒ごとに変えてもデータプレーンは揺らがず、数千個のルートが同時に存在しても radixtree ベースのマッチングはパス長にほぼ比例する定数に近い時間で動作します。さらにコントロールプレーン(Ingress Controller)が一時的に落ちても、apisix データプレーンは etcd にすでに読み込まれた設定でトラフィックを処理し続けます。コントロールプレーンとデータプレーンが障害分離(failure isolation)されているという点は、ゲートウェイの可用性の面で非常に重要です。
ただし etcd が設定の単一の信頼できる情報源(source of truth)になるため、etcd 自体の可用性とバックアップが運用の核心的な関心事になります。この部分は後の運用セクションで改めて扱います。
デプロイモード — 2 つの動作方式
APISIX Ingress Controller は大きく 2 つのデプロイモードを提供します。どのモードを使うかによって、etcd が必要かどうか、コントローラが何を同期するのかが変わります。
| モード | 説明 | etcd 必要 | 特徴 |
|---|---|---|---|
| 標準(default) | コントローラが APISIX Admin API を通じて設定をプッシュし、APISIX は etcd をバックエンドとして使用 | 必要 | 最も一般的、フル機能 |
| etcd 直結(またはコントローラ内蔵同期) | コントローラが変換した設定を直接ストアへ同期 | モードによる | 単純化したトポロジの試み |
2026 年時点での推奨構成は、データプレーンの apisix と etcd を共に置き、Ingress Controller が Admin API で設定を押し込む標準モードです。本記事の実習もこの構成を基準とします。APISIX 陣営ではコントローラとデータプレーンの結合方式がバージョンによって進化してきたため、実際の導入時にはインストールしようとするチャートバージョンのドキュメントで推奨トポロジを必ず確認してください。
中核となるカスタムリソースの解剖
APISIX のネイティブ機能を十分に使うには、標準 Ingress の代わりに APISIX のカスタムリソースを使用します。最も重要な 3 つは ApisixRoute、ApisixUpstream、ApisixPluginConfig です。
ApisixRoute — ルーティングの中心
ApisixRoute はホスト / パス / メソッドのマッチングとバックエンド接続、そしてルート単位のプラグインまで一箇所で表現します。基本形は次のとおりです。
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: orders-route
namespace: shop
spec:
http:
- name: orders
match:
hosts:
- api.example.com
paths:
- /orders/*
methods:
- GET
- POST
backends:
- serviceName: orders-svc
servicePort: 8080
plugins:
- name: limit-count
enable: true
config:
count: 100
time_window: 60
rejected_code: 429
key_type: var
key: remote_addr
ここで注目すべきは match ブロックの表現力です。標準 Ingress がホストとパスだけを扱うのに対し、ApisixRoute は HTTP メソッド、優先度(priority)、そして nginxVars を通じたヘッダー / クッキー / クエリベースのマッチングまで第一級市民としてサポートします。次はヘッダーベースのルーティング例です。
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: beta-route
namespace: shop
spec:
http:
- name: beta-users
priority: 10
match:
hosts:
- api.example.com
paths:
- /orders/*
exprs:
- subject:
scope: Header
name: X-Channel
op: Equal
value: beta
backends:
- serviceName: orders-beta-svc
servicePort: 8080
priority の値が大きいルートが先に評価されるため、上記のベータルートは X-Channel ヘッダーが beta のリクエストを優先的に横取りし、残りはデフォルトルートへ流します。このような表現は標準 Ingress ではきれいに作るのが難しいものです。
ApisixUpstream — バックエンドの細かな制御
ApisixUpstream は特定の Kubernetes Service に対するアップストリームの動作を細かく設定します。ロードバランシングアルゴリズム、ヘルスチェック、リトライ、タイムアウト、パッシブヘルスチェックなどをここで扱います。
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
name: orders-svc
namespace: shop
spec:
loadbalancer:
type: ewma
retries: 2
timeout:
connect: 3s
read: 10s
send: 10s
healthCheck:
active:
type: http
httpPath: /healthz
healthy:
interval: 5
successes: 2
unhealthy:
interval: 5
httpFailures: 3
passive:
healthy:
successes: 3
unhealthy:
httpFailures: 3
tcpFailures: 3
metadata.name が対象 Service の名前と同じでなければならない、という点が核心的なルールです。APISIX Ingress Controller はこのマッチングを通じて、当該 Service へ向かうアップストリームに上記の設定を適用します。ロードバランサのタイプとしてはラウンドロビン、コンシステントハッシュ(chash)、そして応答時間の重み付き移動平均である ewma などを選べるため、レイテンシがばらつくバックエンドに対して ewma で自動回避を狙う、といったチューニングが可能です。
ApisixPluginConfig — プラグインの再利用
複数のルートに同じプラグインの束を繰り返し付与する代わりに、ApisixPluginConfig でプラグインセットを定義しておき、ルートから参照できます。
apiVersion: apisix.apache.org/v2
kind: ApisixPluginConfig
metadata:
name: common-gateway-plugins
namespace: shop
spec:
plugins:
- name: cors
enable: true
config:
allow_origins: "https://app.example.com"
allow_methods: "GET,POST,PUT,DELETE"
allow_headers: "Authorization,Content-Type"
- name: prometheus
enable: true
config:
prefer_name: true
ルートでは次のように参照します。
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: orders-route
namespace: shop
spec:
http:
- name: orders
match:
hosts: ["api.example.com"]
paths: ["/orders/*"]
backends:
- serviceName: orders-svc
servicePort: 8080
plugin_config_name: common-gateway-plugins
こうすると CORS と prometheus の設定を一箇所で管理しながら、数十個のルートに一貫して適用できます。このほかにも ApisixConsumer(コンシューマ / 認証主体)、ApisixTls(証明書)、ApisixClusterConfig(グローバル設定)といったリソースがあり、ゲートウェイのほぼすべての側面を宣言的に扱えます。
プラグイン — ゲートウェイの本当の力
APISIX の差別化点は豊富なプラグインエコシステムです。プラグインはリクエスト処理パイプラインの各ステージ(rewrite、access、header_filter、body_filter、log)にフックとして割り込み、etcd 設定の変更だけで動的にオンオフできます。よく使うプラグインをカテゴリでまとめると次のようになります。
| カテゴリ | 代表的なプラグイン | 用途 |
|---|---|---|
| 認証 | key-auth, jwt-auth, basic-auth, openid-connect, hmac-auth | API キー、JWT、OIDC ベースの認証 |
| トラフィック制御 | limit-count, limit-req, limit-conn, traffic-split | レートリミット、同時実行制限、カナリア分割 |
| セキュリティ | ip-restriction, cors, csrf, ua-restriction | アクセス制御、クロスオリジンポリシー |
| 可観測性 | prometheus, opentelemetry, zipkin, http-logger | メトリクス、分散トレーシング、ログ転送 |
| 変換 | proxy-rewrite, response-rewrite, grpc-transcode | リクエスト / レスポンスの再書き込み、gRPC-JSON 変換 |
認証プラグインの例 — key-auth
API キー認証を付与するには、まずコンシューマを定義し、ルートに key-auth を有効化します。
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: partner-acme
namespace: shop
spec:
authParameter:
keyAuth:
value:
key: acme-secret-key-value
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: partner-api
namespace: shop
spec:
http:
- name: partner
match:
hosts: ["api.example.com"]
paths: ["/partner/*"]
backends:
- serviceName: partner-svc
servicePort: 8080
plugins:
- name: key-auth
enable: true
これでクライアントは apikey ヘッダーに発行されたキーを載せて送らなければ通過できません。実務ではキーの値を平文で置かず、シークレット参照または外部のシークレット管理と連携するパターンが推奨されます。
トラフィック分割の例 — カナリアデプロイ
traffic-split プラグインで重みベースのカナリアを宣言的に構成できます。
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: orders-canary
namespace: shop
spec:
http:
- name: orders
match:
hosts: ["api.example.com"]
paths: ["/orders/*"]
backends:
- serviceName: orders-stable
servicePort: 8080
weight: 90
- serviceName: orders-canary
servicePort: 8080
weight: 10
backends に重みを与えると APISIX が 90 対 10 でトラフィックを分配します。先に強調した動的ルーティングのおかげで、この重みを 90/10 から 50/50 に変えて apply してもデータプレーンは reload なしで即座に新しい比率を反映します。カナリアを段階的に引き上げる自動化パイプラインと相性が良いものです。
可観測性 — prometheus と opentelemetry
ゲートウェイはトラフィックの要衝なので、可観測性のゴールデンスポットです。prometheus プラグインを有効化すると、リクエスト数、レイテンシ分布、ステータスコード別カウントといったメトリクスが公開されます。
apiVersion: apisix.apache.org/v2
kind: ApisixClusterConfig
metadata:
name: default
spec:
monitoring:
prometheus:
enable: true
skywalking:
enable: false
分散トレーシングが必要なら、opentelemetry プラグインでトレースを OTLP コレクタへ送れます。ゲートウェイで trace を開始してバックエンドへ伝播すれば、一つのリクエストがゲートウェイを経て複数のマイクロサービスを通過する全区間を一つのトレースとしてまとめて見られます。
標準 Ingress と Gateway API のサポート
APISIX Ingress Controller の大きな利点は、ネイティブ CRD に閉じ込められないという点です。同じデータプレーンを標準 Ingress と Gateway API でも運転できます。
標準 Ingress モード
既存の Ingress 資産をそのまま持ち込むには、ingressClassName を apisix に指定します。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: legacy-orders
namespace: shop
annotations:
k8s.apisix.apache.org/enable-cors: "true"
spec:
ingressClassName: apisix
rules:
- host: api.example.com
http:
paths:
- path: /orders
pathType: Prefix
backend:
service:
name: orders-svc
port:
number: 8080
標準 Ingress モードの限界は明確です。APISIX の豊富な機能はアノテーションでしか公開されず、そのアノテーションキーは APISIX 専用なので移植性がありません。したがって標準 Ingress モードは「既存資産を無理なく移しておき、段階的にネイティブ CRD や Gateway API へ移行する」移行経路として捉えるのが適切です。
Gateway API モード
新規標準を採用するなら Gateway API を使用します。インフラ運用者が Gateway を定義し、アプリチームが HTTPRoute を付ける役割分離が自然に表現されます。
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: apisix-gateway
namespace: infra
spec:
gatewayClassName: apisix
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: orders-route
namespace: shop
spec:
parentRefs:
- name: apisix-gateway
namespace: infra
hostnames:
- api.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /orders
backendRefs:
- name: orders-svc
port: 8080
weight: 100
Gateway API はトラフィック分割、ヘッダーマッチング、フィルタといった表現を標準仕様として提供するため、コントローラ間の移植性が良好です。2026 年の推奨される方向は、新規ワークロードは Gateway API をデフォルトとし、APISIX 固有のプラグインがどうしても必要なルートに限って ApisixPluginConfig などで補強するハイブリッド戦略です。
Helm でデプロイする — 実習
それでは実際にデプロイしてみます。APISIX、etcd、Ingress Controller を一緒にインストールする最も簡単な経路は公式 Helm チャートです。
まずチャートリポジトリを追加します。
helm repo add apisix https://charts.apiseven.com
helm repo update
kubectl create namespace apisix
次は運用向けの values の例です。核心は etcd を HA で起動し、Ingress Controller を一緒に有効化し、Admin キーと Prometheus の公開を設定する部分です。
apisix:
replicaCount: 3
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: "1"
memory: 1Gi
etcd:
enabled: true
replicaCount: 3
persistence:
enabled: true
size: 10Gi
ingress-controller:
enabled: true
config:
apisix:
serviceNamespace: apisix
resources:
requests:
cpu: 200m
memory: 256Mi
service:
type: LoadBalancer
metrics:
serviceMonitor:
enabled: true
インストールコマンドは次のとおりです。
helm install apisix apisix/apisix \
--namespace apisix \
-f values-prod.yaml
インストール後、核心コンポーネントがすべて起動したか確認します。
kubectl -n apisix get pods
kubectl -n apisix get svc
kubectl -n apisix get crd | grep apisix
CRD 一覧に apisixroutes、apisixupstreams、apisixpluginconfigs などが見えれば、コントローラが正常にインストールされています。これで先に扱った ApisixRoute を apply し、LoadBalancer サービスの外部 IP へリクエストを送ってルーティングを検証できます。
EXTERNAL_IP=$(kubectl -n apisix get svc apisix-gateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -H "Host: api.example.com" "http://$EXTERNAL_IP/orders/123"
運用とチューニング
デプロイが終わったからといって運用が終わったわけではありません。APISIX を本番で安定して回すには、いくつかの核心を押さえる必要があります。
etcd が核心の依存対象である
先に強調したとおり、etcd は設定の単一の信頼できる情報源です。したがって etcd の可用性が、そのままゲートウェイ設定の変更可能性を左右します。次の原則を推奨します。
- etcd は常に奇数ノード(3 または 5)で構成してクォーラムを確保します。
- etcd のディスクは高速な SSD を使い、fsync の遅延を監視します。etcd はディスク遅延に非常に敏感です。
- 定期的なスナップショットバックアップを自動化し、復旧手順を実際にリハーサルします。
- データプレーンが一時的に etcd と切断されても、最後に受け取った設定でトラフィックを処理し続けるという点は安心材料ですが、この状態では新しい設定が反映されないため、切断を素早く察知する必要があります。
リソースとワーカーのチューニング
apisix は OpenResty ベースなので、ワーカープロセス数と共有メモリのサイズが性能に直結します。ノードの CPU 数に合わせてワーカーを設定し、ルートやプラグインの数が多いなら共有辞書のサイズを十分に取ります。CPU の requests / limits を狭く取りすぎるとスロットルでレイテンシが跳ねるため、負荷テストで適正値を見つけるのが良いでしょう。
メトリクスで見る健康シグナル
prometheus プラグインが公開するメトリクスのうち、運用で特に重要なものは次のとおりです。
| メトリクスの性格 | 見るべき理由 |
|---|---|
| リクエストレイテンシ分布 | ゲートウェイ自体のオーバーヘッドとバックエンド遅延を分離して見る |
| ステータスコード別カウント | 4xx の急増は認証 / レートリミット、5xx の急増はアップストリーム障害のシグナル |
| アップストリームのヘルス状態 | ヘルスチェックがバックエンドを外しているか追跡する |
| etcd 接続状態 | 設定同期が切れたかを早期に検知する |
無停止変更の実戦的価値
運用をしていると、ルートを頻繁に変えることになります。新規サービスの追加、カナリア比率の調整、レートリミット閾値のチューニング、緊急の IP 遮断などは、すべて etcd 設定の変更だけで即座に反映されます。reload がないので変更自体が軽い作業になり、これが運用の機敏さにつながります。特にセキュリティインシデント対応で特定のオリジンを ip-restriction で即座に塞ぐといった措置を無停止で行えるという点は、実戦で大きな違いを生みます。
よく遭遇する落とし穴とトラブルシューティング
最後に、現場で頻繁にぶつかる問題と解決の方向をまとめます。
ルートを apply したのに 404 になる
最も一般的な症状です。点検の順序は次のとおりです。
- ingressClassName または gatewayClassName が apisix に正確に指定されているか確認します。クラスが合わないとコントローラはそのリソースを無視します。
- コントローラのログを見ます。変換過程でスキーマ検証に失敗すると、コントローラは etcd に反映しません。
- 対象 Service とポートが実際に存在し、エンドポイントが埋まっているか確認します。
kubectl -n apisix logs deploy/apisix-ingress-controller
kubectl -n shop get endpoints orders-svc
kubectl -n shop describe apisixroute orders-route
設定が etcd に反映されない
コントローラは生きているのに変更がデータプレーンまで届かない場合です。Admin API 認証キーの不一致、コントローラと apisix 間のネットワークポリシー遮断、etcd クォーラムの喪失が定番の原因です。コントローラが Admin API 呼び出しに失敗したログがあるかからまず確認します。
プラグイン設定のスキーマエラー
プラグインの config はプラグインごとにスキーマが厳格です。誤ったフィールドや型を入れると、そのルート全体が拒否されることがあります。疑わしければ小さなルートにプラグインを一つだけ付けて隔離テストを行い、コントローラログの検証エラーメッセージをそのまま追えば、素早く原因を絞り込めます。
Host ヘッダーなしでテストしてルーティングが合わない
hosts マッチングのあるルートは Host ヘッダーが正確に合う必要があります。curl で外部 IP を叩くときに Host ヘッダーを抜かすと、ルートがマッチせず 404 になります。上記の実習の curl 例のように、検証時には必ず Host ヘッダーを指定します。
etcd ディスク遅延による設定反映の遅延
etcd はディスクの fsync に敏感なので、遅いディスクや過負荷状態では設定 PUT のコミットが遅れ、結果としてデータプレーンへの反映も遅くなります。etcd ノードを別の高速ディスクに配置し、etcd 自体のメトリクス(ディスクコミット遅延、リーダー変更頻度)を常に監視することが予防策です。
おわりに
Apache APISIX Ingress Controller の核心は、結局 2 つに要約されます。第一に、設定を etcd に置き、データプレーンがこれを watch することで、reload なしの無停止動的ルーティングを実現するという点。第二に、コントロールプレーンとデータプレーンを分離して障害を分離しながら、標準 Ingress・ネイティブ CRD・Gateway API という 3 つのモードを一つのデータプレーンで運転するという点です。
2026 年の Ingress 地形では標準 Ingress が凍結され、Gateway API が後継標準として定着し、ingress-nginx はメンテナンス負担が大きくなった流れを考えると、豊富なプラグインと動的ルーティングを一度に提供しながら Gateway API までサポートする APISIX は、ゲートウェイを新しく設計するチームにとって十分に魅力的な選択肢です。ただし etcd という追加の依存対象と、それに伴う運用責任を明確に認識し、最初から etcd の HA とバックアップ、そして可観測性を一緒に設計することが、成功する導入の前提条件です。
新規に始めるなら Gateway API を標準の骨格とし、APISIX のプラグインが必要な箇所だけネイティブリソースで補強するハイブリッド戦略を勧めます。既存の Ingress 資産があるなら、標準 Ingress モードへ移しておいてから段階的に移行する経路が現実的です。
参考資料
- Apache APISIX 公式サイト: https://apisix.apache.org
- APISIX Ingress Controller を始める: https://apisix.apache.org/docs/ingress-controller/getting-started/
- APISIX プラグインハブ: https://apisix.apache.org/docs/apisix/plugins/limit-count/
- APISIX Ingress Controller GitHub: https://github.com/apache/apisix-ingress-controller
- Kubernetes Ingress コンセプトドキュメント: https://kubernetes.io/docs/concepts/services-networking/ingress/
- Gateway API 公式ドキュメント: https://gateway-api.sigs.k8s.io/
- etcd 公式ドキュメント: https://etcd.io/docs/
- cert-manager 公式ドキュメント: https://cert-manager.io/docs/
- APISIX Helm チャートリポジトリ: https://github.com/apache/apisix-helm-chart