19 ポイント 投稿者 xguru 2020-08-10 | 3件のコメント | WhatsAppで共有
<p>数千万の同時接続、毎秒数百万リクエスト、テラ単位の帯域を使用しているDropboxが、Nginxと比べたEnvoyの利点をうまく説明した記事<br /> <br /> 従来 : nginx(オープンソース版) + python2 + Jinja2 + YAML <br /> → 1つだけ変わっても全体の再デプロイが必要<br /> → 動的な部分はLuaで開発<br /> → 複雑なロジックはGoベースのプロキシであるBandaidで処理<br /> <br /> この10年近くうまく動いていたが、現在の環境にはあまり合っていない<br /> → 内部および外部(非公開)APIは徐々にRESTからgRPCへ移行中であり、プロキシのトランスコーディング機能が必要<br /> → Protocol Buffersが内部サービス定義の標準に <br /> → すべてのソフトウェアは言語に関係なくBazelでビルドおよびテスト<br /> → 主要インフラプロジェクトのオープンソースコミュニティに社員がかなり積極的に参加中<br /> <br /> Nginxは運用面でも維持コストが高い<br /> → Config生成ロジックが柔軟すぎて、YAML、Jinja2、Pythonに分散している<br /> → 監視がLua / Log parsing / システムベース監視の混在<br /> → サードパーティモジュールへの依存が高まるにつれて、安定性/性能に影響し、頻繁なアップグレードによるコストが発生 <br /> → nginx自体のデプロイおよびプロセス管理は他のサービスと大きく異なる。syslog、logrotateなど基本システムとはかなり異なるものに依存<br /> <br /> そこで、10年ぶりに初めてNginxを置き換えるものを探すことにした<br /> <br /> * なぜBandaid(Dropboxが独自開発したGoベースのプロキシ)ではないのか? <br /> → GoはC/C++よりリソースを多く消費する。 <br /> → GoのTLSスタックはFIPS対応ではない(米国連邦情報処理標準)<br /> → 内部ツールのため外部コミュニティの支援を受けられない <br /> <br /> 現在 : Envoyベースのトラフィックインフラへ移行中 <br /> <br /> ----- NginxよりEnvoyが優れていた点 ------<br /> <br /> * 性能 *<br /> <br /> Nginxのアーキテクチャはイベントドリブン / マルチプロセス。SO_REUSEPORT &amp; EPOLLEXCLUSIVEをサポート<br /> イベントループベースだが完全なノンブロッキングではない。ファイルオープン/ロギング時にはイベントループが停止する可能性がある。(aio、aio_writeおよびThreadpoolを有効化しても)<br /> これによってテールレイテンシが発生し、数秒単位の遅延が生じることもある<br /> <br /> Envoyも同様にイベントドリブンアーキテクチャだが、プロセスではなくスレッドベース <br /> SO_REUSEPORTをサポート(BPFフィルタ対応)、libeventによるイベントループをサポート <br /> イベントループでブロッキングI/Oはなく、イベントロギングもノンブロッキング方式で実装。<br /> <br /> 理論的には似たような性能特性を示しそうで、実際にほとんどのワークロードテストでも似ていた。<br /> ただし、Nginxはロングテールでレイテンシがより大きかった。I/Oが多いときにイベントループが停止したため。<br /> <br /> 統計収集がなければNginxはEnvoyと近い性能を示すが、内部で使用中のLua統計収集ツールがhigh-RPSテストでNginxを3倍遅くしていた。(これはmutexで同期されるlua_shared_dictのため)。Dropboxの統計収集方式にも問題はあったが、これを効率的に再開発するのは断念した。(Nginx内部にインストルメンテーションすると将来のアップグレードが難しくなると見込んだため)<br /> <br /> とにかく、このような問題がEnvoyにはなかったため、移行後は従来Nginxが使っていたサーバーの最大60%を削減できた。<br /> <br /> * Observability *<br /> <br /> 無料版Nginxはstub statusモジュールで7種類のstatしか提供しない <br /> これでは当然不足していたため、log_by_luaハンドラを付けてさらに多くのstatを提供していた。<br /> また、error.logパーサーを通じてエラー情報を出力し、nginx内部状態値を出力するための別個のexporterも存在。<br /> <br /> 基本的なEnvoyセットアップはPrometheus形式で数千種類の異なるメトリクスを提供 <br /> プロキシトラフィック情報からサーバーの内部状態情報、<br /> クラスタ別/アップストリーム別/仮想ホスト別の統計値や、リスナー別のTCP/HTTP/TLSダウンストリーム統計情報など<br /> <br /> このような多様な統計に加えて、EnvoyはTracing Providerをプラグイン可能。<br /> トラフィックチームだけでなく、アプリケーション開発者にも有用。<br /> <br /> 最後に、EnvoyはgRPCを通じてアクセスログをストリーミング可能。<br /> これにより、トラフィックチームがsyslog-to-hiveブリッジを支える負担が軽減される。<br /> カスタムTCP/UDPリスナーを付けるより、一般的なgRPCサービスを実行するほうがはるかに簡単で安全。<br /> <br /> * Integration *<br /> <br /> Nginxの統合は非常にUnix的。Configurationが非常に静的。<br /> configファイルやTLS証明書、allowlist/blocklistなどをファイルに依存。<br /> 単純で後方互換性があるため、いくつかのシェルスクリプトで自動化は可能だが、<br /> システムが大きくなるにつれて、テスト可能性と標準化がますます重要になる。<br /> <br /> Envoyはこのような統合に対して独自の方法を持っている。<br /> xDSと呼ばれるAPIを提供し、protobufとgRPCの利用を推奨。<br /> EnvoyはこのxDSにクエリを送って動的リソースを見つける。<br /> <br /> - このxDSは今やEnvoyを超えて、Universal Data Place API(UDPA)という名前でL4/L7ロードバランサーのde facto標準になろうと進化しており、私たちの経験ではこれがうまく進んでいる。EnvoyだけでなくKatran eBPF/XDP L4ロードバランサーでもUDPAを使おうとしている。<br /> <br /> Dropboxは内部でgRPCを通じてサービスが連携しているため、はるかに都合がよい。<br /> <br /> * Configuration *<br /> <br /> Nginxは人間が読みやすい設定ファイルという大きな利点を持っている。 <br /> しかしこの利点は、設定が複雑化し自動生成されるにつれて失われていった。<br /> DropboxではPython2、Jinja2、YAMLなどを通じて生成されていたため、データモデルも絡み合って複雑だった。<br /> <br /> Envoyは設定に対する統一されたデータモデルを持っている。すべての設定値はProtocol Bufferで定義される。データモデリングの問題が解消され、設定値に型情報が追加される。<br /> Dropbox内部ではprotobufが多く使われているため、統合も容易だった <br /> <br /> * Extensibility * <br /> <br /> Nginxの拡張にはCモジュールの作成が必要。安全なモジュールを書くにはシニア開発者が必要。より軽量なモジュール開発のためにPerl / JSインターフェースも提供しているが非常に限定的。そのため最も一般的に使われる方法はlua-nginx-moduleを通すこと。 <br /> <br /> Envoyの主な拡張メカニズムはC++プラグインだが、ドキュメントはnginxほど充実していないものの非常に単純。これは整理されコメントの行き届いたインターフェース、C++14言語と標準ライブラリのおかげ <br /> <br /> Envoyが他のWebサーバーと大きく異なる点は、WebAssembly(WASM)をサポートしていること。<br /> これによりRustのようなさまざまな言語で拡張開発できる。 <br /> まだDropboxではWASMを使っていないが、いつかproxy-wasm向けGo SDKがサポートされれば変わるかもしれない<br /> <br /> * Building and Testing *<br /> <br /> Nginxは基本的にカスタムシェルベースの設定とmakeベースのビルドを使用。単純で優れているが、これをBazelでビルドされるモノレポに統合するにはかなりの労力がかかる <br /> NginxにはPerlベースのintegration testはあるが、unit testはない。<br /> <br /> EnvoyはすでにビルドシステムがBazelベースで、簡単に私たちのモノレポへ統合できた。<br /> gtest/gmockベースのunit testとintegration test frameworkをサポート<br /> <br /> * Security *<br /> <br /> Nginxのコードは非常に小さく、外部依存も少ないため、セキュリティ上の脆弱性は多くない。<br /> <br /> Envoyはコード量が多いため、そのぶん攻撃面も多く見える。そのためEnvoyは現代的なセキュリティプラクティスに大きく依存している。AddressSanitizer、ThreadSanitizer、MemorySanitizerなどを使用。 <br /> <br /> * Features * <br /> <br /> この部分は主観的な意見が多いので参考までに<br /> <br /> Nginxは当初、ごく少ないリソースで静的ファイルを配信するWebサーバーとして始まった。 <br /> つまりstatic serving、caching、range cachingが主機能<br /> プロキシの観点では、Nginxには現代のインフラで求められる機能が多く不足している。 <br /> バックエンドとのHTTP/2接続もできず、マルチプレックスされるgRPCプロキシにも対応せず、gRPCトランスコーディングも不可など。<br /> オープンコア型のライセンスモデルのため、いくつかの主要機能は「コミュニティ版」には含まれていない<br /> <br /> Envoyはそもそもingress/egress proxyとして始まり、gRPC負荷の高い環境で多く使われている。<br /> Webサービス機能は非常に初歩的なレベル。ファイル配信もできず、キャッシュもまだ開発中で、brotliも未対応など <br /> このような環境向けには、Envoyをアップストリームクラスタとして使うNginxセットアップも使用中 <br /> EnvoyがHTTPキャッシュに対応すれば、このような静的配信環境も移行できると見込んでいる <br /> <br /> EnvoyはgRPC関連機能を多くサポート<br /> - gRPC proxying<br /> - HTTP/2 to backends<br /> - gRPC → HTTP bridge (+ reverse.) <br /> - gRPC-WEB <br /> - gRPC JSON transcoder<br /> <br /> またEnvoyはoutbound proxyとしても利用可能 <br /> - Egress Proxy<br /> - Courier gRPCライブラリによるサードパーティソフトウェアのサービスディスカバリ <br /> <br /> * Community *<br /> <br /> Nginxの開発は中央集権的で、その大半が見えない。 <br /> Envoyの開発はオープンで分散的。GitHubのissue/PRで進み、メーリングリストやSlackなどでも活発 </p><p>----- Dropboxの現在のMigration状況 -----<br /> <br /> NginxとEnvoyを半年前から並行運用しながら、DNSを通じて段階的にトラフィックを移行中 <br /> 何の問題もなく移行できたわけではなく、小さな問題はあったが深刻な障害はなかった。<br /> "unusual" または "non-RFC" 的な挙動によって経験した問題に対する解決策も整理している(本文に詳細があるので参照)<br /> <br /> ** 今後やること **<br /> <br /> - HTTP/3 : Envoyも実験的サポートを開始。UDP高速化のためにLinuxカーネルをアップグレードしたら試してみる予定<br /> - 内部xDSベースのロードバランサーとOutlier Detection<br /> - WASMベースのEnvoy拡張 <br /> - Bandaid(Goベースのプロキシ)をEnvoyに置き換え <br /> - Envoy MobileでモバイルアプリにもEnvoyを適用</p>

3件のコメント

 
baeba 2020-08-13
<p>良い内容を簡潔に <br /> まとめてくださって<br /> ありがとうございます。</p>
 
before30 2020-08-11
<p>ありがとうございます。:)</p>
 
loslch 2020-08-11
<p>詳細な整理と親切なご意見まで添えてくださり、理解にとても役立ちました。ありがとうございます :)</p>