RustベースのZtunnelをIstio Ambientサービスメッシュに導入
Istio Ambientメッシュ専用のノード単位プロキシ。
ztunnel(ゼロトラストトンネル)コンポーネントは、Istio Ambientメッシュ専用のノード単位プロキシです。 Ambientメッシュ内のワークロードの安全な接続と認証を担当します。 Ztunnelは、ワークロードのHTTPトラフィックの終了やワークロードのHTTPヘッダーの解析を行うことなく、mTLS、認証、L4承認、テレメトリなど、Ambientメッシュ内のワークロード向けの少数の機能に重点を置いて設計されています。 ztunnelは、トラフィックがWaypointプロキシに効率的かつ安全に転送されることを保証します。Waypointプロキシでは、HTTPテレメトリやロードバランシングなど、Istioの全機能が実装されています。
ztunnelはすべてのKubernetesワーカーノードで実行するように設計されているため、リソースフットプリントを小さく保つことが重要です。 Ztunnelは、ワークロードへの影響を最小限に抑えた、サービスメッシュの不可視(または「アンビエント」)な部分となるように設計されています。
Ztunnelアーキテクチャ
サイドカーと同様に、ztunnelもxDSクライアントとCAクライアントとして機能します
- 起動時に、サービスアカウントトークンを使用してIstiodコントロールプレーンに安全に接続します。 ztunnelからIstiodへの接続がTLSを使用して安全に確立されると、xDSクライアントとしてxDS構成のフェッチを開始します。 これは、サイドカー、ゲートウェイ、またはWaypointプロキシと同様に機能しますが、Istiodはztunnelからのリクエストを認識し、ztunnel専用のxDS構成を送信するという点が異なります。これについては、後ほど詳しく説明します。
- また、CAクライアントとして機能し、管理するすべてのコロケートされたワークロードに代わってmTLS証明書の管理とプロビジョニングを行います。
- トラフィックが出入りする際に、管理するすべてのコロケートされたワークロードのインバウンドおよびアウトバウンドトラフィック(メッシュ外プレーンテキストまたはメッシュ内HBONE)を処理するコアプロキシとして機能します。
- L4テレメトリ(メトリクスとログ)と、必要に応じてztunnelのデバッグに役立つデバッグ情報を含む管理サーバーを提供します。
Envoyを再利用しないのはなぜですか?
Istio Ambientサービスメッシュが2022年9月7日に発表されたとき、ztunnelはEnvoyプロキシを使用して実装されました。 Istioの残りの部分(サイドカー、ゲートウェイ、Waypointプロキシ)にEnvoyを使用しているため、Envoyを使用してztunnelの実装を開始するのは自然なことでした。
しかし、Envoyは他のユースケースには最適でしたが、Envoyでztunnelを実装するのは難しいことがわかりました。これは、多くのトレードオフ、要件、ユースケースがサイドカープロキシやイングレスゲートウェイとは大きく異なるためです。 さらに、Envoyを他のユースケースに最適なものにしているもののほとんど(豊富なL7機能セットや拡張性など)は、これらの機能を必要としないztunnelでは無駄になりました。
専用ztunnel
Envoyをニーズに合わせて調整するのが難しいことが判明した後、ztunnelの専用実装の作成を検討し始めました。 私たちの仮説は、最初から単一の焦点を絞ったユースケースを念頭に置いて設計することで、汎用プロジェクトを独自のユースケースに合わせて成形するよりも、シンプルでパフォーマンスの高いソリューションを開発できるというものでした。 ztunnelをシンプルにするという明確な決定はこの仮説の鍵でした。 たとえば、膨大な数のサポートされている機能と統合を備えたゲートウェイの書き換えには、同様のロジックは通用しません。
この専用ztunnelには、2つの主要な領域が含まれていました
- ztunnelとそのIstiod間の構成プロトコル
- ztunnelのランタイム実装
構成プロトコル
Envoyプロキシは、構成にxDSプロトコルを使用します。 これは、Istioがうまく機能するための重要な部分であり、豊富で動的な構成更新を提供します。 しかし、一般的な方法から外れるにつれて、構成はますます特注になり、生成のコストが大幅に増加します。 サイドカーでは、1つのPodを持つ単一のサービスが約350行のxDS(YAML)を生成しますが、これはすでにスケーリングが困難になっています。 Envoyベースのztunnelははるかに劣っており、一部の領域ではN ^ 2スケーリング属性がありました。
ztunnelの構成をできるだけ小さくするために、必要な情報だけを効率的な形式で含む専用の構成プロトコルの使用を検討しました。 たとえば、単一のPodは簡潔に表現できます
name: helloworld-v1-55446d46d8-ntdbk
namespace: default
serviceAccount: helloworld
node: ambient-worker2
protocol: TCP
status: Healthy
waypointAddresses: []
workloadIp: 10.244.2.8
canonicalName: helloworld
canonicalRevision: v1
workloadName: helloworld-v1
workloadType: deployment
この情報はxDSトランスポートAPIを介して転送されますが、カスタムのAmbient固有のタイプを使用します。 構成の詳細については、ワークロードxDS構成セクションを参照してください。
専用のAPIを使用することで、Envoy構成ではなくプロキシにロジックをプッシュできます。 たとえば、EnvoyでmTLSを構成するには、各サービスの正確なTLS設定を調整する、同一の大きな構成セットを追加する必要があります。 ztunnelでは、mTLSを使用するかどうかを宣言する単一の列挙型のみが必要です。 残りの複雑なロジックは、ztunnelコードに直接埋め込まれています。
Istiodとztunnel間のこの効率的なAPIにより、100,000 Podなどの大規模なメッシュに関する情報を、桁違いに少ない構成でztunnelに構成できることがわかりました。これは、CPU、メモリ、ネットワークのコスト削減につながります。
ランタイム実装
名前が示すように、ztunnelはHTTPSトンネルを使用してユーザーリクエストを伝送します。 Envoyはこのトンネリングをサポートしていますが、構成モデルがニーズに合致していないことがわかりました。 大ざっぱに言うと、Envoyは、リクエストの受け入れからリクエストの送信まで、一連の「フィルター」を介してリクエストを送信することによって動作します。 複数のリクエストレイヤー(トンネル自体とユーザーのリクエスト)と、ロードバランシング後にPod単位のポリシーを適用する必要があるという要件があるため、以前のEnvoyベースのztunnelを実装する際には、接続ごとにこれらのフィルターを4回ループする必要があることがわかりました。 Envoyには、メモリ内で本質的に「自身にリクエストを送信する」ためのいくつかの最適化がありますが、これは依然として非常に複雑でコストがかかります。
独自の実装を構築することで、これらの制約を最初から設計に組み込むことができました。 さらに、設計のあらゆる側面で柔軟性が高まります。 たとえば、スレッド間で接続を共有したり、サービスアカウント間の分離に関するより具体的な要件を実装したりできます。 専用プロキシが実現可能であることを確認した後、実装の詳細を選択しました。
Rustベースのztunnel
ztunnelを高速、安全、軽量にするという目標を掲げ、Rustは当然の選択でした。 しかし、それは私たちの最初の選択ではありませんでした。 IstioでGoを広範囲に使用していることを考えると、Goベースの実装でこれらの目標を達成できることを期待していました。 最初のプロトタイプでは、Goベースの実装とRustベースの実装の両方のシンプルなバージョンを構築しました。 テストの結果、Goベースのバージョンはパフォーマンスとフットプリントの要件を満たしていないことがわかりました。 さらに最適化できた可能性はありますが、Rustベースのプロキシが長期的に最適な実装を提供すると感じました。
C ++実装(おそらくEnvoyの一部を再利用)も検討されました。 しかし、メモリ安全性がないこと、開発者のエクスペリエンスに関する懸念、そしてRustへの一般的な業界トレンドにより、このオプションは採用されませんでした。
この消去法により、Rustが最適な選択肢となりました. Rustは、高性能、低リソース使用率のアプリケーション、特にネットワークアプリケーション(サービスメッシュを含む)で成功した実績があります。 エコシステムのデファクトスタンダードであり、高性能な非同期コードを簡単に記述できる、TokioとHyperライブラリを基盤に構築することを選びました。両ライブラリは、広範囲にわたってテストされ実績があります。
Rustベースのztunnelのクイックツアー
ワークロードxDS構成
ワークロードxDS構成は、理解とデバッグが非常に簡単です。 ztunnel Podのいずれかから `localhost:15000/config_dump` にリクエストを送信するか、便利な `istioctl pc workload` コマンドを使用して表示できます。 ワークロードとポリシーという2つの主要なワークロードxDS構成があります。
ワークロードがAmbientメッシュに含まれる前は、ztunnelはAmbient対応の有無にかかわらずすべてのワークロードを認識しているため、ztunnelの構成ダンプでワークロードを確認できます。 たとえば、以下は、`protocol:TCP`で示されるメッシュ外の、新しくデプロイされたhelloworld v1 Podのサンプルワークロード構成です。
{
"workloads": {
"10.244.2.8": {
"workloadIp": "10.244.2.8",
"protocol": "TCP",
"name": "helloworld-v1-cross-node-55446d46d8-ntdbk",
"namespace": "default",
"serviceAccount": "helloworld",
"workloadName": "helloworld-v1-cross-node",
"workloadType": "deployment",
"canonicalName": "helloworld",
"canonicalRevision": "v1",
"node": "ambient-worker2",
"authorizationPolicies": [],
"status": "Healthy"
}
}
}
PodがAmbientに含まれると(名前空間のデフォルトに`istio.io/dataplane-mode = ambient`のラベルを付けることにより)、`protocol`の値は`HBONE`に置き換えられ、ztunnelはhelloworld-v1 Podからのすべての着信および発信通信をHBONEにアップグレードするように指示します。
{
"workloads": {
"10.244.2.8": {
"workloadIp": "10.244.2.8",
"protocol": "HBONE",
...
}
ワークロードレベルの承認ポリシーをデプロイした後、ポリシー構成はIstiodからztunnelにxDS構成としてプッシュされ、`policies`の下に表示されます。
{
"policies": {
"default/hw-viewer": {
"name": "hw-viewer",
"namespace": "default",
"scope": "WorkloadSelector",
"action": "Allow",
"groups": [[[{
"principals": [{"Exact": "cluster.local/ns/default/sa/sleep"}]
}]]]
}
}
...
}
また、承認ポリシーへの参照がワークロードの構成に更新されていることに気付くでしょう.
{
"workloads": {
"10.244.2.8": {
"workloadIp": "10.244.2.8",
...
"authorizationPolicies": [
"default/hw-viewer"
],
}
...
}
ztunnelによって提供されるL4テレメトリ
ztunnelログが理解しやすいことに驚かれるかもしれません。 たとえば、宛先ztunnelでHTTP Connectリクエストが表示され、送信元Pod IP(`peer_ip`)と宛先Pod IPが示されます。
2023-02-15T20:40:48.628251Z INFO inbound{id=4399fa68cf25b8ebccd472d320ba733f peer_ip=10.244.2.5 peer_id=spiffe://cluster.local/ns/default/sa/sleep}: ztunnel::proxy::inbound: got CONNECT request to 10.244.2.8:5000
`localhost:15020/metrics` APIにアクセスすることで、ワークロードのL4メトリクスを表示できます。このAPIは、サイドカーが公開するものと同じラベルが付いた、TCP 標準メトリクスの完全なセットを提供します。 例えば
istio_tcp_connections_opened_total{
reporter="source",
source_workload="sleep",
source_workload_namespace="default",
source_principal="spiffe://cluster.local/ns/default/sa/sleep",
destination_workload="helloworld-v1",
destination_workload_namespace="default",
destination_principal="spiffe://cluster.local/ns/default/sa/helloworld",
request_protocol="tcp",
connection_security_policy="mutual_tls"
...
} 1
PrometheusとKialiをインストールすると、KialiのUIからこれらのメトリクスを簡単に表示できます。
まとめ
新しいRustベースのztunnelが、以前のEnvoyベースのztunnelよりも大幅に簡素化され、軽量で高性能になったことを非常に嬉しく思っています。 Rustベースのztunnel用に意図的に設計されたワークロードxDSを使用すると、xDS構成をより簡単に理解できるだけでなく、Istiodコントロールプレーンとztunnel間のネットワークトラフィックとコストを劇的に削減できます。 Istio Ambientがアップストリームマスターにマージされたので、入門ガイドに従って新しいRustベースのztunnelを試すことができます。