TL;DR
What is Envoy — envoy tag-v1.9.0 documentation の和訳記事になります。
そんなに時間をかけずに和訳したので、誤訳などあれば都度指摘お願いします。
Envoy を理解するための一助となれば幸いです。
What is Envoy | Envoy とはなにか
Envoy は L7 proxy で大規模な現代的サービス指向アーキテクチャとしてデザインされています。
このプロジェクトは以下の考えから誕生しました。
ネットワークはアプリケーションに対して透過であるべきです。
ネットワークとアプリケーションプラットフォームで問題が発生した場合、問題の原因を特定するのは簡単なはずです。
実際には、前述の宣言を達成するのは極めて困難です。Envoy は次の高水準な機能を提供することによって、そうすることを試みます。
Out of process architecture
Envoy は自己完結型のプロセスです、それは全てのアプリケーションサーバと並んで実行されます。 Envoy は全て、それぞれのアプリケーションが localhost からのメッセージの送受信による透過的な通信メッシュを構築し、ネットワークトポロジを認識しません。プロセス設計の外部は、従来のライブラリによるサービス間通信へのアプローチに比べ、2つの利点があります。
- Envoy はどのアプリケーション言語でも動作します。1つの Envoy のデプロイメントは Java, C++, Go, PHP, Python, etc 間のメッシュを構築することができます。これにより、サービス指向アーキテクチャが複数のアプリケーションフレームワークや言語で使われるようにますますなるでしょう。
- 大規模なサービス指向アーキテクチャを知っている人なら誰でも知っているように、ライブラリのアップデートをデプロイするのは非常に面倒なことです。Envoy はインフラストラクチャ全体にわたって透過的に迅速にデプロイやアップデートが可能です。
Modern C++11 code base
Envoy は C++11 で書かれています。ネイティブコードは私達は Envoy のようなアーキテクチャコンポーネントは、できる限り邪魔にならないようにする必要があるため選択されました。現代のアプリケーション開発者は共有クラウド環境での展開と、PHP, Python, Ruby, Scala などの非常に生産的であるが特にパフォーマンスのよくない言語の仕様のため 、考えるのが難しいテールレイテンシに対処しています。ネイティブコードはすでに混乱した状況にさらなる混乱を加えるようなことはなく、一般的に優れたレイテンシ特性を提供します。C で書かれた他のネイティブコードプロキシソリューションとは異なり、 C+11 は優れた開発者の生産性とパフォーマンスの両方を提供します。
L3/L4 filter architecture
本質的には、 Envoy は L3/L4 ネットワークプロキシです。プラガブルフィルタチェインメカニズムによりさまざまな TCP プロキシタスクを実行するためのフィルタを作成でき、メインサーバに挿入することができます。フィルタはすでに生の TCP プロキシ、 HTTP プロキシ、 TLS クライアント証明書認証のようなさまざまなタスクをサポートするように書かれています。
HTTP L7 filter architecture
HTTP は現代のアプリケーションアーキテクチャの重要なコンポーネントであり、 Envoy は追加の HTTP L7 フィルタレイヤをサポートします。HTTP フィルタはバッファリング、レートリミット、ルーティング/フォワーディング、 Amazon の DynamoDB のスニファリングのような様々なタスクを実行する HTTP 接続管理サブシステムに接続することができます。
First class HTTP/2
HTTP モードで動作している場合、 Envoy は HTTP/1.1 と HTTP/2 の両方をサポートします。 Envoy は双方向の透過的な HTTP/1.1 から HTTP/2 プロキシとして動作できます。これは HTTP/1.1 及び HTTP/2 のクライアントとターゲットサーバの任意の組み合わせをブリッジできるということです。推奨されるサービス間構成は 全ての Envoy の間に HTTP/2 を使用して、リクエストとレスポンスを多重化された持続的接続のメッシュ作成することです。 Envoy はプロトコルが段階的に廃止されているため SPDY のサポートはしません。
HTTP L7 routing
HTTP モードで動作している場合、 Envoy はルーティングやパスに基づくリダイレクトリクエスト、認証、コンテンツタイプ、ランタイムバリューなどが可能な、ルーティングサブシステムをサポートしています。この機能は フロント/エッジプロキシとして Envoy を利用する場合に最も便利ですが、Service to Service mesh を構築するときにも利用されます。
gRPC support
gRPC は基礎となる多重転送として HTTP/2 を利用した Google による RPC フレームワークです。 Envoy は gRPC リクエストとレスポンスのためのルーティング及び負荷分散の基礎として使用するために必要な全ての HTTP/2 の機能をサポートしています。2つのシステムは非常に補完的です。
MongoDB L7 support
MongoDB は現代の Web アプリケーションで使用される人気のあるデータベースです。 Envoy は L7 のスニファリング、統計制作、そして MongoDB の接続を記録します。
DynamoDB L7 support
DynamoDB は Amazon が提供する key/value の NOSQL データベースです。 Envoy は L7 のスニファリングと DynamoDB の接続のための統計制作をサポートしています。
Service discovery and dynamic configuration
Envoy はオプションで集中管理のための動的構成 API のレイヤー化されたセットを消費します。レイヤーは Envoy に以下の動的な変更を提供します。
- バックエンドクラスタ内のホスト
- バックエンドクラスター自体
- HTTP ルーティング
- リスニングソケット
- 暗号材料
より簡単なデプロイのために、バックエンドホストディスカバリは DNS 解決を通して(または完全にスキップされても)可能で、さらなるレイヤーは静的な設定ファイルによって置き換えられます。
Health checking
Envoy のメッシュを構築するための推奨方法は、サービスの発見を最終的に一貫したプロセスとして扱うことです。 Envoyにはアップストリームサービスクラスタの アクティブヘルスチェックをオプションで実行できるヘルスチェックサブシステムが含まれています。 Envoy はその後、サービス発見の集合と健全な負荷分散ターゲットを決定するヘルスチェック情報を利用します。 Envoy は異常値検出サブシステムによる受動的ヘルスチェックもサポートしています。
Advanced load balancing
分散システム内の異なるコンポーネント間の負荷分散は複雑な問題です。なぜなら Envoy はライブラリではなく自己完結型プロキシであり、高度な負荷分散技術を1箇所に実装し、それらをあらゆるアプリケーションからアクセスできるようにするためです。現在、 Envoy は自動リトライ、サーキットブレーカ、外部レート制限サービスによるしたグローバルレートリミット、リクエストシャドーウィング、そして外れ値の検出をサポートしています。今後のサポートはリクエストレースのための計画があります。
Front/edge proxy support
Envoy は主に Service to Service のコミュニケーションシステムとして設計されていますが、エッジで同じソフトウェアを利用することには利点があります(可観測性、管理、同一のサービスディスカバリ、そして負荷分散アルゴリズムなど)。 Envoy は最新の Web アプリケーションのほとんどのユースケースでエッジプロキシとして使用するのに十分な機能が含まれています。これは TLS 終端、 HTTP/1.1、 そして HTTP/2 のサポート、および HTTP L7 ルーティングが含まれます。
Best in class observability
前述のように、 Envoy の主な目的はネットワークを透過させることです。しかし、問題はネットワークレベルとアプリケーションレベルの両方で発生します。 Envoy は全てのサブシステムのための堅牢な統計サポートが含まれます。 statsd
(と互換性プロバイダ)は現在サポートされている統計シンクですが、別の物に置き換えるのは難しくありません。統計は管理ポートからも見ることができます。 Envoy はサードパーティプロバイダを介した分散トレースもサポートしています。
Design goals
コード自体の設計目標についての簡単なメモ:
Envoy は決して遅くはないが(私達は特定の高速パスの最適化にかなりの時間を費やしました)、コードはモジュール化されていてテストが簡単なのに対して、最大限の絶対性能を目指して書かれています。私達の見解では、典型的なデプロイは言語やランタイムと並んで何倍も遅くなり、何倍ものメモリ使用量を伴うため、これはより効率的な時間の活用になります。