Skip to content
Published on

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

Authors

はじめに

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 つのモードをすべてサポートします。

区分標準 IngressAPISIX ネイティブ CRDGateway 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-authAPI キー、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 モードへ移しておいてから段階的に移行する経路が現実的です。

参考資料