Ingress と Ingress Controller
外部トラフィックがクラスタの中の Service へ入ってくるモデルをまとめる抽象化です。Ingress オブジェクトと Ingress Controller の二層分離、ホスト · パス · pathType ベースのルーティング、TLS 終端と cert-manager、IngressClass、そして後続標準である Gateway API までを体系的に整理します。
第9章 PV / PVC / StorageClass まで扱ったのがクラスタの中のデータが生き残るモデルだったとすれば、本章の視点はクラスタの外へ移ります。外部トラフィックがどうクラスタの中の Service へ入ってくるか のモデルです。第5章 Service の LoadBalancer が外部進入の標準ですが、1つのクラスタに外部公開が必要な Service が数十個あるなら、その分 LoadBalancer を立ち上げる作業が費用 · 管理の両面で重くなります。本章は、その負担をまとめて解くオブジェクト Ingress と、そのマニフェストを実際のルーティングへ落とし込む Ingress Controller の二層を扱います。
本章の終わりには クラウド LoadBalancer 1つの後ろに Ingress Controller が1まとまり、その後ろに ClusterIP Service が複数に分かれる、運用でよくある進入の形 が手に入ります。TLS 終端 · ドメインルーティング · パスルーティングを1か所で扱う標準パターンです。
LoadBalancer 1つでは解けないこと — 出発点 #
第5章 でつかんだ LoadBalancer Service の形を一行に縮めると次のとおりです — type: LoadBalancer の一行でクラウドプロバイダが外部 LB を自動で作ってくれて、その LB の外部 IP で1つの Service のバックエンド Pod たちへトラフィックが流れていきます。単純で十分に強力なモデルです。
問題は Service が1つを超えたときから 始まります。運用クラスタのよくある形を描いてみるとこうです。
webService — ユーザの Web ページapiService — REST API バックエンドadminService — 運用者用の管理ページstaticService — 静的アセット専用
この4つをすべて外部に公開しようとそれぞれ type: LoadBalancer を付けると、クラウド LB が4つできます。AWS の NLB · ALB であれ GCP の LB であれ Azure の LB であれ、LB はそれ自体に時間あたりの費用があり、この費用が Service の個数に比例して累積します。Service が数十個なら LB の費用が無視できない水準になります。
費用だけが負担ではありません。運用面の負担も一緒に増えます。
- ドメインを LB の個数分管理 — 外部に見せるドメインが LB ごとに別に取られる形なので、DNS レコードもその数だけ管理しなければなりません。
- TLS 証明書を LB ごとに別々に — 証明書の発行 · 更新を LB 単位で持っていなければなりません。
- ホスト · パスベースのルーティングができません —
example.com/apiはapiService へ、example.com/staticはstaticService へ流したくても、LoadBalancer Service 1つは1つの Service のバックエンドだけを見ます。このルーティングを解くには誰かが一段載せなければなりません。
この3つを集約して解いてくれる抽象化が Ingress です。1つのクラウド LB の後ろに1つの Ingress Controller が立ち、その Controller がドメイン · パスを見てクラスタの中の複数の Service へトラフィックを分けて送ります。TLS 終端も1か所で処理します。外部から見ると LB 1つに見えますが、中では Ingress マニフェストのルーティングルールに従って分岐される形です。
Ingress の二層 — オブジェクトとコントローラ #
K8s でよく落とし穴になる部分がここにあります。Ingress マニフェストを書いただけではトラフィックが流れない という点です。Ingress は二層が一緒にあって初めて動作します。
| 層 | 何か | 誰が作るか |
|---|---|---|
| Ingress オブジェクト | 「どの host のどの path をどの Service へ送る」という意図を書いたマニフェスト | アプリ開発者または運用者 |
| Ingress Controller | その Ingress オブジェクトを読んで実際にトラフィックをルーティングするランタイム | クラスタ管理者が一度インストール |
Deployment · Service のようなオブジェクトは K8s 本体 (コントロールプレーン) が自分のコントローラで直接処理しますが、Ingress は違います。Ingress コントローラは K8s 本体に入っておらず、外部コンポーネントとしてクラスタに別途インストール しなければなりません。コントローラがないクラスタに Ingress マニフェストを適用するとオブジェクトは作られますがトラフィックはどこへも流れません — apply は成功するのに外部から応答が来ない形で事故になります。
頭の中の図は次のように置くと楽です。
[外部クライアント]
│
▼
[ クラウド LB ] ←── Ingress Controller が公開する1つの Service (LoadBalancer)
│
▼
[ Ingress Controller Pod ] ←── nginx / Traefik / ALB など
│
│ Ingress オブジェクトのルーティングルールを読んで分岐
├──────────┬──────────┐
▼ ▼ ▼
[Service A] [Service B] [Service C]
│ │ │
Pods Pods Pods核心は — 外部クラウド LB は1つ で、その後ろに立った Ingress Controller がすべての Ingress オブジェクトのルールを合わせて実際のルーティングを行う、という点です。クラスタに Ingress オブジェクトを100個書いてもクラウド LB は普通1つのままです。
Ingress Controller の種類 #
Ingress オブジェクトのマニフェスト形式は K8s が標準で定めてありますが、それをどう解釈してルーティングへ解くかはコントローラの実装ごとに異なります。運用でよく出会うコントローラを一表に整理すると次のとおりです。
| コントローラ | どこでよくあるか | 備考 |
|---|---|---|
| ingress-nginx | 最もよくあります。オンプレミス · ローカル · マネージドどこでも | K8s コミュニティが管理。nginx をルーティングエンジンとして使用 |
| Traefik | コンテナ親和環境、自動証明書統合が強み | 設定がアノテーション · CRD で豊富 |
| HAProxy Ingress | 高性能 · 細かいチューニングが必要な環境 | HAProxy ベース |
| AWS Load Balancer Controller | EKS で ALB · NLB として公開するとき | ALB が直接ルーティング。クラスタの中に nginx Pod が別途ない |
| GKE Ingress | GKE 標準提供 | Google Cloud Load Balancer がルーティング |
| AKS Application Gateway Ingress Controller | AKS で Application Gateway へ | Azure がルーティング |
| Cilium | eBPF ベースのネットワーキング、Gateway API に強み | CNI 兼用 |
大きく二系統に分けて見ると理解しやすいです。
- クラスタの中の Pod がルーティング — ingress-nginx、Traefik、HAProxy のようなコントローラは自分の nginx · Traefik Pod をクラスタに立ち上げて、その Pod がトラフィックを受けて処理します。クラウド LB はその Pod の前に単純な L4 分配器として立つ形です。
- クラウドリソースがルーティング — AWS ALB Controller、GKE Ingress、AKS AGIC はクラウドのマネージド LB (ALB · CLB · Application Gateway) 自体がホスト · パスのルーティングをします。クラスタの中には小さなコントローラ Pod があって Ingress オブジェクトをクラウド LB のルールへ翻訳しておくだけです。
同じ Ingress マニフェストでも、どのコントローラが処理するかによってアノテーションのキーと動作が変わります。だからマニフェストにコントローラ固有のアノテーションを書くときは、どのコントローラを使うかから確認しなければなりません。EKS の上で AWS Load Balancer Controller を本格的に扱う部分は 第22章 アプリ配備の骨格 でもう一度本格的に整理します。
Ingress Controller のインストール #
運用クラスタでは普通、1種類のコントローラを一度インストールしておいて、すべての Ingress がそれを通過するようにします。環境ごとのインストールの形を短く押さえておきます。
minikube #
addons コマンドの一行で ingress-nginx がインストールされます。
minikube addons enable ingresskubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-controller-6d4b7f6c8-abc12 1/1 Running 0 30skind #
kind は ingress-nginx を別途マニフェストで適用します。
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yamlさらに kind クラスタを作るとき 80 / 443 ポートをホストへマッピングしておく設定も一緒に必要です。ingress-nginx の公式ガイドに従えばよいです。
EKS / GKE / AKS #
マネージドクラスタではコントローラを Helm でインストールするパターンが標準です。
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx --create-namespaceEKS で AWS ALB Controller を使う場合は別途の IAM · サービスアカウント設定が付いてきます。
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
--namespace kube-system \
--set clusterName=my-cluster \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controllerGKE は Google が管理する GKE Ingress が基本有効化状態なので、別途インストールなしで Ingress マニフェストを適用すると GCLB が自動で作られる体験が可能です。AKS も似た方式のマネージドオプションがあります。
インストールしたコントローラは普通、自分のネームスペース (ingress-nginx、kube-system など) に1まとまりの Pod · Service · Deployment · ConfigMap として立ち上がっています。1台のクラスタにコントローラが1種類だけインストールされていれば普通は十分です。
最初の Ingress マニフェスト — 単純なドメインルーティング #
最も単純な形から始めます。example.com へ入ってくるすべてのトラフィックを web Service の80ポートへ送る Ingress です。
まずバックエンドの Service が立ち上がっていると仮定します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
type: ClusterIP
selector:
app: web
ports:
- port: 80
targetPort: 80Service タイプが ClusterIP だという点が重要です。Ingress の後ろの Service はクラスタ内部専用で十分 です。外部公開は Ingress Controller が自分の LoadBalancer Service 1つで代わりに行うからです。ここの Service に type: LoadBalancer を書く理由はありません。
これで Ingress マニフェストです。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80フィールドを一行ずつ押さえておきます。
apiVersion: networking.k8s.io/v1— Ingress の安定バージョンです。1.19 で stable になり、以前のextensions/v1beta1やnetworking.k8s.io/v1beta1はもう使いません。spec.ingressClassName: nginx— どの Ingress Controller がこのオブジェクトを処理するかを指します。1つのクラスタにコントローラが1種類だけあってそれが default IngressClass なら省略してもよいですが、明示しておく方が安全です。詳しい内容は後のIngressClass節でもう一度見ます。spec.rules[].host: example.com— どのホストのトラフィックかを表現します。HTTP の Host ヘッダ、HTTPS の SNI を見てマッチします。spec.rules[].http.paths[].path: /— マッチするパスです。/はこのホストのすべてのパスを意味します。spec.rules[].http.paths[].pathType: Prefix— パスマッチの方式です。最もよくある値です。spec.rules[].http.paths[].backend.service— マッチしたトラフィックを流す Service の名前とポートです。
このマニフェストを適用したあと状態を見ると次のような形です。
kubectl apply -f ingress-web.yaml
kubectl get ingressNAME CLASS HOSTS ADDRESS PORTS AGE
web nginx example.com 34.120.10.20 80 30sADDRESS のカラムに外部進入点の IP やホスト名が埋まります。この IP が Ingress Controller を公開する LoadBalancer Service の EXTERNAL-IP と同じです。クラスタの中に Ingress オブジェクトが100個あっても、普通この ADDRESS は同じ1つの IP です。
DNS マッピング #
運用で example.com が本当に上の ADDRESS を指すようにするには、外部 DNS に A レコード (または CNAME) をその IP で設定しておかなければなりません。K8s の中で自動で起こることではありません。ExternalDNS のようなツールを使うと Ingress オブジェクトの host フィールドを見てクラウド DNS にレコードを自動で作ってくれる運用パターンもあります。EKS 環境で ExternalDNS と Route 53 を結ぶパターンは 第22章 アプリ配備の骨格 で本格的に扱います。
path ベースのルーティング #
同じホストのパスごとに別の Service へ流したい場合です。example.com/api は backend-api Service、example.com/static は cdn Service へ行く形です。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: backend-api
port:
number: 8080
- path: /static
pathType: Prefix
backend:
service:
name: cdn
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80このマニフェストの動作は次のとおりです。
example.com/api/users→backend-api:8080example.com/static/logo.png→cdn:80example.com/またはexample.com/about→web:80
paths は上から下へ評価されるのではなく マッチがより長いパスが優先 です。/api が / より長くマッチするので /api/users のリクエストは backend-api へ行きます。この優先順位ルールはコントローラの実装ごとに微妙に異なることがあるので、運用ではできる限りマニフェストの中でパスが重ならないように書く方が安全です。
pathType の3つの値 #
pathType はパスマッチの方式を定めます。3つあります。
| 値 | 意味 |
|---|---|
Prefix | パスをスラッシュ単位で切った prefix マッチ。/api は /api、/api/、/api/users にマッチ。/api2 にはマッチしない |
Exact | パスが正確に一致するときだけマッチ |
ImplementationSpecific | コントローラの実装が自分の方式で解釈。ingress-nginx は正規表現まで受ける |
運用で最もよく使う値は Prefix です。Exact は単一エンドポイント1つだけを公開したいとき、ImplementationSpecific はコントローラ固有の機能 (例: ingress-nginx の regex) を使いたいときに選びます。マニフェストの移植性を考えるなら Prefix で統一しておく方が無難です。
Prefix のスラッシュ単位マッチが微妙な部分なので短く押さえておくと — /api と書いたとき /api/users はマッチしますが /api2 はマッチしません。K8s が Prefix を「ディレクトリ prefix」の意味で解釈するからです。この違いがセキュリティと関連することがあります — 意図しないパスが同じバックエンドへ流れていく事故を防いでくれます。
host + path の組み合わせ #
互いに異なるドメインを1つの Ingress で一緒に処理する形です。api.example.com と app.example.com を分けておくよくある構成です。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-api
port:
number: 8080
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80rules 配列に host が異なる項目を2つ入れればよいです。1つの Ingress が複数の host を一緒に持ってもよく、host ごとに別の Ingress オブジェクトを別々に作ってもよいです。運用ではドメイングループ単位で Ingress を分けるパターンがよくあります — ネームスペースごとに1つ、チームごとに1つのように責任が分離されるときにオブジェクトも一緒に分離する形です。
ホストはワイルドカードも支援します。*.example.com と書くと foo.example.com、bar.example.com のような一段階のサブドメインがすべてマッチします。ただし *.example.com は foo.bar.example.com のような二段階はマッチしません — DNS ワイルドカードのそのルールをそのまま従います。
TLS 終端 — Ingress + Secret #
運用で外部進入はほぼ常に HTTPS です。Ingress の tls フィールドと K8s Secret を対にすると、証明書の終端を1か所で処理できます。Secret オブジェクトのメンタルモデル自体は 第6章 ConfigMap と Secret ですでにつかみました。
まず証明書 · キーを入れた Secret が必要です。
kubectl create secret tls example-com-tls \
--cert=fullchain.pem \
--key=privkey.pemSecret のタイプは kubernetes.io/tls で、中には tls.crt (証明書チェーン) と tls.key (秘密鍵) の2つのキーが入っています。マニフェストでも同じ形を作れますが、キーファイルを base64 でエンコードした値をマニフェストに入れることになるので、普通は上のようにコマンドで作る方がきれいです。
この Secret を Ingress に接続します。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
spec:
ingressClassName: nginx
tls:
- hosts:
- example.com
secretName: example-com-tls
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80spec.tls[].hosts に書いたドメインのトラフィックは Ingress Controller が受けるとき TLS を終端し、内側の Service には平文 HTTP で流します。この形のおかげで Service と Pod 側のマニフェストは HTTPS を気にしなくてよく、証明書の更新は Secret を入れ替えるだけで済みます。
cert-manager — 自動発行 · 更新 #
Let’s Encrypt のような無料 CA から証明書を自動発行 · 更新する標準ツールが cert-manager です。cert-manager をクラスタにインストールして ClusterIssuer オブジェクトを一度作っておけば、Ingress マニフェストにアノテーション一行を書くだけで証明書の発行が自動で進みます。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts:
- example.com
secretName: example-com-tls
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80cert-manager.io/cluster-issuer のアノテーションを見て cert-manager が次のサイクルを自動で進めます。
- ACME チャレンジ (HTTP-01 または DNS-01) を通じてドメイン所有の検証。
- Let’s Encrypt から証明書発行。
- 証明書 · キーを
secretNameに書いた Secret として作っておく。 - 満了30日前くらいに自動更新。
cert-manager 自体のインストールと ClusterIssuer の設定は分量が少なくないので本章では形だけ押さえ、EKS の上の ACM 統合と一緒に本格的な使用は 第22章 アプリ配備の骨格 で整理します。運用で cert-manager が事実上の標準になっているので、名前と位置だけ覚えておけば十分です。
IngressClass — コントローラが2つ以上あるとき #
ほとんどのクラスタはコントローラを1種類だけ置きますが、同じクラスタに2種類が一緒にあらなければならない場合もあります。例えば 公開トラフィックは ingress-nginx で、内部管理トラフィックは AWS ALB Controller で 送りたい形です。このときどの Ingress オブジェクトがどのコントローラで処理されるべきかを表現するオブジェクトが IngressClass です。
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
spec:
controller: k8s.io/ingress-nginx核心フィールドは2つです。
spec.controller— どのコントローラの実装がこの IngressClass を処理するかを指す識別子です。ingress-nginx はk8s.io/ingress-nginx、AWS ALB Controller はingress.k8s.aws/albのように実装ごとに決まっています。ingressclass.kubernetes.io/is-default-class: "true"アノテーション — この IngressClass をクラスタの基本として表示します。Ingress マニフェストにingressClassNameを書かないと default IngressClass のコントローラが処理します。
Ingress マニフェストでは spec.ingressClassName でどのクラスに属するかを書きます。
spec:
ingressClassName: alb # AWS ALB Controller が処理
rules:
- host: admin.example.com
...同じクラスタの別の Ingress が ingressClassName: nginx なら、それは ingress-nginx が処理します。2つのコントローラが同じオブジェクトをめぐって衝突しません。
kubectl get ingressclassNAME CONTROLLER PARAMETERS AGE
nginx (default) k8s.io/ingress-nginx <none> 30d
alb ingress.k8s.aws/alb <none> 10d(default) の表示が付いたクラスが default です。クラスタに default IngressClass は1つだけ にするのが標準です。2つが default として表示されると新しい Ingress オブジェクトがどちら側で処理されるか曖昧になります。
Gateway API — Ingress の後続標準 #
最後に一行で押さえておきます。Ingress オブジェクトは単純なホスト · パスのルーティングには十分ですが、より表現力のあるルーティング (ヘッダベース、クエリパラメータベース、重みベースのトラフィック分配など) を扱うにはアノテーションに依存することになり、コントローラごとに変わる限界があります。SIG-Network がその限界を解こうとして作った後続標準が Gateway API です。
Gateway API はオブジェクトを3つに分けます。
| オブジェクト | 役割 |
|---|---|
| GatewayClass | どのコントローラが処理するか (Ingress の IngressClass に対応) |
| Gateway | 外部進入点そのもの (LoadBalancer のようなリソースに対応) |
| HTTPRoute / TCPRoute / TLSRoute | ルーティングルール (Ingress の rules に対応するがより表現力がある) |
ingress-nginx、Traefik、Cilium、Istio のような多くのコントローラが Gateway API を支援していて、新しいクラスタを始める運用者なら Gateway API を検討する段階です。ただし Ingress が依然として最も広く使われる標準 で、既存クラスタで運用者が出会うオブジェクトはほとんどが Ingress です。Gateway API の深いモデルは後続の K8s 深掘り本へ後回しにし、本章では名前と位置だけ押さえる程度にしておきます。
運用パターン — LoadBalancer 1つ + Ingress 多数 #
本章の頭の中の図を一行で固めておきます。運用クラスタの外部進入は普通クラウド LoadBalancer 1つに集まります。 その LoadBalancer は Ingress Controller が自分の公開用に立ち上げた1つの Service (type: LoadBalancer) に付いていて、すべての外部トラフィックがその1つの LB を通過します。
[ クラウド LoadBalancer ] ←── 1つ。費用も1か所
│
▼
[ Ingress Controller (nginx Pod のまとまり) ] ←── ingress-nginx ネームスペース
│
│ Ingress オブジェクトたちのルーティングルール
├──────────┬──────────┬──────────┐
▼ ▼ ▼ ▼
[web] [api] [admin] [static] ←── それぞれ ClusterIP Serviceこの構造の効果を一行に整理すると次のとおりです。
- クラウド LB の費用が1か所 — Service の個数が増えても LB はそのまま1つです。
- TLS 終端が1か所 — 証明書 · cert-manager の設定も1か所に集まります。
- ドメイン · パスルーティングがマニフェストで表現 — 新しい Service の公開は Ingress オブジェクト一行を追加する作業です。
- DNS レコードが単純 —
*.example.comを LB の IP / 名前に一度設定しておけば、すべてのホストがその LB へ入ってきます。
Service の個数とは別にクラウド LB は普通1つですが、トラフィック隔離が必要な場合 (公開 vs 内部など) にはコントローラを2まとまり立ち上げて LB を2つ持つパターンもよくあります。上の IngressClass 節の形がその運用パターンの例です。
Ingress Controller 自体の可用性 #
この構造の一つの危険は — Ingress Controller が単一障害点になり得る という点です。すべての外部トラフィックがその Controller を通過するので、Controller Pod が同時に障害になると全体の外部トラフィックが切れます。運用では次を備えるのが標準です。
- Controller Pod の多重化 — Deployment の
replicasを2以上に設定します。ノード障害時にも1つの Pod は生きているように PodDisruptionBudget · anti-affinity で分散します。 - リソースの余裕 — Controller Pod の CPU · メモリ limits を十分に取っておきます。次の章 第11章 resources.requests / limits で扱うテーマです。
- モニタリング — Controller が公開する Prometheus メトリクス (リクエスト数、5xx 比率、応答時間) をアラートへ連動させます。第19章 可観測性 で本格的に扱います。
練習問題 #
- ローカルクラスタ (minikube または kind) に ingress-nginx をインストールしたあと、
example.comへ入ってくるトラフィックをwebService へ送る単純な Ingress マニフェストを適用してみてください。kubectl get ingressのADDRESSカラムに何が入ってくるか、/etc/hostsに127.0.0.1 example.com(kind) またはminikube ipの値を追加したあとcurl http://example.comがどういう応答をくれるかを時間順に記録します。 - 本文どおり
ingress-paths.yamlを適用したあと、pathTypeをPrefixとExactで交互に変えながらcurl http://example.com/api、curl http://example.com/api/、curl http://example.com/api/users、curl http://example.com/api2の4リクエストがどこへ流れていくかを表に整理します。意図しないパス (/api2) が同じバックエンドへ流れていかないという §「pathType の3つの値」のスラッシュ単位マッチのモデルを自分の表現で一段落にまとめます。 - 同じクラスタに
ingressClassNameが異なる2つの Ingress マニフェストを同時に適用するシナリオをメモしてみましょう — 例えばnginxクラスでexample.com、albクラスでadmin.example.comを公開する形です。2つの IngressClass が一緒にあるクラスタで default が1つだけでなければならない理由、そして default が2つに誤って表示されたとき新しい Ingress がどう動作するかを §「IngressClass」のモデルで一段落に推論します。
一行まとめ: Ingress はクラウド LoadBalancer 1つの後ろでホスト · パスのルーティングと TLS 終端をまとめる二層抽象だ。マニフェストで書く Ingress オブジェクトと、それを読み取って実際のトラフィックを振り分ける Ingress Controller (ingress-nginx · ALB · GKE Ingress など) で構成される。運用の標準はクラウド LB 1つ + Controller 1まとまり + ClusterIP Service 多数、その上に cert-manager で TLS 自動発行と IngressClass で多重コントローラを扱う。後続標準である Gateway API は、より表現力のあるルーティングを担う。
次の章 #
本章で外部進入点の形をつかみながら最後に短く押さえた一つが次の章の出発点になります — Ingress Controller Pod のリソースの余裕 です。Controller がすべての外部トラフィックを処理するので、その Pod に CPU · メモリが足りないとトラフィック自体が詰まります。ところが K8s で Pod が自分に必要なリソースをどう表現し、その表現がスケジューラの決定とノードの OOM 動作にどう影響するかはまだ扱っていません。
第11章 resources.requests / limits では、Pod マニフェストの resources.requests と resources.limits の2つのフィールドのモデル、CPU とメモリの2つのリソースの動作の違い (CPU は throttling、メモリは OOMKill)、QoS クラス (Guaranteed / Burstable / BestEffort)、LimitRange でネームスペースの基本値を強制する運用パターンまでを一連の流れで整理します。