概要
KubernetesにIstioを導入し、外部からメッシュ内のPodにアクセスするまでに
何のリソースが関連しているかをざっくり調べてみましたので画像を交えて説明します。
また、例として記載するyamlファイルは一部を抜粋しています。
※私個人の解釈が多く混じっているので別の観点から捉えてみると理解しやすいかもしれません。
代表的なIstioリソースは3つ
- IngressGateway(Service/Pod)
- Gateway(Resource)
- Virtual Service(Resource)
これらのIstioリソースを定義することで最低限のアクセスは可能となります。
DestinationRuleはKubernetesリソースのServiceに対し、同時コネクション数やHTTPリクエスト数の制限、コネクションのアイドル時間の制限といったあらゆる制限を付加することができますが、外部からメッシュ内のPodにとりあえずアクセスしたい場合には必須ではなく、おまけ程度の認識です。
IngressGateway
IngressGatewayは上記画像のようにKubernetesのServiceとDeployment(Pod)で構成します。
ServiceはKubernetesリソースをそのまま使っているだけなので、単純にNodePortと同じ動作をしているように見受けられます。
Podが一番重要な働きをしているように見えていて、Podで受けたトラフィックは後述のIstioリソースに従いトラフィックをコントロールします。
例としてistio-system
Namespaceに対しGatewayリソースをデプロイするとIngressGateway Podに反映されることが確認できます。
確認方法は次のコマンドでPod(Envoy)のconfig_dumpをcurlコマンドでGETし、デプロイ前後で比較します。
kubectl exec [IngressGatewayPodName] -n istio-system -- curl localhost:15000/config_dump
Gateway
トラフィックを受信するとIngressGateway PodはGateway
リソースを確認します。
トラフィックのFQDN、ポート番号、プロトコル
に一致するとVirtualService
リソースでトラフィックをコントロールすることが可能になります。
この時点でのトラフィックの位置はまだIngressGateway Podの中です。
VirtualService
Gateway
の次はVirtualService
リソースに基づきトラフィックをコントロールしていきます。
画像のVirtualService
は特定のGateway
のルールに一致したトラフィックだけを扱うことを明示しています。
http:
以降ではリクエストURIのプレフィックス/hogehoge
に一致した場合に、KubernetesリソースのServiceであるserviceA
の8080ポート
にルーティングします。
ここでやっとIngressGateway Pod
からService
にトラフィックが流れ、その後Service
からPod
に流れていきます。
Pod内にはサイドカーとしてインジェクションされているEnvoy-Proxy
があり、トラフィックを一旦受け取ってからアップストリーム(バックエンド)のApplication
コンテナにトラフィックが渡されます。
外からアクセスができない!どこを調べれば良いの!?
今のトラフィックの流れを見ると
IngressGateway Service
-> IngressGateway Pod
->
serviceA
-> Pod(Envoy-Proxy)
-> Pod(Application)
といったフローになります。
まずは、外部からアクセスした際にIngressGateway Pod
までトラフィックが来ているのかを確認します。
kubectl logs -f [IngressGatewayPodName] -n istio-system
でtail -fモードを使用し、ログをリアルタイムで確認できる状態にします。
次にブラウザやcurlコマンドで外部からアクセスしてみます。
その時にログとして確認できればIngressGateway
としては正常に動いています。
しかし、そこからService
までの経路が繋がっていない可能性があるため、Gateway
やVirtualService
が正しく設定されているか見直してみます。
逆にIngressGateway Pod
のログからトラフィックを確認できない場合は、IngressGateway Service
の設定に問題があるか、そもそもワーカーノードのポートまでたどり着けていない可能性がありますので、外部LBのフォワーディング設定やELBのターゲットグループ設定を確認してみると良いかもしれません。
そもそもアクセスログが出力されないのですが???
Istio導入直後はkubectl logs
でアクセスログを確認できません。
kubectl edit configmap istio -n istio-system
を実行し、AccessLogFile
の値を/dev/stdout
に変更します。
詳細についてはこちらのページで解説しています。
istio-proxy(Envoy)を通過するhttp accessログを出力させる(Pod個別設定)
ここまでざっくりとIngress通信について解説しましたが
「これは違うんじゃないのかな〜?」「私はこう解釈してるよ」といったコメント頂けると本当に嬉しいです。
そもそも私の解釈が全て正解だとは思っていないので他の方の意見も聞いてみたいというのが本音です。