IstioとKubernetesの生産中。 パート2.トレース

前回の記事では、Service Mesh Istioの基本的なコンポーネントを調べ、システムに精通し、通常Istioでの作業の最初に生じる基本的な質問に答えました。 このパートでは、ネットワーク上でトレース情報のコレクションを整理する方法を見ていきます。







多くの開発者とシステム管理者が最初に遭遇するのは、Service Meshがトレースしているという言葉を聞いたときです。 実際、すべてのTCPトラフィックが通過する各ネットワークノードに特別なプロキシサーバーを追加します。 ネットワーク上のすべてのネットワーク相互作用に関する情報を簡単に送信できるようになりました。 残念ながら、実際には考慮に入れる必要がある多くのニュアンスがあります。 それらを見てみましょう。



誤解第1位:ネットワークを介した旅行のデータを無料で取得できます



実際、比較的無料で、矢印で接続されたシステムのノードと、サービス間を通過するデータレート(実際には、単位時間あたりのバイト数のみ)を取得できます。 ただし、ほとんどの場合、当社のサービスは、HTTP、gRPC、Redisなど、何らかのアプリケーションレベルのプロトコルを使用して通信します。 そしてもちろん、これらのプロトコルに従ってトレース情報を正確に確認したいのです。データのレートではなく、リクエストのレートを確認したいのです。 プロトコルによるリクエストのレイテンシを理解したい。 最後に、システムに入ってからユーザーからの応答を受け取るまでのリクエストの完全なパスを確認します。 このタスクはそれほど簡単に解決されません。



まず、Istioのアーキテクチャの観点から、トレーススパンの送信がどのように見えるかを見てみましょう。 最初の部分から覚えているように、Istioにはテレメトリーを収集するためのミキサーと呼ばれる別のコンポーネントがあります。 ただし、現在のバージョン1.0では*送信はプロキシサーバーから直接、つまり、envoyプロキシを使用して行われます。 Envoyプロキシは、そのままの状態でzipkinプロトコルを介したトレーススパンの送信をサポートしています。 他のプロトコルも接続できますが、プラグインを介してのみ接続できます。 Istioを使用すると、zipkinプロトコルのみをサポートする、組み立てられ構成されたenvoyプロキシをすぐに取得できます。 たとえば、Jaegerプロトコルを使用し、UDP経由でトレーススパンを送信する場合は、istio-proxyイメージをアセンブルする必要があります。 istio-proxyのカスタムプラグインのサポートがありますが、アルファ版のままです。 したがって、多くのカスタム設定なしで実行したい場合、トレーススパンを保存および受信するために使用されるテクノロジの範囲が縮小されます。 実際、メインシステムのうち、Zipkin自体またはJaegerを使用できますが、Zipkin互換プロトコルを使用してすべてを送信できます(効率ははるかに劣ります)。 zipkinプロトコル自体には、HTTPプロトコルを使用してすべてのトレース情報をコレクターに送信することが含まれますが、これは非常に高価です。



先ほど言ったように、アプリケーションレベルのプロトコルを追跡します。 これは、各サービスの隣にあるプロキシサーバーが、現在どのような対話が行われているのかを理解する必要があることを意味します。 デフォルトでは、IstioはすべてのプレーンTCPポートのタイプを設定します。つまり、トレースは送信されません。 トレースを送信するには、最初にメインメッシュ構成でこのオプションを有効にし、非常に重要なことに、サービスで使用されるプロトコルに従ってサービスエンティティkubernetesのすべてのポートの名前を変更する必要があります。 たとえば、次のようになります。



apiVersion: v1 kind: Service metadata: name: nginx spec: ports: - port: 80 targetPort: 80 name: http selector: app: nginx
      
      





http-magicなどの複合名を使用することもできます(Istioはhttpを認識し、このポートをhttpエンドポイントとして認識します)。 形式は、proto-extraです。



プロトコルを定義するための膨大な数の構成にパッチを適用しないために、ダーティな回避策を使用できます。 プロトコル定義ロジックを実行するだけでPilotコンポーネントにパッチを適用します 。 その結果、当然、このロジックを標準に変更し、すべてのポートの命名規則に従う必要があります。



プロトコルが実際に正しく定義されているかどうかを理解するには、envoyプロキシを使用してサイドカーコンテナーに移動し、location / config_dumpを使用してenvoyインターフェースの管理ポートにリクエストを行う必要があります。 結果の構成では、目的のサービスフィールド操作を確認する必要があります。 Istioでは、リクエストの送信先の識別子として使用されます。 Istioでこのパラメーターの値をカスタマイズするには(トレースシステムで確認します)、サイドカーコンテナーを起動する段階でserviceClusterフラグを指定する必要があります。 たとえば、下向きのAPI kubernetesから取得した変数から次のように計算できます。



--serviceCluster ${POD_NAMESPACE}.$(echo ${POD_NAME} | sed -e 's/-[a-z0-9]*-[a-z0-9]*$//g')







特使でトレースがどのように働くかを理解する良い例はここにあります



トレーススパンを送信するエンドポイント自体も、envoyプロキシの開始フラグで指定する必要があります。例:-- --zipkinAddress tracing-collector.tracing:9411







誤解その2:システムに対するリクエストの通過の完全なトレースを安価で入手できます



残念ながら、そうではありません。 実装の複雑さは、サービスの相互作用をどのように実装したかによって異なります。 なぜそう



事実は、istio-proxyがサービスへの着信要求と同じサービスからの要求との対応を理解するためには、すべてのトラフィックを傍受するだけでは不十分です。 何らかの種類のリンク識別子が必要です。 EnvoyプロキシHTTPは特別なヘッダーを使用します。これにより、特定のサービスリクエストが他のサービスへの特定のリクエストを生成することをenvoyが認識します。 そのようなヘッダーのリスト:





たとえば、このようなロジックを追加できるベースクライアントなど、単一のポイントがある場合は、すべてが問題なく、すべてのクライアントがこのライブラリを更新するのを待つだけです。 しかし、非常に異種のシステムがあり、サービスからネットワークを介したサービスへのキャンペーンに統一がない場合、これはおそらく大きな問題になります。 このようなロジックを追加しないと、すべてのトレース情報は「兄弟」のみになります。 つまり、すべてのサービス間相互作用を取得しますが、それらはネットワークを通過する単一のチェーンに接着されません。



おわりに



Istioは、ネットワークを介してトレース情報を収集するための便利なツールを提供しますが、実装にはシステムを調整し、Istioの実装の機能を考慮する必要があることを理解する必要があります。 その結果、2つの主要なポイントを解決する必要があります:アプリケーション層プロトコル(エンボイプロキシでサポートされる必要があります)を決定することと、サービスからの要求からサービスへの要求の接続性に関する情報の転送を設定する(HTTPプロトコルの場合はヘッダーを使用)。 これらの問題が解決されると、多くの異なる言語やフレームワークで記述された非常に異種のシステムであっても、ネットワークから透過的に情報を収集できる強力なツールが手に入ります。



Service Meshに関する次の記事では、Istioの最大の問題の1つであるサイドカープロキシコンテナーごとのメモリ消費量が高いことを検討し、その対処方法について説明します。



All Articles