Envoy Gateway Route Type チートシート: HTTPRoute、GRPCRoute、TCPRoute、それとも TLSRoute?

8 min read

前の記事まで読んできたなら、今あなたを止めているのは「Gateway API がわからない」ではなく、むしろこれかもしれません。

「で、実際どれを書くの? HTTPRoute, GRPCRoute, TCPRoute, TLSRoute のどれ?」

この記事はその混線をほどくためのものです。ポケットリファレンスとして残しておいてください。新しい service が出てきたらまずこれを見れば、やみくもに YAML を書いて condition status に説教されるのをかなり減らせます。

先に結論: 4 つの Route Type、4 つの役割

Route Type トラフィック層 何を見ているか 向いているもの 向いていないもの
HTTPRoute L7 HTTP/HTTPS host, path, header, query, method Web サイト、REST API、一般的な web traffic 生の TCP、TLS passthrough
GRPCRoute L7 gRPC hostname, service, method, header gRPC service/method routing 一般的な REST API、生の TCP
TCPRoute L4 TCP Listener と接続レベルの情報 database、独自 TCP protocol、非 HTTP service path/header の判定が必要な場面
TLSRoute L4/L5 TLS TLS SNI hostname TLS passthrough、end-to-end 暗号化維持 復号後に HTTP 詳細を見たい場面

超短縮版が欲しいならこうです。

  • pathheader を見たい → HTTPRoute
  • gRPC の service/method を見たい → GRPCRoute
  • TCP 接続をそのまま流したい → TCPRoute
  • TLS を terminate せず SNI だけで route したい → TLSRoute

3 ステップ判断法: 勘で選ばない

この順番で考えてください。

  1. Gateway はこのトラフィックから HTTP の意味を解釈するか?
  2. するなら、それは通常の HTTP/REST か、gRPC か?
  3. しないなら、生の TCP か、それとも TLS passthrough か?

対応させると:

  • HTTP の path/header/method を見たい → HTTPRoute
  • gRPC の service/method を見たい → GRPCRoute
  • L7 ルール不要で TCP 転送だけしたい → TCPRoute
  • TLS を backend まで保ちたい → TLSRoute

この判断はかなり重要です。多くの人は reflex 的に HTTPRoute から書き始めて、途中で実は database traffic を扱っていたことに気づきます。そこで YAML 全体が「私は今何をしているんだ」状態に入ります。

最小 YAML 例: ひと目で見分ける

それぞれの最短で見分けやすい形を置いておきます。

HTTPRoute

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: web-route
spec:
  parentRefs:
    - name: eg
      sectionName: http
  hostnames:
    - "app.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: api-service
          port: 8080

pathhostnamesbackendRefs が見えたら、まずこれです。

GRPCRoute

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: user-grpc
spec:
  parentRefs:
    - name: eg
      sectionName: grpc
  hostnames:
    - "grpc.example.com"
  rules:
    - matches:
        - method:
            service: com.example.User
            method: Login
      backendRefs:
        - name: user-grpc-service
          port: 50051

method.servicemethod.method が見えたら、通常の HTTP ではなく gRPC の意味を扱っています。

TCPRoute

apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
  name: postgres-route
spec:
  parentRefs:
    - name: eg
      sectionName: postgres
  rules:
    - backendRefs:
        - name: postgres
          port: 5432

TCPRoute にはほとんど path/header の概念がありません。そもそも見ていないからです。 もっと近い感覚は「この listener に到着した TCP connection はこの backend に送る」です。

TLSRoute

apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
  name: passthrough-route
spec:
  parentRefs:
    - name: eg
      sectionName: tls
  hostnames:
    - "db.example.com"
  rules:
    - backendRefs:
        - name: db-service
          port: 5432

通常は protocol: TLS の listener と組み合わせます。焦点は復号ではなく、SNI ベース routing です。

💡 TCPRouteTLSRoute は Gateway API の version によって experimental channel 側にあることがあります。適用前に cluster にインストールされている CRD version を確認してください。

よくある 4 つの落とし穴

1. gRPC だからといって必ず GRPCRoute とは限らない

単に gRPC traffic を通したいだけなら、実装によっては gRPC が HTTP/2 上で動くため HTTPRoute でも扱える場合があります。 ですが、gRPC の service/method でマッチしたいなら GRPCRoute のほうが正しく、読みやすい選択です。

2. TLSRoute は「上級 HTTPS」ではない

これが最も多い誤解です。

  • HTTPS listener + HTTPRoute: Gateway が TLS を terminate してから HTTP ルールを適用する
  • TLS listener + TLSRoute: Gateway は TLS を terminate せず、SNI だけで route する

片方は復号して L7 で処理します。もう片方は暗号化を維持したまま passthrough します。まったく別世界です。

3. TCPRoute では Path/Header は見えない

要件が次なら:

  • /api は A へ
  • /admin は B へ

それは TCPRoute の仕事ではありません。 TCPRoute は HTTP の詳細を理解しません。そこへその要件を押し込むのは、自分で自分に苦行を課しているだけです。

4. parentRefs.sectionName は重要

Gateway に複数 listener があるなら、sectionName を使いましょう。

parentRefs:
  - name: eg
    sectionName: https

これで route が意図した listener に正確に attach されます。 これがないと、VIP ルームを予約したつもりで別会場に入っていた、みたいな事故が起きます。

一文まとめ

まず自分が扱っているのが HTTP、gRPC、TCP、それとも TLS passthrough のどれかを見極めてから、正しい route type を選んでください。 route が合っていれば YAML の 8 割は自然に流れます。間違えると condition status との格闘生活が始まります。

次の一歩

route type が見えてきたら、次によく詰まるのはこれです。 同じ Gateway に listener がたくさんあるとき、どう構造化すれば chaos にならないのか?

次の記事では multi-listener 設計を扱います。 👉 Listener 設計ガイド