Envoy Gateway コア概念: Gateway、Listener、Proxy、Route ファミリーを整理する
Gateway API を初めて見たとき、多くの人はこう感じます。「用語の数はそこまで多くないのに、似た名前の登場人物が一気に出てくる感じで、誰が主役で誰が脇役かわからない。」この記事はその混乱を切り分けるためのものです。あわせて代表的な route type も一通り整理します。
全体アーキテクチャ
Envoy Gateway の公式概念では、全体を 3 層に分けています。
- User Configuration: あなたが書く
Gateway APIリソースと Envoy Gateway 拡張 CRD - Envoy Gateway Controller: リソースを読み、検証し、設定へ変換する
- Envoy Proxy: 実際にトラフィックを処理するデータプレーン
つまり、普段あなたが編集するのは Envoy Proxy そのものではなく、「どうしたいかの宣言」です。 Envoy Gateway がその宣言を Envoy Proxy が実行できる設定に変換します。これが proxy 設定を手で書くより気持ちよい理由です。
主要な役割
今はこの対応関係だけ覚えておけば十分です。
GatewayClass: 「この cluster でどの Gateway 実装を使うか」を定義するGateway: 「入口がどこにあり、どの protocol を話すか」を定義するListener: 特定の port/protocol/hostname の入口スロットを定義するRoute: 「どのリクエストをどの Service に送るか」を定義するEnvoy Proxy: 実際にトラフィックを受けて転送する Gateway Proxy
平たく言うと:
GatewayClassは仕様書Gatewayは建物の正面入口Listenerは受付窓口Routeは館内の案内表示Envoy Proxyは入退室管理と案内を実行するセキュリティシステム
このどれか一つが欠けても、トラフィックは意図した場所へ届きません。
全体像が見える最小 YAML
理解しやすい最小例を見ましょう。
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: eg
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: eg
spec:
gatewayClassName: eg
listeners:
- name: http
protocol: HTTP
port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: backend
spec:
parentRefs:
- name: eg
hostnames:
- "www.example.com"
rules:
- backendRefs:
- name: backend
port: 3000連鎖としてはこうなります。
GatewayClassがEnvoy Gatewaycontroller を担当者として示すGatewayが port80の HTTP 入口を 1 つ宣言するHTTPRouteがwww.example.comへのリクエストをbackend:3000に送ると定義するEnvoy GatewayがこれらをまとめてEnvoy Proxy用に変換する
各 field の理解
GatewayClass
これは cluster-level の入口タイプ定義です。最重要 field はたいていこれです。
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller意味は単純です。
「この GatewayClass は Envoy Gateway controller に管理される。」
controllerName が一致しないと、配達先を別会社にしているようなものです。誰も受け取りません。
Gateway
これは「入口がどう見えるか」を定義します。最もよく参照する field は listeners です。
listeners:
- name: http
protocol: HTTP
port: 80意味は次の通りです。
httpという名前の listener を開く- HTTP トラフィックを受ける
- 外部向けに port
80を listen する
HTTPS なら、通常は protocol: HTTPS の listener を追加し、TLS 設定を付けます。
Gateway がよく管理するもの:
- 外部向けの port と protocol
- listener ごとの hostname
- TLS termination の位置
- どの namespace の route を attach 可能にするか
Gateway は app 側というより platform 層の関心事であることが多く、所有者も platform team になるのが一般的です。
Listener
初心者に最も見落とされやすい役割ですが、実はかなり重要です。
listener は Gateway 上の外向き入口スロットです。次を定義します。
nameportprotocolhostnametlsallowedRoutes
例:
listeners:
- name: https
protocol: HTTPS
port: 443
hostname: api.example.com意味:
- このスロット名は
https - HTTPS を受ける
- port
443を listen する api.example.com専用
たとえば複数 listener を持つなら:
- port 80 用の
http - port 443 用の
https - port 50051 用の
grpc
同じ Gateway の中に複数の入口スロットを開いており、それぞれに別の route を attach できます。
Envoy Proxy
YAML ばかり見て、実際にライブトラフィックを処理するのが Envoy Proxy だという点を忘れる人は少なくありません。
役割は次の通りです。
- クライアントリクエストを受ける
- Envoy Gateway から push された設定にマッチさせる
- 適切な backend へ転送する
- TLS、header、timeout、retry などの data-plane 振る舞いを処理する
なので、Envoy Gateway は「control plane」、Envoy Proxy は「data plane / Gateway Proxy」と考えると整理しやすいです。
Route ファミリー
Route は HTTPRoute だけではありません。このファミリー全体が Gateway API の中心です。
HTTPRoute
最もよく書き換えるのはこれです。代表的な 3 field は次の通りです。
spec:
parentRefs:
- name: eg
hostnames:
- "www.example.com"
rules:
- backendRefs:
- name: backend
port: 3000parentRefs: どの Gateway に attach するかhostnames: どの Host header がこのルールを発火させるかbackendRefs: マッチしたリクエストをどこへ送るか
よくある誤解は、細かいルーティングを Gateway に書くと思ってしまうことです。実際に「どう振り分けるか」を決めるのは HTTPRoute のほうです。
GRPCRoute
gRPC を扱うなら、無理に HTTPRoute に押し込むより GRPCRoute のほうが自然です。
マッチできる対象:
- gRPC hostname
- gRPC service
- gRPC method
- headers
例:
matches:
- method:
service: com.example.User
method: Loginこの意味論は gRPC に自然に一致します。単なる URL path ではなく、gRPC の service/method モデルそのものにマッチできます。
公式ドキュメントでも、GRPCRoute と HTTPRoute が同じ listener を共有し、hostname が衝突した場合は実装側が片方を reject すべきだとされています。要するに、HTTP と gRPC に同じ hostname の取り合いをさせないことです。
TCPRoute
TCPRoute は生の TCP トラフィックを扱います。
HTTPRoute と違って L7 の path や header は理解しません。L4 に近い転送です。
向いている場面:
- 非 HTTP protocol の service
- 純粋な TCP service
- listener port だけを見て異なる backend へ接続を振り分ける
独自 protocol の database や proprietary な TCP protocol は TCPRoute の典型例です。
TLSRoute
TLSRoute は TLS トラフィックを扱い、特に TLS passthrough の場面でよく使われます。
コア概念:
- Gateway が TLS を終端しない場合がある
- TLS handshake の SNI hostname だけでルーティングすることがある
- 暗号化トラフィックを backend までそのまま保つ
これは、end-to-end の暗号化が必要な場面や、Gateway で TLS を終端したくない場面で重要です。
Route type の選び方
| 要件 | 使うもの |
|---|---|
| Web サイト、REST API、一般的な web traffic | HTTPRoute |
| gRPC service/method routing | GRPCRoute |
| 生の TCP トラフィック | TCPRoute |
| TLS passthrough / SNI ベース routing | TLSRoute |
この表が大事なのは、多くの人が何でも HTTPRoute で書き始めてしまうからです。実際には gRPC や TCP を扱っているのに HTTPRoute に押し込むと、YAML がどんどん不自然になります。
なぜ Route のほうが Ingress より整理しやすいのか
従来の Ingress 設定は 1 つのリソースに責務を詰め込みすぎることが多く、いくつかの痛みがありました。
- Platform 設定と app routing が混ざる
- 高度な機能が annotation で表現され、読みづらい
- 非 HTTP protocol の表現力が弱い
Gateway API は責務を分ける方向で設計されています。
- Platform team が
GatewayClass/Gatewayを管理する - App team が自分たちの
HTTPRouteを管理する
この分離は複数人の協業でかなり効きます。path を変えるだけなのに入口全体を触る必要がなくなり、チーム同士で踏み合う事故が大きく減ります。
status を見る習慣をつける
spec だけでなく、徐々に status も見る習慣をつけましょう。特に HTTPRoute と Gateway は重要です。
kubectl get gateway eg -o yaml
kubectl get httproute backend -o yaml最初は次を見るだけでも十分です。
- route が
Acceptedされたか - gateway listener が Ready か
- address が割り当てられたか
提出しただけで終わりにせず、採点されて合格したかまで見る。そんな感覚です。
一文まとめ
GatewayClass、Gateway、Listener、Route、Envoy Proxy を、「誰が管理し、入口がどう開き、各スロットがどうつながり、トラフィックがどう分かれ、誰が実行するのか」として捉えられれば、コア概念の 8 割はもう掴めています。
💡 初心者はすぐ CRD の細部に突っ込みがちです。でも焦らなくて大丈夫です。まずこの役割分担を整理すると、YAML が毎回初対面の他人に見える感じがかなり減ります。
次の一歩
概念が入ったので、次の記事では最もよく使う HTTP ルーティングを掘ります。host、path、header、traffic splitting です。 👉 実践 HTTP ルーティング