WebAssemblyプラグインのアルファ版リリースのお知らせ
新しいWasmプラグインAPIと、EnvoyおよびIstioにおけるWasmベースのプラグインサポートの更新についてご紹介します。
Istio 1.9では、WebAssembly(Wasm)モジュール配布と、拡張機能開発のための標準的な例とユースケースを含むWasm拡張機能エコシステムリポジトリの試験的サポートが導入されました。過去9か月間、Istio、Envoy、およびProxy-Wasmコミュニティは、Wasm拡張性を安定性、信頼性、そして導入しやすいものにするための共同作業を続けてきました。そして、Istio 1.12におけるWasm拡張性のアルファサポートを発表できることを嬉しく思います!以下のセクションでは、1.12リリースで行われたWasmサポートの更新について説明します。
新しいWasmPlugin API
extensions.istio.io
名前空間の新しいWasmPlugin
CRDにより、カスタムWasmモジュールを使用してIstioプロキシの機能を拡張するための新しい高レベルAPIを導入します。この取り組みは、過去2年間Proxy-Wasmの仕様と実装に費やされた素晴らしい成果に基づいています。今後、プロキシにカスタムWasmモジュールを追加するためにEnvoyFilter
リソースを使用する必要はありません。代わりに、WasmPlugin
リソースを使用できるようになりました。
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: your-filter
spec:
selector:
matchLabels:
app: server
phase: AUTHN
priority: 10
pluginConfig:
someSetting: true
someOtherSetting: false
youNameIt:
- first
- second
url: docker.io/your-org/your-filter:1.0.0
WasmPlugin
とEnvoyFilter
の間には多くの類似点とわずかな違いがあるため、フィールドを1つずつ見ていきましょう。
上記の例では、selector
フィールドに一致するすべてのワークロード(ゲートウェイポッドを含む)にWasmモジュールをデプロイします。これは、EnvoyFilter
とほぼ同じように機能します。
その下の次のフィールドはphase
です。これは、プロキシのフィルターチェーンのどこにWasmモジュールが挿入されるかを決定します。挿入には、4つの異なるフェーズを定義しています。
AUTHN
:Istio認証および認可フィルターの前。AUTHZ
:Istio認証フィルターの後、かつファーストクラスの認可フィルターの前、つまりAuthorizationPolicy
リソースが適用される前。STATS
:すべての認可フィルターの後、かつIstio統計フィルターの前。UNSPECIFIED_PHASE
:コントロールプレーンに挿入場所を決定させます。これは一般的に、フィルターチェーンの最後、ルーターの直前になります。これは、このphase
フィールドのデフォルト値です。
pluginConfig
フィールドは、Wasmプラグインを設定するために使用されます。このフィールドに入力したものはすべてJSONでエンコードされ、フィルターに渡されます。フィルターでは、Proxy-Wasm SDKの構成コールバックでアクセスできます。たとえば、C++ SDKのonConfigure
、Rust SDKのon_configure
、またはGo SDKのOnPluginStart
コールバックを使用して、構成を取得できます。
url
フィールドは、Wasm モジュールを取得する場所を指定します。この例の url
は Docker URI であることに注意してください。HTTP、HTTPS、およびローカルファイルシステム(file:// を使用)を介した Wasm モジュールのロードに加えて、Wasm モジュールを配布するための推奨メカニズムとして OCI イメージ形式を導入しています。
最後に、現在、Wasm Plugin API はインバウンド HTTP フィルターチェーンにのみ適用されることに注意してください。ネットワークフィルターとアウトバウンドトラフィックのサポートは、今後追加される予定です。
Wasmイメージ仕様
コンテナはプロキシ拡張機能を保存、公開、および管理するための理想的な方法であると考えているため、Solo.io と協力して、既存の Proxy-Wasm コンテナ形式を、すべてのレジストリおよび CLI ツールチェーンと互換性のあるように拡張しました。プロセスに応じて、Docker CLI や buildah などの既存のコンテナ CLI ツールを使用して、プロキシ拡張コンテナをビルドできるようになりました。
OCIイメージのビルド方法については、この手順を参照してください。
Istio エージェントのイメージフェッチャー
Istio 1.9 以降、Istio エージェントは、istio エージェント内の xDS プロキシと Envoy の拡張構成検出サービス (ECDS) を活用することで、EnvoyFilters
で構成されたリモート HTTP ソースからフェッチされた Wasm バイナリをロードするための信頼性の高いソリューションを提供してきました。 Istio 1.12 の新しい Wasm API 実装でも同じメカニズムが適用されます。リモートフェッチが失敗した場合に Envoy が誤った構成でスタックする心配なく、HTTP リモートリソースを確実に使用できます。
さらに、Istio 1.12 はこの機能を Wasm OCI イメージに拡張します。つまり、Istio エージェントは Docker Hub、Google Container Registry (GCR)、Amazon Elastic Container Registry (Amazon ECR) など、あらゆる OCI レジストリから Wasm イメージをフェッチできるようになりました。イメージをフェッチした後、Istio エージェントは Wasm バイナリを抽出してキャッシュし、Envoy フィルターチェーンに挿入します。
Envoy Wasm ランタイムの改善
Envoy の V8 を搭載した Wasm ランタイムは Istio 1.5 から出荷されており、それ以来多くの改善が行われています。
WASI サポート
まず、一部の WASI (WebAssembly System Interface) システムコールがサポートされるようになりました。たとえば、clock_time_get
システムコールは Wasm プログラムから行うことができるため、他のネイティブプラットフォームと同様に、Envoy Wasm 拡張機能で Rust で std::time::SystemTime::now()
を使用したり、Go で time.Now().UnixNano()
を使用したりできます。別の例として、random_get
が Envoy でサポートされるようになったため、「crypto/rand」パッケージは Go で暗号的に安全な乱数ジェネレーターとして使用できます。また、Wasm プログラムからローカルファイルの読み取りと書き込みに対するリクエストが見られたため、ファイルシステムのサポートについても検討しています。
デバッグのしやすさ
次はデバッグの改善です。 Envoy ランタイムは、たとえば C++ でヌルポインター例外が発生した場合や Go または Rust でパニック関数が呼び出された場合など、ランタイムエラーが発生したときにプログラムのスタックトレースを出力するようになりました。以前の Envoy エラーメッセージには原因に関する情報が含まれていませんでしたが、現在はトレースが表示されるため、プログラムのデバッグに使用できます。
Function: proxy_on_request_headers failed: Uncaught RuntimeError: unreachable
Proxy-Wasm plugin in-VM backtrace:
0: 0xdbd - runtime._panic
1: 0x103ab - main.anotherCalculation
2: 0x10399 - main.someCalculation
3: 0xea57 - main.myHeaderHandler
4: 0xea15 - proxy_on_request_headers
上記は、Go SDK ベースの Wasm 拡張機能からのスタックトレースの例です。出力にはトレースのファイル名と行番号が含まれていないことに気付くかもしれません。これは、WebAssembly の DWARF 形式と WebAssembly 仕様の例外処理の提案に関連する重要な今後の作業項目と未解決の問題です。
Wasm プログラムの Strace サポート
Envoy によって出力された strace
と同等のログを確認できます。 Istio プロキシのコンポーネントログレベル wasm:trace
を使用すると、Wasm 仮想マシンと Envoy の境界を越えるすべてのシステムコールと Proxy-Wasm ABI コールを観察できます。以下は、そのような strace
ログストリームの例です。
[host->vm] proxy_on_context_create(2, 1)
[host<-vm] proxy_on_context_create return: void
[host->vm] proxy_on_request_headers(2, 8, 1)
[vm->host] wasi_snapshot_preview1.random_get(86928, 32)
[vm<-host] wasi_snapshot_preview1.random_get return: 0
[vm->host] env.proxy_log(2, 87776, 18)
これは、たとえば Wasm プログラムが不正なシステムコールを行っていないことを確認するために、ランタイムで Wasm プログラムの実行をデバッグするのに特に役立ちます。
Wasm 内メトリクスの任意の Prometheus 名前空間
最後の更新はメトリクスに関するものです。 Wasm 拡張機能は、他のメトリックと同様に、独自の カスタムメトリックを定義して Envoy で公開することができましたが、Istio 1.12 より前は、これらのカスタムメトリックはすべて envoy_
Prometheus 名前空間でプレフィックスが付けられており、ユーザーは独自の 名前空間を使用できませんでした。これで、任意の名前空間を選択できるようになり、メトリックは envoy_
のプレフィックスなしでそのまま Envoy で公開されます。
これらのカスタムメトリックを実際に公開するには、グローバル構成の場合は meshConfig
で ProxyConfig.proxyStatsMatcher
を、プロキシごとの構成の場合は proxy.istio.io/config
で構成する必要があることに注意してください。詳細については、Envoy 統計
を参照してください。
今後の作業とフィードバックのお願い
Wasm プラグインのアルファ版の提供を発表しましたが、まだ多くの作業が残っています。重要な作業項目の 1 つは、Wasm API での「イメージプルシークレット」のサポートです。これにより、プライベートリポジトリの OCI イメージを簡単に使用できるようになります。その他には、L4 フィルターのファーストクラスのサポート、Wasm バイナリの署名検証、Envoy のランタイムの改善、Proxy-Wasm SDK の改善、ドキュメントなどがあります。
これは、Istio でファーストクラスの Wasm サポートを提供するという計画のほんの始まりに過ぎません。今後の Istio のリリースで Wasm プラグインを使用した開発エクスペリエンスを向上させることができるよう、皆様からのフィードバックをお待ちしております。