Envoy Gateway ステータスとデバッグ手引き: Accepted、ResolvedRefs、Programmed の本当の意味

9 min read

エンジニアリングで一番つらいのは、エラーメッセージではなく次の状況です。

YAML を apply した、kubectl apply も成功した、でもトラフィックは流れない。

この時点で spec だけを見つめていると、お茶の葉占いをしている気分になります。 Gateway API で本当に診断に効く情報は status にあります。

この記事の目的は 1 つです。最短の debugging 経路を渡すこと。GatewayHTTPRouteListener が効かないとき、何を最初に見るべきかがわかるようにします。宇宙の整合性をいきなり疑わなくて済むようになります。

まずここから: spec をいじる前に status を読む

最も役立つ command:

kubectl get gateway -A
kubectl get httproute -A
kubectl get grpcroute -A
kubectl describe gateway <name>
kubectl describe httproute <name>
kubectl get gateway <name> -o yaml
kubectl get httproute <name> -o yaml

大事なのは、YAML を 100 回読み直すことではなく、controller が実際に設定を受理したかを確認することです。

status は採点表だと思ってください。

  • spec は提出した解答
  • status はシステムが採点した結果

提出物だけ眺めて採点結果を見ないのは、デバッグではなく感情の安定です。

最重要の 3 condition: まずこれを掴めば足りる

Accepted

これは通常、その resource が parent に受け入れられたかを示します。 route なら、だいたい次を意味します。

  • 意図した Gateway / listener に正常に attach できたか
  • ルールに明らかな衝突や invalid な設定がないか

AcceptedFalse なら、まず疑うのは:

  • parentRefs が間違った Gateway や listener を指している
  • hostname / listener 条件が噛み合っていない
  • listener がこの route type を拒否している
  • allowedRoutes に阻まれている

ResolvedRefs

これは resource 内で参照しているオブジェクトが正しく解決できたかを示します。 たとえば:

  • backendRefs で参照した Service は存在するか
  • certificateRefsSecret は正しく参照可能か
  • Cross-namespace reference 用の ReferenceGrant は適切か

この condition はかなり便利です。 設定失敗の多くは routing logic の間違いではなく、参照先が存在しない、または参照権限がないことです。

Programmed

これは通常、その設定が実装レイヤーに実際に適用されたかを示します。 感覚としてはこうです。

  • controller は設定を受理した
  • そしてそれを data plane や基盤側へ push した

Accepted がすでに True なのにトラフィックが流れないなら、ここで Programmed、Gateway address、listener status、下の Envoy リソースを見る価値が出てきます。

💡 resource によって出る condition の組は多少違いますが、まず直感を作るべき最初の 3 つは AcceptedResolvedRefsProgrammed です。

最短 Debugging フロー: たいていこの順でよい

Step 1: Gateway 自体がちゃんと動いているかを見る

kubectl get gateway -A
kubectl get gateway eg -o yaml

確認ポイント:

  • status.addresses に値があるか
  • listener condition に異常はないか
  • listener の hostname / protocol / port は想定通りか

Gateway に address がなければ、どれだけ美しい route YAML でも、それは創作活動です。

Step 2: Route が正常に attach されたかを見る

kubectl get httproute -A
kubectl get httproute app-route -o yaml

優先して見る項目:

  • status.parents
  • Accepted
  • ResolvedRefs
  • observedGeneration

observedGeneration も意外と大事です。 metadata.generation に追いついていないなら、controller がまだ最新の設定 version を処理していない可能性があります。

Step 3: 参照先 resource が本当に存在するかを見る

ここは一番よく飛ばされるステップです。

kubectl get svc -A
kubectl get secret -A
kubectl get referencegrant -A

よくある問題:

  • Backend service 名が間違っている
  • port が違う
  • Secret が思っている namespace にない
  • Cross-namespace reference に ReferenceGrant がない

ResolvedRefsFalse なら、この線で追うのが定石です。

Step 4: Data Plane と Controller を見る

Gateway と Route の status がどちらもそれなりに正しそうなのに、まだトラフィックが流れないなら、さらに下を見ます。

kubectl get pods -n envoy-gateway-system
kubectl logs -n envoy-gateway-system deployment/envoy-gateway

この段階では「rule が受理されたか」を見ているのではなく、control plane と data plane が正常に動いているかを見ています。

egctl が入っていれば status 確認がより楽になります。 ですが、なくても kubectl get/describe -o yaml で大半の問題は解けます。

よくある 4 つの失敗パターン

1. Route 自体は正しいが、意図した Listener に attach されていない

症状:

  • YAML は正しそう
  • でもトラフィックが rule に当たらない

確認すること:

  • parentRefs.name
  • parentRefs.sectionName
  • Gateway の listener 名が完全一致しているか

複数 listener 構成では、sectionName の typo 1 つで debugging セッションが丸ごと溶けます。

2. Accepted は通るが ResolvedRefs が失敗する

これは通常、attach そのものは可能でも、参照している何かに問題があることを意味します。 よくある原因:

  • Backend Service が存在しない
  • Secret 名が違う
  • Cross-namespace reference に認可がない

このタイプの失敗がいやらしいのは、「もう少しで通りそう」に見えるのに、実際は参照レイヤーで止まっていることです。

3. Gateway に Listener はあるのに想定した Address がない

これはローカル cluster や LoadBalancer 実装のない環境でよく起きます。 Gateway API が壊れているわけではなく、単に基盤が外部 address を払い出していません。

対処:

  • cluster に LoadBalancer 機能があるか確認する
  • port-forward で routing path を検証する

4. YAML は効いたように見えるのに、request が 404 / 503 を返す

この段階では、単一 field のミスというより、どこかのチェーンが切れていることが多いです。

  • Host header が違う
  • path がどの rule にもマッチしていない
  • Backend Pod が unhealthy
  • Service selector がどの Pod も選んでいない

入口の問題に見えても、backend 側がまだ ready でないだけ、ということはよくあります。何でも proxy 層のせいにしないことです。向こうも忙しいです。

一文まとめ

Gateway API を最速で debug する方法は、YAML を何度もいじることではなく status を読む力をつけることです。 Accepted は受理されたか、ResolvedRefs は参照が解決できたか、Programmed は実際に適用されたかを示します。この 3 層を分けて見るだけで、トラブルシュート速度はかなり上がります。

次の一歩

これで 10 本の Envoy Gateway シリーズは完了です。 シリーズ全体の地図に戻りたい場合は:

👉 シリーズ概要