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 エクステンションを作成するときは、WasmPlugin API を使用してください。ServiceMeshExtension API は Red Hat OpenShift Service Mesh バージョン 2.2 で非推奨化され、Red Hat OpenShift Service Mesh バージョン 2.3 で廃止されました。

Red Hat OpenShift Service Mesh 拡張機能の作成には 2 つの部分があります。

  1. proxy-wasm API を公開する SDK を使用して拡張機能を記述し、それを WebAssembly モジュールにコンパイルする必要があります。
  2. 次に、モジュールをコンテナーにパッケージ化する必要があります。

サポートされる言語

WebAssembly バイトコードにコンパイルする言語を使用して Red Hat OpenShift Service Mesh 拡張を作成できますが、以下の言語には proxy-wasm API を公開する既存の SDK があるため、これを直接使用できます。

表1.13 サポートされる言語

言語保守管理者リポジトリー

AssemblyScript

solo.io

solo-io/proxy-runtime

C++

proxy-wasm チーム (Istio コミュニティー)

proxy-wasm/proxy-wasm-cpp-sdk

Go

tetrate.io

tetratelabs/proxy-wasm-go-sdk

Rust

proxy-wasm チーム (Istio コミュニティー)

proxy-wasm/proxy-wasm-rust-sdk

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) イメージが使用されています。フィールド urlimagePullPolicy、および 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.14 WasmPlugin フィールドリファレンス

フィールドタイプ説明必須

spec.selector

WorkloadSelector

このプラグイン設定を適用する必要がある Pod/VM の特定のセットを選択するために使用される基準。省略した場合に、この設定は同じ namespace 内のすべてのワークロードインスタンスに適用されます。WasmPlugin フィールドが configroot namespace に存在する場合は、任意の namespace の該当するすべてのワークロードに適用されます。

いいえ

spec.url

string

Wasm モジュールまたは OCI コンテナーの URL。スキームが存在しない場合は、デフォルトで oci:// になり、OCI イメージを参照します。その他の有効なスキームとして、プロキシーコンテナー内にローカルに存在する.wasm モジュールファイルを参照するための file:// と、リモートでホストされる.wasm モジュールファイルを参照するため の http s:// があります。

いいえ

spec.sha256

string

Wasm モジュールまたは OCI コンテナーの検証に使用される SHA256 チェックサム。url フィールドがすでに SHA256 を参照している場合 (@sha256: 表記を使用) には、このフィールドの値と一致する必要があります。OCI イメージがタグによって参照され、このフィールドが設定されている場合は、プル後にそのチェックサムがこのフィールドの内容に対して検証されます。

いいえ

spec.imagePullPolicy

PullPolicy

OCI イメージをフェッチするときに適用されるプル動作。イメージが SHA ではなくタグで参照されている場合にのみ参照します。デフォルト値は IfNotPresent です。ただし、URL フィールドで OCI イメージが参照され、latest タグが使用されている場合は、Always の値がデフォルトで、K8s の動作を反映しています。url フィールドが file:// または http s:// を使用して Wasm モジュールを直接参照している場合は、設定が無視されます。

いいえ

spec.imagePullSecret

string

OCI イメージのプルに使用するクレデンシャル。イメージをプルするときにレジストリーに対して認証するためのプルシークレットなど、WasmPlugin オブジェクトと同じ namespace 内のシークレットの名前。

いいえ

spec.phase

PluginPhase

フィルターチェーンのどこにこの WasmPlugin オブジェクトを挿入するかを決定します。

いいえ

spec.priority

int64

phase の値が同じ WasmPlugins オブジェクトの順序を決定します。複数の WasmPlugins オブジェクトが同じフェーズで同じワークロードに適用される場合、それらは優先度と降順をもとに適用されます。優先度 フィールドが設定されていない場合や値が同じ WasmPlugins オブジェクトが 2 つある場合、順序は WasmPlugins オブジェクトの名前と namespace をもとに決定されます。デフォルト値は 0 です。

いいえ

spec.pluginName

string

Envoy 設定で使用されるプラグイン名。一部の Wasm モジュールでは、実行する Wasm プラグインを選択するためにこの値が必要になる場合があります。

いいえ

spec.pluginConfig

Struct

プラグインに渡される設定。

いいえ

spec.pluginConfig.verificationKey

string

署名された OCI イメージまたは Wasm モジュールの署名を検証するために使用される公開鍵。PEM 形式で指定する必要があります。

いいえ

