Higress actual combat

はじめに

11 月 15 日の Higress オープンソース開発の歴史とデモのライブ配信で、Higress の Wasm プラグインを Ingress リソースに対して設定し、有効化する方法をデモしました。本記事では、当日のデモを振り返り、その背後にある原理と仕組みを解説します。

本記事のデモを実行する前に、Higress を K8s クラスターにインストールし、以下のクイックスタート設定を有効にする必要があります。

https://github.com/alibaba/higress/releases/download/v0.5.2/quickstart.yaml

このデモで実装する機能は Mock レスポンス機能で、設定された内容に従って HTTP レスポンスを返すものです。本記事では以下の構成で解説します。

・コードの記述:コードロジックの分析

・プラグインの有効化:コンパイル、パッケージ化、デプロイ、有効化の方法

・プラグイン機能のテスト:グローバル粒度およびルーティング/ドメイン名粒度での有効化方法

・プラグイン有効化の原理:全体フローの振り返りとプラグイン有効化の原理解説

・3 つの革新的な特徴:Wasm プラグイン機構がゲートウェイのプラグイン開発にもたらす変革

上記のコードには 3 つの関数があります。

・main:プラグインのコンテキストを定義する関数で、プラグイン名、設定を解析する関数、リクエスト/レスポンスを処理する関数を含みます

・parseConfig:SetCtx で指定された ParseConfigBy をプラグイン設定の解析フェーズにマウントする関数です。渡される 3 つのパラメータは以下の通りです。

・json:プラグインに渡される設定は统一的に JSON 辞書オブジェクトにシリアライズされ、parseConfig に解析用として提供されます

・config:parseConfig は解析したプラグイン設定をこの MyConfig オブジェクトに出力します

・log:ログ出力インターフェイスを提供します

・onHttpRequestHeaders:関数内で呼び出される proxywasm.SendHttpResponse は、HTTP レスポンスを直接返すために使用されます。この関数は SetCtx で指定された ProcessRequestHeadersBy を通じて、リクエストヘッダーの解析フェーズにマウントされます。その他のマウント方法は以下の通りです。

・ProcessRequestBodyBy:リクエストボディの解析フェーズにアタッチします

・ProcessResponseHeadersBy:レスポンスヘッダーの構築フェーズにアタッチします

・ProcessResponseBodyBy:レスポンスボディの構築フェーズにアタッチします

渡される 3 つのパラメータは以下の通りです。

・ctx:リクエストコンテキストの取得に使用され、scheme、method、path などの情報を取得できます。ctx を通じてカスタムコンテキストを設定でき、実行フェーズをまたいでアクセス可能です

・config:解析済みのカスタム設定を提供します

・log:ログ出力インターフェイスを提供します

30 行のコードで実装されたプラグインは比較的シンプルです。より複雑な実装例はこちらです。

https://github.com/alibaba/higress/tree/main/plugins/wasm-go/extensions

プラグイン SDK の詳細な使用ドキュメントはこちらです。

https://higress.io/zh-cn/docs/user/wasm-go.html

このプラグイン SDK は Tetrate コミュニティの proxy-wasm-go-sdk を基に実装されています。より低レベルの詳細を確認したい場合は、以下を参照してください。

https://github.com/tetratelabs/proxy-wasm-go-sdk

https://github.com/alibaba/higress/blob/main/plugins/wasm-go/pkg/wrapper

Higress の Wasm Go SDK は、Go 1.18 で導入されたジェネリクス機能を活用してプラグインのコンテキスト処理の詳細をラップしており、プラグイン開発に必要なコード量を削減しています。開発者は設定の解析とリクエスト/レスポンス処理のロジックのみに集中できます。

プラグインの有効化

コードの記述後、プラグインロジックを有効化するには 3 つの手順があります。

1. コンパイル:Go コードを Wasm 形式のファイルにコンパイルする

2. イメージのプッシュ:Wasm ファイルを Docker イメージにパッケージ化し、イメージレジストリにプッシュする

3. 設定の配信:K8s 上で WasmPlugin リソースを作成する

コンパイル

上記の Go ファイル main.go を plugin.wasm にコンパイルします。

tinygo build -o plugin.wasm -scheduler=none -target=wasi main.go

イメージのプッシュ

Dockerfile を作成します。

FROM scratch

COPY plugin.wasm ./

Docker イメージをビルドしてプッシュします(この例では Higress の公式イメージレジストリを使用しています)。

kubectl を使用してこのリソースを作成します。

kubectl apply -f wasmplugin.yaml

プラグイン機能のテスト

変更した設定を有効化します。

kubectl apply -f wasmplugin.yaml

結果は以下の通りです。

・/foo へのリクエストは「hello foo」という HTTP レスポンスを返します(1 番目のルールにマッチ)

