Aeraki — Istioサービスメッシュで任意のレイヤー7プロトコルを管理

Aerakiは、IstioがHTTP以外のより多くのレイヤー7プロトコルをサポートできるようにするフレームワークを提供します。

2021年9月28日 | Huabing Zhao - Tencent

Aeraki [エアラキ] はギリシャ語で「そよ風」を意味します。Istioがサービスメッシュ内のマイクロサービスを接続する一方、AerakiはIstioがHTTPとgRPC以外のより多くのレイヤー7プロトコルをサポートできるようにするフレームワークを提供します。このそよ風が、Istioがもう少し先まで進むのを助けられることを願っています。

サービスメッシュにおけるプロトコルサポートの欠如

私たちは現在、サービスメッシュに関していくつかの課題に直面しています。

これらの障害により、ユーザーがマイクロサービスで広く使用されている他のレイヤー7プロトコルのトラフィックを管理することが、不可能ではないにしても非常に困難になっています。たとえば、マイクロサービスアプリケーションでは、以下のプロトコルが存在する可能性があります。

Common Layer-7 Protocols Used in Microservices
マイクロサービスで一般的に使用されるレイヤー7プロトコル

すでにサービスメッシュへの移行に多くの労力を費やしている場合、当然、そのメリットを最大限に活用したいと考えるでしょう。つまり、マイクロサービス内のすべてのプロトコルのトラフィックを管理したいと考えるでしょう。

Aerakiのアプローチ

これらの問題に対処するために、私たちはオープンソースプロジェクトであるAeraki Meshを作成し、Istioサービスメッシュで任意のレイヤー7トラフィックを非侵入的で拡張可能な方法で管理できるようにしました。

Aeraki Architecture
Aerakiアーキテクチャ

この図が示すように、Aerakiフレームワークは以下のコンポーネントで構成されています。

DubboThriftは、すでにMetaProtocolに基づいて実装されています。より多くのプロトコルが開発中です。クローズドソースの独自のプロトコルを使用している場合は、MetaProtocolコーデックを作成するだけで、サービスメッシュでそれを管理できます。

ほとんどのリクエスト/レスポンススタイルのステートレスプロトコルは、MetaProtocolプロキシの上に構築できます。ただし、一部のプロトコルのルーティングポリシーは「特殊」すぎて、MetaProtocolで正規化できません。たとえば、Redisプロキシは、クライアントクエリを特定のRedisサーバーノードにマッピングするためにスロット番号を使用し、スロット番号はリクエスト内のキーによって計算されます。Aerakiは、Envoyプロキシ側に利用可能なEnvoyフィルターがある限り、これらのプロトコルを管理できます。現在、このカテゴリのプロトコルについては、RedisとKafkaがAerakiでサポートされています。

MetaProtocolの詳細

MetaProtocolがどのように機能するかを見てみましょう。MetaProtocolが導入される前は、特定のプロトコルのトラフィックをプロキシしたい場合、そのプロトコルを理解するEnvoyフィルターを作成し、ルーティング、ヘッダーの変更、障害注入、トラフィックミラーリングなど、トラフィックを操作するコードを追加する必要がありました。

ほとんどのリクエスト/レスポンススタイルのプロトコルの場合、トラフィック操作のコードは非常に似ています。したがって、異なるEnvoyフィルターでこれらの機能を重複させることを避けるために、Aerakiフレームワークは、レイヤー7プロトコルプロキシの一般的な機能のほとんどを1つの場所(MetaProtocolプロキシフィルター)に実装しています。

MetaProtocol Proxy
MetaProtocolプロキシ

このアプローチにより、新しいEnvoyフィルターを作成するための障壁が大幅に低くなります。つまり、完全に機能するフィルターを作成する代わりに、コーデックインターフェースを実装するだけで済みます。さらに、コントロールプレーンはすでに整っています。Aerakiは、コントロールプレーンで動作し、MetaProtocolの上に構築されたすべてのプロトコルのMetaProtocol構成と動的ルートを提供します。

Writing an Envoy Filter Before and After MetProtocol
MetaProtocolの前後のEnvoyフィルターの作成

MetaProtocolプロキシには、MetadataとMutationという2つの重要なデータ構造があります。Metadataはルーティングに使用され、Mutationはヘッダー操作に使用されます。

リクエストパスでは、デコーダー(コーデック実装のデコードメソッド)がリクエストから解析されたキーと値のペアでMetadataデータ構造を設定し、MetadataはMetaProtocolルーターに渡されます。ルーターは、RDS経由でAerakiから受信したルート構成とMetadataを照合した後、適切なアップストリームクラスターを選択します。

リクエストを変更する必要がある場合(ヘッダーの追加やヘッダーの値の変更など)、カスタムフィルターは任意のキーと値のペアでMutationデータ構造を設定できます。次に、Mutationデータ構造はエンコーダー(コーデック実装のエンコードメソッド)に渡されます。エンコーダーは、キーと値のペアをワイヤプロトコルに書き込む役割を担います。

The Request Path
リクエストパス

レスポンスパスは、方向が異なるだけでリクエストパスと似ています。

The Response Path
レスポンスパス

MetaProtocolに基づいてアプリケーションプロトコルを実装する必要がある場合は、以下の手順に従うことができます(例としてThriftを使用)。

データプレーン

apiVersion: metaprotocol.aeraki.io/v1alpha1
kind: ApplicationProtocol
metadata:
  name: thrift
  namespace: istio-system
spec:
  protocol: thrift
  codec: aeraki.meta_protocol.codec.thrift

コントロールプレーン

コントロールプレーンを実装する必要はありません。Aerakiはサービスとトラフィックルールを監視し、サイドカープロキシの構成を生成し、EnvoyFilterとMetaProtocol RDSを介して構成をデータプレーンに送信します。

プロトコルの選択

Istioと同様に、プロトコルはサービスポートのプレフィックスによって識別されます。サービスポートの名前は、tcp-metaprotocol-{アプリケーションプロトコル}-xxxというパターンで指定してください。たとえば、Thriftサービスポートの名前はtcp-metaprotocol-thriftにする必要があります。

トラフィック管理

MetaRouter CRDを介してルートを変更できます。例:リクエストの20%をv1に、80%をv2に送信します。

apiVersion: metaprotocol.aeraki.io/v1alpha1
kind: MetaRouter
metadata:
  name: test-metaprotocol-route
spec:
  hosts:
    - thrift-sample-server.thrift.svc.cluster.local
  routes:
    - name: traffic-spilt
      route:
        - destination:
            host: thrift-sample-server.thrift.svc.cluster.local
            subset: v1
          weight: 20
        - destination:
            host: thrift-sample-server.thrift.svc.cluster.local
            subset: v2
          weight: 80

サービスメッシュでHTTP以外のプロトコルを管理する必要がある場合に役立つことを願っています。ご不明な点がございましたら、zhaohuabingまでお問い合わせください。

参考資料

この投稿を共有