WorkloadSelector オブジェクトは、フィルターをプロキシーに適用できるかどうかを判別するために使用される条件を指定します。一致の条件には、プロキシーに関連付けられたメタデータ、Pod/VM に添付されたラベルなどのワークロードインスタンス情報、またはプロキシーが最初のハンドシェイク中に Istio に提供するその他の情報が含まれます。複数の条件が指定されている場合、ワークロードインスタンスを選択するには、すべての条件が一致する必要があります。現在、ラベルベースの選択メカニズムのみがサポートされています。

表1.15 WorkloadSelector

フィールドタイプ説明必須

matchLabels

map<string, string>

ポリシーを適用する必要がある Pod/VM の特定のセットを示す 1 つ以上のラベル。ラベル検索の範囲は、リソースが存在する設定 namespace に限定されます。

はい

PullPolicy オブジェクトは、OCI イメージをフェッチするときに適用されるプル動作を指定します。

表1.16 PullPolicy

説明

<empty>

デフォルト値は IfNotPresent です。ただし、OCI イメージのタグが latest の場合、デフォルト値は Always です。

IfNotPresent

イメージの既存のバージョンが以前にプルされている場合は、それが使用されます。イメージのバージョンがローカルに存在しない場合は、最新バージョンをプルします。

Always

このプラグインを適用するときは、常に最新バージョンのイメージをプルします。

Struct は、動的に型付けされた値にマップされるフィールドで設定される構造化データ値を表します。一部の言語では、Struct はネイティブ表現でサポートされている場合があります。たとえば、JavaScript のようなスクリプト言語では、構造体はオブジェクトとして表されます。

表1.17 Struct

フィールドタイプ説明

fields

map<string, Value>

動的に型付けされた値のマップ。

PluginPhase は、プラグインが注入されるフィルターチェーンのフェーズを指定します。

表1.18 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 フィルターを作成します。

手順

  1. 以下のリソース例を作成します。

    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

  2. 次のコマンドを使用して plugin.yaml ファイルを適用します。

    $ oc apply -f plugin.yaml

1.19.4. ServiceMeshExtension コンテナー形式

コンテナーイメージを有効な拡張イメージにするために、WebAssembly モジュールのバイトコードを含む .wasm ファイルとコンテナーファイルシステムのルートに manifest.yaml ファイルが必要です。

注記

新しい WebAssembly エクステンションを作成するときは、WasmPlugin API を使用してください。ServiceMeshExtension API は Red Hat OpenShift Service Mesh バージョン 2.2 で非推奨化され、Red Hat OpenShift Service Mesh バージョン 2.3 で廃止されました。

manifest.yaml

schemaVersion: 1

name: <your-extension>
description: <description>
version: 1.0.0
phase: PreAuthZ
priority: 100
module: extension.wasm

表1.19 manifest.yml フィールドの参照情報

フィールド説明必須

schemaVersion

マニフェストスキーマのバージョン管理に使用されます。現時点で使用できる値は 1 のみです。

これは必須フィールドです。

name

拡張の名前です。

このフィールドは単なるメタデータであり、現時点では使用されていません。

description

拡張の説明。

このフィールドは単なるメタデータであり、現時点では使用されていません。

version

拡張のバージョンです。

このフィールドは単なるメタデータであり、現時点では使用されていません。

phase

拡張のデフォルトの実行フェーズです。

これは必須フィールドです。

priority

拡張のデフォルトの優先度です。

これは必須フィールドです。

module

コンテナーファイルシステムのルートから WebAssembly モジュールへの相対パスです。

これは必須フィールドです。

1.19.5. ServiceMeshExtension リファレンス

ServiceMeshExtension API には、WebAssembly フィルターを介して Istio プロキシーによって提供される機能を拡張するメカニズムがあります。WebAssembly 拡張機能の作成には 2 つの部分があります。

  1. proxy-wasm API を公開する SDK を使用して拡張機能を記述し、それを WebAssembly モジュールにコンパイルします。
  2. コンテナーにパッケージ化します。
注記

新しい WebAssembly エクステンションを作成するときは、WasmPlugin API を使用してください。Red Hat OpenShift Service Mesh バージョン 2.2 で非推奨化された ServiceMeshExtension API は、Red Hat OpenShift Service Mesh バージョン 2.3 で廃止されました。

表1.20 ServiceMeshExtension フィールドの参照情報

フィールド説明

metadata.namespace

ServiceMeshExtension ソースの metadata.namespace フィールドには特殊なセマンティクスが含まれます。これが Control Plane Namespace と等しい場合、拡張はその workloadSelector の値に一致する Service Mesh のすべてのワークロードに適用されます。これは、その他の Mesh namespace にデプロイされる場合に、同じ namespace のワークロードにのみ適用されます。