・/bar へのリクエストは「hello bar」という HTTP レスポンスを返します(2 番目のルールにマッチ)

・www.example.com へのリクエストは「hello world」という HTTP レスポンスを返します(3 番目のルールにマッチ)

・www.abc.com へのリクエストは「hello hierarchy」という HTTP レスポンスを返します(マッチするルールがないため、グローバル設定を使用)

プラグイン有効化の原理

プラグインの有効化の仕組みを簡単に説明します。

1. ユーザーがコードを Wasm ファイルにコンパイルする

2. ユーザーが Wasm ファイルを Docker イメージにビルドする

3. ユーザーが Docker イメージをイメージレジストリにプッシュする

4. ユーザーが WasmPlugin リソースを作成する

5. Istio が WasmPlugin リソースの変更を監視する

6. Higress ゲートウェイ内の xDS プロキシプロセスが Istio から設定を取得し、プラグインのイメージアドレスを見つける

7. xDS プロキシがイメージレジストリからイメージをプルする

8. xDS プロキシがイメージから Wasm ファイルを抽出する

9. Higress ゲートウェイ内の Envoy プロセスが xDS プロキシから設定を取得し、Wasm ファイルのローカルパスを見つける

10. ローカルファイルから Wasm ファイルをロードして呼び出す

ここでは、ECDS(Extension Config Discovery Service)の仕組みを使用して設定の取得と Wasm ファイルのロードを行っています。Wasm ファイルの更新と直接のホットロードは接続の切断を引き起こさず、ビジネストラフィックは完全に無損失です。

3 つの革新的な特徴

上記の Wasm プラグイン機構は、ゲートウェイのカスタムプラグイン開発に 3 つの革新的な特徴をもたらします。

特徴 1:プラグインのライフサイクルとゲートウェイのデカップリング

この特徴は主に Istio の WasmPlugin 機構の設計によるものです。K8s Nginx と比較するとよく分かります。

Nginx Ingress でカスタムプラグインをロードするには、Lua ファイルを Pod にマウントするか、イメージビルド時に組み込む必要があります。この方式ではプラグインのライフサイクルがゲートウェイに密結合されます。プラグインロジックを更新すると新バージョンのリリースが必要で、ゲートウェイ側も新バージョンのリリースや再デプロイが必要でした。

WasmPlugin 機構では、プラグインの新バージョンリリース時にプラグイン自体のイメージをビルドして配信するだけで有効化でき、イメージタグによるバージョン管理も可能です。これにより、プラグインの変更に伴うゲートウェイの再デプロイが不要になり、Envoy の ECDS メカニズムによりトラフィックへの影響も完全にありません。

特徴 2:高性能なマルチリンガル対応

Wasm の能力により、プラグインを複数の言語で記述でき、開発者にとってより使いやすい環境を提供します。マルチリンガル開発のもう一つの手法として、RPC ベースの外部プロセス/サービスとゲートウェイプロセス間の通信がありますが、この方式には追加の IO オーバーヘッドがあり、追加のプロセス/サービスは運用保守の複雑さも増大させます。パフォーマンス面では、Wasm プラグインの命令実行性能はネイティブ C++ とは差があるものの、Lua と同等の性能を発揮し、外部プラグインを大きく上回ります。

特徴 3:セキュリティサンドボックス

Envoy は現在、V8、WAMR、wasmtime など複数の Wasm ランタイムをサポートしており、これらのランタイムはすべてセキュリティサンドボックス機能を提供します。つまり、Wasm プラグイン内でヌルポインタへのアクセスや未捕捉の例外が発生しても、Envoy のホストプロセスはクラッシュしません。さらに、プラグインに異常が発生した際に Fail Open を設定して、プラグインの実行ロジックをスキップし、ビジネスへの影響を最小限に抑えることができます。

オープンソースコミュニティ

Istio/Envoy コミュニティの先駆的な取り組みに感謝します。おかげで Higress は Ingress リソースで WasmPlugin を有効化でき、Ingress Controller のカスタマイズ性と拡張性を高めることができました。

Tetrate コミュニティが実装した proxy-wasm-go-sdk に特に感謝します。Higress はこれを基に Wasm Go SDK をラップし、プラグイン開発のハードルを下げました。

Higress は Istio/Envoy の Wasm 機能に対してバグ修正を行い、これらはアップストリームコミュニティに取り込まれました。今後も新機能を継続的にアップストリームコミュニティに貢献していく予定です。

Related Articles

Explore More Special Offers

  1. Short Message Service(SMS) & Mail Service

    50,000 email package starts as low as USD 1.99, 120 short messages start at only USD 1.00

phone お問い合わせ
Hi, I'm Alibaba Cloud AI Assistant!
I can help with questions and solutions.