1.19. 拡張
WebAssembly 拡張機能を使用して、Red Hat Service Mesh プロキシーに直接新しい機能を追加できます。これにより、お使いのアプリケーションから、さらに一般的な機能を移動して、単一の言語で実装して、WebAssembly bytecode にコンパイルできます。
WebAssembly 拡張機能は、IBM Z および IBM Power ではサポートされていません。
1.19.1. WebAssembly モジュールの概要
WebAssembly モジュールは、プロキシーなどの多くのプラットフォームで実行でき、これには、幅広い言語サポート、高速実行、および sandboxed-by-default (デフォルトでサンドボックス化される) セキュリティーモデルが含まれます。
Red Hat OpenShift Service Mesh 拡張機能として Envoy HTTP フィルター を使用でき、幅広い機能を提供します。
- 要求と応答の本体とヘッダーの操作
- 認証やポリシーのチェックなど、要求パスにないサービスへの帯域外 HTTP 要求
- 相互に通信するフィルター用のサイドチャネルデータストレージおよびキュー
新しい WebAssembly 拡張機能を作成するときは、WasmPluginAPI を使用してください。ServiceMeshExtension API は、Red Hat OpenShift Service Mesh バージョン 2.2 で非推奨になり、今後のリリースで削除される予定です。
Red Hat OpenShift Service Mesh 拡張機能の作成には 2 つの部分があります。
- proxy-wasm API を公開する SDK を使用して拡張機能を記述し、それを WebAssembly モジュールにコンパイルする必要があります。
- 次に、モジュールをコンテナーにパッケージ化する必要があります。
サポートされる言語
WebAssembly バイトコードにコンパイルする言語を使用して Red Hat OpenShift Service Mesh 拡張を作成できますが、以下の言語には proxy-wasm API を公開する既存の SDK があるため、これを直接使用できます。
表1.14 サポートされる言語
| 言語 | 保守管理者 | リポジトリー |
|---|---|---|
| AssemblyScript | solo.io | |
| C++ | proxy-wasm チーム (Istio コミュニティー) | |
| Go | tetrate.io | |
| Rust | proxy-wasm チーム (Istio コミュニティー) |
1.19.2. WasmPlugin コンテナー形式
Istio は、Wasm プラグインメカニズムで Open Container Initiative (OCI) イメージをサポートしています。Wasm プラグインをコンテナーイメージとして配布でき、spec.url フィールドを使用してコンテナーレジストリーの場所を参照できます。たとえば、quay.io/my-username/my-plugin:latest です。
WASM モジュールの各実行環境 (ランタイム) にはランタイム固有の設定パラメーターを設定できるため、WASM イメージは次の 2 つの階層で設定できます。
-
plugin.wasm (必須) - コンテンツレイヤー。このレイヤーは、ランタイムによってロードされる WebAssembly モジュールのバイトコードを含む
.wasmバイナリーで設定されます。このファイルにはplugin.wasmという名前を付ける必要があります。 - runtime-config.json (オプション) - 設定レイヤー。このレイヤーは、ターゲットランタイムのモジュールに関するメタデータを記述する JSON 形式の文字列で設定されます。ターゲットランタイムによっては、設定レイヤーに追加のデータが含まれる場合もあります。たとえば、WASM Envoy Filter の設定には、フィルターで使用可能な root_ids が含まれています。
1.19.3. WasmPlugin API リファレンス
WasmPlugins API には、WebAssembly フィルターを介して Istio プロキシーによって提供される機能を拡張するメカニズムがあります。
複数の WasmPlugin をデプロイできます。phase および priority の設定により、実行の順序が (Envoy のフィルターチェーンの一部として) 決定され、ユーザー提供の WasmPlugins と Istio の内部フィルター間の複雑な対話設定が可能になります。
次の例では、認証フィルターが OpenID フローを実装し、Authorization ヘッダーに JSON Web Token (JWT) を入力します。Istio 認証はこのトークンを消費し、ingress ゲートウェイにデプロイします。WasmPlugin ファイルはプロキシーサイドカーファイルシステムに存在します。フィールドの URL に注意してください。
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: openid-connect
namespace: istio-ingress
spec:
selector:
matchLabels:
istio: ingressgateway
url: file:///opt/filters/openid.wasm
sha256: 1ef0c9a92b0420cf25f7fe5d481b231464bc88f486ca3b9c83ed5cc21d2f6210
phase: AUTHN
pluginConfig:
openid_server: authn
openid_realm: ingress
以下は同じ例ですが、今回はファイルシステム内のファイルの代わりに Open Container Initiative (OCI) イメージが使用されています。フィールド url、imagePullPolicy、および imagePullSecret に注意してください。
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: openid-connect
namespace: istio-system
spec:
selector:
matchLabels:
istio: ingressgateway
url: oci://private-registry:5000/openid-connect/openid:latest
imagePullPolicy: IfNotPresent
imagePullSecret: private-registry-pull-secret
phase: AUTHN
pluginConfig:
openid_server: authn
openid_realm: ingress表1.15 WasmPlugin フィールドリファレンス
| フィールド | タイプ | 説明 | 必須 |
|---|---|---|---|
| spec.selector | WorkloadSelector |
このプラグイン設定を適用する必要がある Pod/VM の特定のセットを選択するために使用される基準。省略した場合に、この設定は同じ namespace 内のすべてのワークロードインスタンスに適用されます。 | いいえ |
| spec.url | 文字列 |
Wasm モジュールまたは OCI コンテナーの URL。スキームが存在しない場合には、デフォルトで | いいえ |
| spec.sha256 | 文字列 |
Wasm モジュールまたは OCI コンテナーの検証に使用される SHA256 チェックサム。 | いいえ |
| spec.imagePullPolicy | PullPolicy |
OCI イメージをフェッチするときに適用されるプル動作。イメージが SHA ではなくタグで参照されている場合にのみ参照します。デフォルト値は | いいえ |
| spec.imagePullSecret | 文字列 |
OCI イメージのプルに使用するクレデンシャル。イメージをプルするときにレジストリーに対して認証するためのプルシークレットなど、 | いいえ |
| spec.phase | PluginPhase |
フィルターチェーンのどこにこの | いいえ |
| spec.priority |
|
| いいえ |
| spec.pluginName | string | Envoy 設定で使用されるプラグイン名。一部の Wasm モジュールでは、実行する Wasm プラグインを選択するためにこの値が必要になる場合があります。 | いいえ |
| spec.pluginConfig | Struct | プラグインに渡される設定。 | いいえ |
| spec.pluginConfig.verificationKey | 文字列 | 署名された OCI イメージまたは Wasm モジュールの署名を検証するために使用される公開鍵。PEM 形式で指定する必要があります。 | いいえ |
WorkloadSelector オブジェクトは、フィルターをプロキシーに適用できるかどうかを判別するために使用される条件を指定します。一致の条件には、プロキシーに関連付けられたメタデータ、Pod/VM に添付されたラベルなどのワークロードインスタンス情報、またはプロキシーが最初のハンドシェイク中に Istio に提供するその他の情報が含まれます。複数の条件が指定されている場合には、ワークロードインスタンスを選択するには、すべての条件が一致する必要があります。現在、ラベルベースの選択メカニズムのみがサポートされています。
表1.16 WorkloadSelector
| フィールド | タイプ | 説明 | 必須 |
|---|---|---|---|
| matchLabels | map<string, string> | ポリシーを適用する必要がある Pod/VM の特定のセットを示す 1 つ以上のラベル。ラベル検索の範囲は、リソースが存在する設定 namespace に限定されます。 | はい |
PullPolicy オブジェクトは、OCI イメージをフェッチするときに適用されるプル動作を指定します。
表1.17 PullPolicy
| 値 | 説明 |
|---|---|
| <empty> |
デフォルト値は |
| IfNotPresent | イメージの既存のバージョンが以前にプルされている場合は、それが使用されます。イメージのバージョンがローカルに存在しない場合は、最新バージョンをプルします。 |
| Always | このプラグインを適用するときは、常に最新バージョンのイメージをプルします。 |
Struct は、動的に型付けされた値にマップされるフィールドで設定される構造化データ値を表します。一部の言語では、Struct はネイティブ表現でサポートされている場合があります。たとえば、JavaScript のようなスクリプト言語では、構造体はオブジェクトとして表されます。
表1.18 Struct
| フィールド | タイプ | 説明 |
|---|---|---|
| fields | map<string, Value> | 動的に型付けされた値のマップ。 |
PluginPhase は、プラグインが注入されるフィルターチェーンのフェーズを指定します。
表1.19 PluginPhase
| フィールド | 説明 |
|---|---|
| <empty> | コントロールプレーンは、プラグインを挿入する場所を決定します。これは通常、フィルターチェーンの最後かつ、ルーターの直前にあります。プラグインが他のプラグインから独立している場合は、PluginPhase を指定しないでください。 |
| AUTHN | Istio 認証フィルターの前にプラグインを挿入します。 |
| AUTHZ | Istio 認証フィルターの前と Istio 認証フィルターの後にプラグインを挿入します。 |
| STATS | Istio 統計フィルターの前と Istio 認証フィルターの後にプラグインを挿入します。 |
1.19.3.1. WasmPlugin リソースのデプロイ
WasmPlugin リソースを使用して、Red Hat Service Mesh エクステンションを有効にできます。この例では、istio-system が Service Mesh コントロールプレーンプロジェクトの名前です。次の例では、OpenID Connect フローを実行してユーザーを認証する openid-connect フィルターを作成します。
手順
以下のリソース例を作成します。
plugin.yaml の例
apiVersion: extensions.istio.io/v1alpha1 kind: WasmPlugin metadata: name: openid-connect namespace: istio-system spec: selector: matchLabels: istio: ingressgateway url: oci://private-registry:5000/openid-connect/openid:latest imagePullPolicy: IfNotPresent imagePullSecret: private-registry-pull-secret phase: AUTHN pluginConfig: openid_server: authn openid_realm: ingress次のコマンドを使用して
plugin.yamlファイルを適用します。$ oc apply -f plugin.yaml
1.19.4. ServiceMeshExtension コンテナー形式
コンテナーイメージを有効な拡張イメージにするために、WebAssembly モジュールのバイトコードを含む .wasm ファイルとコンテナーファイルシステムのルートに manifest.yaml ファイルが必要です。
新しい WebAssembly 拡張機能を作成するときは、WasmPlugin を使用してください。ServiceMeshExtension は、Red Hat OpenShift Service Mesh バージョン 2.2 で非推奨になり、今後のリリースで削除される予定です。
manifest.yaml
schemaVersion: 1 name: <your-extension> description: <description> version: 1.0.0 phase: PreAuthZ priority: 100 module: extension.wasm
表1.20 manifest.yml フィールドの参照情報
| フィールド | 説明 | 必須 |
|---|---|---|
| schemaVersion |
マニフェストスキーマのバージョン管理に使用されます。現時点で使用できる値は | これは必須フィールドです。 |
| name | 拡張の名前です。 | このフィールドは単なるメタデータであり、現時点では使用されていません。 |
| description | 拡張の説明。 | このフィールドは単なるメタデータであり、現時点では使用されていません。 |
| version | 拡張のバージョンです。 | このフィールドは単なるメタデータであり、現時点では使用されていません。 |
| phase | 拡張のデフォルトの実行フェーズです。 | これは必須フィールドです。 |
| priority | 拡張のデフォルトの優先度です。 | これは必須フィールドです。 |
| module | コンテナーファイルシステムのルートから WebAssembly モジュールへの相対パスです。 | これは必須フィールドです。 |
1.19.5. ServiceMeshExtension リファレンス
ServiceMeshExtension API には、WebAssembly フィルターを介して Istio プロキシーによって提供される機能を拡張するメカニズムがあります。WebAssembly 拡張機能の作成には 2 つの部分があります。
- proxy-wasm API を公開する SDK を使用して拡張機能を記述し、それを WebAssembly モジュールにコンパイルします。
- コンテナーにパッケージ化します。
新しい WebAssembly 拡張機能を作成するときは、WasmPlugin を使用してください。ServiceMeshExtension は、Red Hat OpenShift Service Mesh バージョン 2.2 で非推奨になり、今後のリリースで削除される予定です。
表1.21 ServiceMeshExtension フィールドの参照情報
| フィールド | 説明 |
|---|---|
| metadata.namespace |
|
| spec.workloadSelector |
|
| spec.config | これは、拡張に転送される構造化フィールドで、セマンティクスはデプロイしている拡張に依存します。 |
| spec.image | 拡張を保持するイメージを参照するコンテナーイメージ URI です。 |
| spec.phase |
このフェーズでは、認証、認可、メトリクスの生成などの既存の Istio 機能に関連して、拡張が挿入されるフィルターチェーン内の場所を決定します。有効な値は、PreAuthN、PostAuthN、PreAuthZ、PostAuthZ、PreStats、PostStats です。このフィールドは、拡張の |
| spec.priority |
同じ |
1.19.5.1. ServiceMeshExtension リソースのデプロイ
Red Hat OpenShift Service Mesh 拡張機能は ServiceMeshExtension リソースを使用して有効にできます。この例では、istio-system が Service Mesh コントロールプレーンプロジェクトの名前です。
新しい WebAssembly 拡張機能を作成するときは、WasmPlugin を使用してください。ServiceMeshExtension は、Red Hat OpenShift Service Mesh バージョン 2.2 で非推奨になり、今後のリリースで削除される予定です。
Rust SDK を使用してビルドされる完全なサンプルについては、header-append-filter を参照してください。これは、拡張の config フィールドから取られた名前および値で HTTP 応答に 1 つ以上のヘッダーを追加する単純なフィルターです。以下のスニペットの設定例を参照してください。
手順
以下のリソース例を作成します。
ServiceMeshExtension リソース拡張機能の例
apiVersion: maistra.io/v1 kind: ServiceMeshExtension metadata: name: header-append namespace: istio-system spec: workloadSelector: labels: app: httpbin config: first-header: some-value another-header: another-value image: quay.io/maistra-dev/header-append-filter:2.1 phase: PostAuthZ priority: 100以下のコマンドを使用して
extension.yamlファイルを適用します。$ oc apply -f <extension>.yaml
1.19.6. ServiceMeshExtension リソースから WasmPlugin リソースへの移行
ServiceMeshExtension API は、Red Hat OpenShift Service Mesh バージョン 2.2 で非推奨になり、今後のリリースで削除される予定です。ServiceMeshExtention API を使用している場合は、WebAssembly 拡張を引き続き使用するために WasmPlugin API に移行する必要があります。
API は非常に似ています。移行の手順は、以下の 2 つのステップで設定されます。
- プラグインファイルの名前を変更し、モジュールパッケージを更新する。
-
更新されたコンテナーイメージを参照する
WasmPluginリソースを作成する。
1.19.6.1. API の変更
新しい WasmPlugin API は ServiceMeshExtension に似ていますが、いくつかの違いがあります (特にフィールド名)。
表1.22 ServiceMeshExtensions と WasmPluginの間のフィールドの変更
| ServiceMeshExtension | WasmPlugin |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
以下は、ServiceMeshExtension リソースを WasmPlugin リソースに変換する方法の例になります。
ServiceMeshExtension リソース
apiVersion: maistra.io/v1
kind: ServiceMeshExtension
metadata:
name: header-append
namespace: istio-system
spec:
workloadSelector:
labels:
app: httpbin
config:
first-header: some-value
another-header: another-value
image: quay.io/maistra-dev/header-append-filter:2.2
phase: PostAuthZ
priority: 100
上記の ServiceMeshExtension と等価な新しい WasmPlugin リソース
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: header-append
namespace: istio-system
spec:
selector:
matchLabels:
app: httpbin
url: oci://quay.io/maistra-dev/header-append-filter:2.2
phase: STATS
pluginConfig:
first-header: some-value
another-header: another-value
1.19.6.2. コンテナーイメージの形式の変更
新しい WasmPlugin コンテナーイメージの形式は ServiceMeshExtensions と似ていますが、以下のような違いがあります。
-
ServiceMeshExtensionコンテナー形式には、コンテナーファイルシステムのルートディレクトリーにmanifest.yamlという名前のメタデータファイルが必要でした。WasmPluginコンテナー形式にはmanifest.yamlファイルは必要ありません。 -
任意のファイル名を付けることができた
.wasmファイル (実際のプラグイン) にはplugin.wasmという名前を付け、コンテナーファイルシステムのルートディレクトリーに配置する必要があります。
1.19.6.3. WasmPlugin リソースへの移行
WebAssembly 拡張を ServiceMeshExtension API から WasmPlugin API にアップグレードするには、プラグインファイルの名前を変更します。
前提条件
-
ServiceMeshControlPlaneがバージョン 2.2 以降にアップグレードされる。
どちらのプラグインも要求ごとに呼び出されるため、新しい WasmPlugin リソースを作成する前に、既存の ServiceMeshExtension リソースを削除しなければならない場合があります。2 つのプラグインが同時にアクティブな状態では、望ましくない結果が生じる可能性があります。
手順
コンテナーイメージを更新します。プラグインがすでにコンテナー内の
/plugin.wasmにある場合は、次のステップに進みます。そうでない場合は、以下を行います。-
プラグインファイルの名前が
plugin.wasmであることを確認します。拡張ファイルにはplugin.wasmという名前を付ける必要があります。 - プラグインファイルがルート (/) ディレクトリーにあることを確認します。拡張ファイルをコンテナーファイルシステムのルートに配置する必要があります。
- コンテナーイメージを再ビルドして、これをコンテナーレジストリーにプッシュします。
-
プラグインファイルの名前が
-
ServiceMeshExtensionリソースを削除し、ビルドした新しいコンテナーイメージを参照するWasmPluginリソースを作成します。