EnvoyとApache APISIX:Envoy Filterを実装するもう一つの方法

API7.ai

December 16, 2020

Technology

Envoyフィルターの実装方法

Envoyフィルター

Envoyは、大規模な現代的なサービス指向アーキテクチャ向けに設計されたL7プロキシおよび通信バスです。プラグ可能なフィルターチェーンメカニズムにより、さまざまなタスクを実行するフィルターを記述し、メインサーバーに挿入することができます。

Envoyフィルター

拡張方法

既存のフィルターがユーザーのカスタム要件を満たさない場合、Envoyを拡張する必要があります。既存のフィルターチェーンに基づいて新しいフィルターをカスタマイズし、カスタマイズ要件を実現します。

開発者は、以下の3つの方法でEnvoyを拡張できます:

導入の難易度安定性開発効率デプロイとコンパイル
C++高い安定低いコンパイルに時間がかかる
Lua低い安定高いコンパイル不要、直接デプロイ可能
WASM中程度不安定言語依存言語に依存するコンパイル時間
  1. C++を使用して拡張

この方法では、Envoyの基盤上で直接C++コードを記述し、機能を強化します。カスタムフィルターを実装した後、新しいバイナリファイルを再コンパイルしてアップグレードを完了します。この方法には2つの問題があります:

  • C++言語に制限され、導入が難しく、開発者が少ない。
  • デプロイ、運用、アップグレードの複雑さが増す。Envoyはますます重くなり、変更のたびにバイナリファイルを再コンパイルする必要があり、反復と管理に適していない。
  1. Luaを使用して拡張

Luaはアプリケーションに組み込まれることを前提として設計されており、アプリケーションに柔軟な拡張とカスタマイズ機能を提供し、広く使用されています。

Luaフィルターは、リクエストとレスポンスのプロセスでLuaスクリプトを実行することを可能にします。現在サポートされている主な機能は次のとおりです:リクエストフローまたはレスポンスフローでのヘッダー、ボディ、トレーラーの検査;ヘッダーとトレーラーの変更;完全なリクエスト/レスポンスボディのブロックとバッファリングによる検査;上流ホストへのアウトバウンド非同期HTTP呼び出しの実行;直接応答の実行とさらなるフィルター反復のスキップなど。

現在、多くの人が設定に直接Luaコードを配布していますが、これはコードの組織と管理に適しておらず、他の人と共有してエコシステムを形成するのが難しいです。

  1. WASMを使用して拡張

開発者は、自分のプログラミング言語でフィルターを記述し、ツールを使用してWASM形式にコンパイルし、Envoyに組み込んで実行することができます。

現在サポートされている言語は少なく、これらの言語を使用して拡張することはまだそれほど簡単ではありません。一方、多くの人はWASMに対してまだ懐疑的で、直接使用しないかもしれません。

Apache APISIXのソリューション

上記の分析に基づいて、LuaがEnvoyを拡張するのに非常に適しており、学習が容易で、開発効率が非常に高いことがわかります。Envoyに組み込まれているため、追加のネットワークオーバーヘッドがなく、パフォーマンスが良いです。

Apache APISIXコミュニティは、Luaに基づいて独自のソリューションを提案しています。それは、Apache APISIXのすべてのプラグインと将来開発されるプラグインがEnvoy上で実行されるように、強力で柔軟な基本ライブラリを提供することです。開発者はこの基本ライブラリに基づいて独自のカスタマイズプラグインを開発することもできます。

Apache APISIXは、NginxライブラリとLuaに基づいた動的でリアルタイムの高性能APIゲートウェイです。Apache APISIXは、ロードバランシング、動的上流、カナリアリリース、サーキットブレーカー、認証、可観測性などの豊富なトラフィック管理機能を提供します。

具体的なコードと実行方法については、リポジトリを確認してください:https://github.com/api7/envoy-apisix

Envoyの関連設定は以下のとおりです:

フィルターを定義する:

http_filters:
  - name: entry.lua
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
      source_codes:
        entry.lua:
          filename: /apisix/entry.lua

ルートに対してフィルターを有効にし、メタデータで設定する:

routes:
  - match:
      prefix: "/foo"
    route:
      cluster: web_service
    typed_per_filter_config:
      envoy.filters.http.lua:
        "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
        name: entry.lua
    metadata:
      filter_metadata:
        envoy.filters.http.lua:
          plugins:
            - name: uri-blocker
              conf:
                rejected_code: 403
                block_rules:
                  - root.exe
                  - root.m+

動作原理

Envoyに大きな変更を加える必要はなく、公共のニーズに適した最適化のみを行います。

プラグインレイヤーのプラットフォームの違いを遮蔽します。使用する必要があるすべてのインターフェースは、apisix.coreと呼ばれる基盤フレームワークで抽象化されているため、すべてのプラグインがEnvoyとApache APISIXで同時に実行できます。

アーキテクチャ図

前の例を使用して、プラグインがどのように実行されるかを示します:

プラグインワークフロー

最初のステップ、設定を読み取る

メタデータを通じて、各ルートで実行する必要があるプラグインと各プラグインの設定を決定します。例では、プレフィックスが/fooのルートに対してプラグインuri-blockerを設定し、プラグインのブロックルールとブロックが必要な場合の応答ステータスを設定しました。

2番目のステップ、リクエストを解析する

クライアントリクエストデータをctxにカプセル化し、プロセス全体で直接使用できるようにします。

3番目のステップ、プラグインを実行する

設定されたルールと取得したuriを照合して、このリクエストをブロックする必要があるかどうかを判断します。ブロックが必要な場合は、respondを呼び出して直接応答し、そうでない場合は通過させます。

将来の展望

ますます多くのAPISIXプラグインがEnvoy上で実行可能になり、最終的にはすべてのAPISIXプラグイン(将来開発されるものも含む)がEnvoy上で実行可能になります。

同時に、Luaフィルターの方向でEnvoyコミュニティと協力し、Luaフィルターを最適化および改善し、Envoyの拡張能力を強化し、Envoyの拡張の難易度を低減することを望んでいます。

Tags: