門が二つなら見張りも二人要る
一言でいうと
メッシュに入る入り口(Ingressゲートウェイ)は、サイドカーではなく単独で動くEnvoyです。Istioでその入り口を開く方法は2つあります。すでに起動しているゲートウェイを選んで設定を載せるIstioのGatewayと、Gatewayリソース1つでゲートウェイを新しく立てるKubernetesのGateway APIです。
なぜ必要なのか
サイドカーは、Podの中から出て行き、中へ入るトラフィックを扱います。クラスターの外のユーザーのリクエストは、どのPodのサイドカーでもない場所で受け止める必要があり、そこでTLSを解き、ホスト名で振り分け、おかしなパスを防がなければなりません。KubernetesのIngressリソースは、その仕事をするには表現力が足りませんでした。ヘッダー条件、重み、TLSの方式が、すべてコントローラーごとに違うアノテーションだったからです。
Istioは最初、自前のAPI(Gateway + VirtualService)でこの問題を解き、Kubernetesはその経験をまとめて、ベンダー中立のGateway APIを作りました。IstioのドキュメントはGateway APIを今後の標準のトラフィック管理APIにすると述べています。そのため現在は2つの方式が併用され、同じメッシュに入り口が2つできることがよくあります。
どう動くのか
Istio Gateway: ゲートウェイを選び、受け取るものを決めます。
Gateway mall-gw selector: istio=ingressgateway ← 이미 떠 있는 파드를 고른다
servers: 80 HTTP mall.example.com
443 HTTPS mall.example.com credentialName: mall-cred
VirtualService mall-ingress gateways: [mall-gw] ← 어디로 보낼지는 여기서
Gatewayだけだと、ゲートウェイは受け取りはしても送り先を知らず、404を返します。VirtualServiceがgatewaysにその名前を書いて初めて、両者がつながります。
TLSはSDSで受け取ります。credentialNameはファイルパスではなくSecretの名前です。istiodがそのSecretを読んで、ゲートウェイのEnvoyにSDSで送り込むので、証明書を入れ替えてもゲートウェイを再起動しません。その代わり、SecretはゲートウェイのPodと同じネームスペースに置く必要があります。
Gateway API: Gatewayがゲートウェイを立てます。
| Istio Gateway | Gateway API Gateway | |
|---|---|---|
| ゲートウェイのPod | 事前にインストールされたものをセレクターで選ぶ | Gatewayごとに<이름>-istioのDeploymentとServiceを作る(プレースホルダーは名前です) |
| 立つ場所 | たいていistio-system | Gatewayがあるネームスペース |
| ルーティング | VirtualService(gateways:) |
HTTPRoute(parentRefs:) |
| 細かい調整 | IstioOperator・Helmの値 | infrastructure.parametersRefのConfigMap |
ゲートウェイを自分で立てるということは、チームごとに自分の入り口を別々に増減できるということです。その分Podが増え、何より入り口ごとにポリシーを別々に適用する必要があります。
認可ポリシーもワークロードに付きます。ゲートウェイはEnvoyのワークロードなので、AuthorizationPolicyをセレクターで付けられ、そこで防いだリクエストはメッシュの中に入ってきません。しかしセレクターがistio: ingressgatewayだと、Gateway APIが新しく立てたゲートウェイには適用されません。
現場での姿
Gatewayを作ったのにProgrammedにならない場合です。自動配備されたServiceがLoadBalancerのアドレスを受け取れないと、そうなります。クラウドならロードバランサーのクォータ、オンプレミスならLBの実装がないケースがよくあります。このVMのk3sでは、80番ポートをすでに別のゲートウェイが使っているため、新しいServiceが<pending>のまま留まります。
証明書を替えたのに古い証明書が見える場合です。Secretを別のネームスペースに作ったか、名前がcredentialNameと違っています。istioctl proxy-config secretで、ゲートウェイが実際に受け取った証明書を見れば、すぐに切り分けられます。
管理パスを塞いだのに新しいゲートウェイからは入れる場合です。入り口を新しく開けるときに、警備を移して立て直さなかったケースです。ゲートウェイを追加するときに、認可ポリシーのセレクター(またはtargetRefs)を一緒に見直す必要がある理由です。
公式ドキュメント: Ingress Gateways・Secure Gateways・Kubernetes Gateway API・Authorization on ingress gateways
次のラボですること
VMの中の本物のメッシュ(k3s + Istio 1.31.0)にアプリを2系統載せ、Istio GatewayでHTTP・HTTPSの入り口を開いた後、Gateway APIで2つ目の入り口を立てて、ヘッダーと重みで振り分けます。2つのゲートウェイがどこに立っているかを比べ、1つ目の入り口にかけた/adminの遮断が2つ目の入り口にはかからないことを、ステータスコードで確認します。