2026年8月18日
2026年8月18日
KubernetesのIngressでHTTPルーティングを設定する|ホスト名・パス振り分け・TLSと404/503の調べ方
KubernetesのIngressは、外から来たHTTP/HTTPSのリクエストを、ホスト名やURLのパスに応じてクラスター内のServiceへ振り分ける設定です。ただしIngressはルールを書くだけのリソースで、実際に通信を受けるのは別途インストールする「Ingressコントローラー」です。この記事では、コントローラーとIngressClassの関係、ホスト名とパスでの振り分け、TLSの設定、WordPressをIngressの後ろに置くときの注意、つながらないときの調べ方を説明します。
あわせて、Ingressを取り巻く状況の変化にも触れます。後半の「コントローラー選びの現状」は、新しく構築する方は先に読んでおいてください。
Ingressが動く仕組み
通信は次の順に流れます。
- クライアントがIngressコントローラー(クラウドのロードバランサーやNodePort経由)に接続する。
- コントローラーが、Ingressに書かれたホスト名とパスのルールを見て、転送先のServiceを決める。
- Serviceの裏にある、準備完了(Ready)のPodへ転送される。
このため、Ingressを作ってもコントローラーが入っていなければ何も起きません。また、どのコントローラーがそのIngressを担当するかは、IngressClassで決まります。
kubectl get ingressclass
ここに表示される名前(例:nginx、traefik など)を、Ingressの spec.ingressClassName に書きます。何も表示されない場合は、コントローラーが入っていません。minikubeなら minikube addons enable ingress、k3sなら標準でTraefikが入るなど、環境ごとに用意の仕方が異なります。
転送先のServiceを用意する
Ingressの転送先はPodではなくServiceです。まず2つのアプリ(web と api)にServiceがある状態を作ります。
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- port: 80
targetPort: 8080
port はService自身のポート、targetPort はPodのコンテナが待ち受けているポートです。ここを取り違えると、後で502や503の原因になります。api も同じ形で作ります。
ホスト名とパスで振り分ける
1つのドメインで、/api 以下を api に、それ以外を web に送る例です。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
ingressClassName: nginx は例です。kubectl get ingressclass で確認した自分の環境の名前に置き換えてください。
pathType には3種類あります。
Prefix:パスの前方一致です。ただし文字列ではなく/で区切った単位で比べるため、/apiは/apiと/api/usersには一致しますが、/apiv2には一致しません。Exact:パス全体が同じ場合だけ一致します。末尾の/の有無も区別します。ImplementationSpecific:一致の仕方をコントローラーに任せます。コントローラーを変えると動きが変わる可能性があるので、特別な理由がなければPrefixかExactを使います。
複数のルールに一致する場合は、より長いパスが優先され、同じ長さなら Exact が Prefix より優先されます。書く順番では決まらない点に注意してください。
ホスト名ごとに別のサービスへ振り分けるなら、rules にホストを並べます。host を省略したルールは、すべてのホスト名に対して使われます。
HTTPSにする(TLS)
証明書と秘密鍵をTLS用のSecretとして登録し、Ingressの tls で指定します。
kubectl create secret tls app-example-tls --cert=fullchain.pem --key=privkey.pem
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: app-example-tls
rules:
- host: app.example.com
# ...(上と同じ)
SecretはIngressと同じ名前空間に置きます。tls.hosts と rules.host のホスト名、証明書に含まれるホスト名がそろっていないと、コントローラーの仮の証明書が返され、ブラウザで証明書エラーになります。証明書の取得と更新を自動にするなら、cert-managerを組み合わせるのが一般的です。
HTTPからHTTPSへのリダイレクト、URLの書き換え(リライト)、アップロードの最大サイズ、タイムアウトなどは、Ingressの標準の項目にはなく、コントローラーごとのアノテーションや設定で指定します。名前も書き方もコントローラーによって異なるため、使っているコントローラーのドキュメントで確認してください。
WordPressをIngressの後ろに置くときの注意
Ingressコントローラーでの暗号化を終えて、Podへは平文のHTTPで転送する構成では、WordPressは自分がHTTPで呼ばれていると判断します。その結果、管理画面へのリダイレクトが繰り返される、CSSが http:// で読み込まれて表示が崩れる、といった症状が出ます。
コントローラーは通常、元の通信がHTTPSだったことを X-Forwarded-Proto ヘッダーで伝えます。wp-config.php の require_once ABSPATH . 'wp-settings.php'; より前に、次を書きます。
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
$_SERVER['HTTPS'] = 'on';
}
このヘッダーはクライアントが偽装できるため、PodにIngressコントローラー経由でしか到達できない構成(ServiceをClusterIPにする、NetworkPolicyで制限するなど)であることが前提です。メディアのアップロードで413エラーが出る場合は、前述のアップロード上限をコントローラー側で引き上げます。編集前には wp-config.php のバックアップを取ってください。
つながらないときの調べ方
まずIngressの状態を確認します。
kubectl get ingress app
kubectl describe ingress app
そのうえで、症状ごとに起きやすい原因を順に確認します。
- **
ADDRESSが空のまま**:担当するコントローラーがいません。ingressClassNameがkubectl get ingressclassの名前と一致しているか、コントローラーのPodが動いているかを確認します。 - 404が返る:コントローラーまでは届いているが、ルールに一致していません。ホスト名の打ち間違いが多い原因です。DNSを設定する前に試すなら、
curl -H "Host: app.example.com" http://<コントローラーのIP>/のようにHostヘッダーを付けて送ります。 - 503が返る:転送先のServiceに準備完了のPodがありません。次のコマンドで、Serviceに紐づくPodのIPが並んでいるかを見ます。
``bash kubectl get endpointslices -l kubernetes.io/service-name=web
空なら、Serviceの selector とPodのラベルが一致していないか、PodのreadinessProbeが通っていません。
- 502が返る:Podには届いているが応答が得られていません。Serviceの
targetPortとコンテナの実際の待ち受けポートが合っているかを確認します。
これでも分からない場合は、コントローラーのPodのログ(kubectl logs -n <コントローラーの名前空間> <Pod名>)を見ると、どのServiceに転送しようとして失敗したかが記録されています。
コントローラー選びの現状
Ingressの利用者が最も多かったコミュニティ版のコントローラー「Ingress NGINX(kubernetes/ingress-nginx)」は、Kubernetesプロジェクトが2025年11月に開発終了を発表し、2026年3月までで保守を終える方針が示されました(2026年10月現在)。既存の環境がすぐ止まるわけではありませんが、セキュリティ修正が提供されなくなるため、移行の計画が必要です。名前が似ているF5社のNGINX Ingress Controllerは別のプロジェクトなので、混同しないよう注意してください。
Ingressのリソース自体はKubernetesの正式なAPIとして残っており、Traefikなど他のコントローラーで使い続けられます。一方で、Kubernetesプロジェクトは後継としてGateway API(Gateway と HTTPRoute などのリソース)を推しており、ヘッダーによる振り分けや重み付けなど、Ingressでは各コントローラーのアノテーションに頼っていた機能を標準の項目で書けます。新しく構築するなら、使うコントローラーがGateway APIに対応しているかを確認し、選択肢に入れておくとよいでしょう。
まとめ
- Ingressはルールで、通信を受けるのはIngressコントローラー。
ingressClassNameで担当を指定する。 pathTypeはPrefix(/区切りの前方一致)かExactを使い、長いパスが優先される。- TLSは同じ名前空間のTLS用Secretを
tls.secretNameに指定する。リダイレクトや上限値はコントローラーごとの設定。 - WordPressは
X-Forwarded-Protoを見て$_SERVER['HTTPS']を設定する。経路を限定したうえで使う。 - つながらないときは、ADDRESS空→コントローラー、404→ルール、503→EndpointSlice、502→targetPort の順に見る。