spec.workloadSelector

spec.workloadSelector フィールドには、Istio Gateway リソースspec.selector フィールドと同じセマンティクスが含まれます。これは Pod ラベルに基づいてワークロードに一致します。workloadSelector の値が指定されていない場合、拡張は namespace のすべてのワークロードに適用されます。

spec.config

これは、拡張に転送される構造化フィールドで、セマンティクスはデプロイしている拡張に依存します。

spec.image

拡張を保持するイメージを参照するコンテナーイメージ URI です。

spec.phase

このフェーズでは、認証、認可、メトリクスの生成などの既存の Istio 機能に関連して、拡張が挿入されるフィルターチェーン内の場所を決定します。有効な値は、PreAuthN、PostAuthN、PreAuthZ、PostAuthZ、PreStats、PostStats です。このフィールドは、拡張の manifest.yaml ファイルで設定される値にデフォルト設定されますが、ユーザーが上書きできます。

spec.priority

同じ spec.phase の値を持つ複数の拡張機能が同じワークロードインスタンスに適用される場合、spec.priority は実行の順序を決定します。優先度が高い拡張機能が最初に実行されます。これにより、相互に依存する拡張が使用可能になります。このフィールドは、拡張の manifest.yaml ファイルで設定される値にデフォルト設定されますが、ユーザーが上書きできます。

1.19.5.1. ServiceMeshExtension リソースのデプロイ

Red Hat OpenShift Service Mesh 拡張機能は ServiceMeshExtension リソースを使用して有効にできます。この例では、istio-system が Service Mesh コントロールプレーンプロジェクトの名前となります。

注記

新しい WebAssembly エクステンションを作成するときは、WasmPlugin API を使用してください。ServiceMeshExtension API は Red Hat OpenShift Service Mesh バージョン 2.2 で非推奨化され、Red Hat OpenShift Service Mesh バージョン 2.3 で廃止されました。

Rust SDK を使用してビルドされる完全なサンプルは、header-append-filter を参照してください。これは、拡張の config フィールドから取られた名前および値で HTTP 応答に 1 つ以上のヘッダーを追加する単純なフィルターです。以下のスニペットの設定例を参照してください。

手順

  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

  2. 以下のコマンドを使用して extension.yaml ファイルを適用します。

    $ oc apply -f <extension>.yaml

1.19.6. ServiceMeshExtension リソースから WasmPlugin リソースへの移行

Red Hat OpenShift Service Mesh バージョン 2.2 で非推奨化された ServiceMeshExtension API は、Red Hat OpenShift Service Mesh バージョン 2.3 で廃止されました。ServiceMeshExtension API を使用している場合、WebAssembly エクステンションを引き続き使用するには WasmPlugin API に移行する必要があります。

API は非常に似ています。移行の手順は、以下の 2 つのステップで設定されます。

  1. プラグインファイルの名前を変更し、モジュールパッケージを更新する。
  2. 更新されたコンテナーイメージを参照する WasmPlugin リソースを作成する。

1.19.6.1. API の変更

新しい WasmPlugin API は ServiceMeshExtension に似ていますが、いくつかの違いがあります (特にフィールド名)。

表1.21 ServiceMeshExtensionsWasmPluginの間のフィールドの変更

ServiceMeshExtensionWasmPlugin

spec.config

spec.pluginConfig

spec.workloadSelector

spec.selector

spec.image

spec.url

spec.phase 有効な値: PreAuthN、PostAuthN、PreAuthZ、PostAuthZ、PreStats、PostStats

spec.phase 有効な値: <empty>、AUTHN、AUTHZ、STATS

以下は、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 以降にアップグレードされる。

手順

  1. コンテナーイメージを更新します。プラグインがすでにコンテナー内の /plugin.wasm にある場合は、次のステップに進みます。そうでない場合は、以下を行います。

    1. プラグインファイルの名前が plugin.wasm であることを確認します。拡張ファイルには plugin.wasm という名前を付ける必要があります。
    2. プラグインファイルがルート (/) ディレクトリーにあることを確認します。拡張ファイルをコンテナーファイルシステムのルートに配置する必要があります。
    3. コンテナーイメージを再ビルドして、これをコンテナーレジストリーにプッシュします。
  2. ServiceMeshExtension リソースを削除し、ビルドした新しいコンテナーイメージを参照する WasmPlugin リソースを作成します。