社内エンジニアカンファレンスで発表したものです
⼊⾨Envoy株式会社サイバーエージェント AI事業本部 黒崎 優太 (@kuro_m )@AI Tech Developer Conference
View Slide
黒崎 優太• 株式会社サイバーエージェント Dynalyst 開発責任者• 業務は Scala + AWSが中⼼• イラスト図解でよくわかる ITインフラの基礎知識•書きました• ⾃宅サーバなどが好きです@kuro_m @kurochan
Contents• Envoyとは• Envoyができること• Envoyのつかいかた• サービスメッシュについて• Dynalystでの導⼊事例
Envoyとは
Envoyを使ったことがある⼈?•!
Envoyに対する誤解• EnvoyとIstioは同じですか?• いいえ、違います (役割違い)• Envoyはサービスメッシュですか?• いいえ、違います (Envoyだけでは成⽴しない)• Envoyはマイクロサービスですか?• いいえ、違います (Envoy⾃⾝はサービスではない)• Envoyとは何者なのか• いろんなところで単語は聞くけれど…
Envoyとは?• OSSのL /L プロキシ• 「モダンなサービス指向アーキテクチャ」向け• 「ユニバーサルデータプレーン」を⽬指して開発されている• パフォーマンスに優れ、拡張性が⾼く、API経由でコントロール可能なプロキシ• C++で書かれているらしい, ⼿元でビルドしてみたら1時間以上掛かったhttps://www.envoyproxy.io/docs/envoy/latest/intro/what_is_envoy
Envoyのユースケース• Edge Proxy• 外部(インターネット)との境界に設置する• API Gatewayのようなものとしても• サービスやInternal Proxyにトラフィックをロードバランシング/転送する• Internal Proxy• 内部での通信をロードバランシング/転送する• Egress Proxy• 外向きのトラフィックをプロキシする(後述)
Envoyができること
Envoyができること• Envoyの「プロキシ」としての動作を理解するために、まずはシンプルに httpのリクエストを受け取ってバックエンドのサーバに転送することを考える• 慣れ親しんだNginxとの⽐較で⾒ていきましょう
Nginxと⽐較• 構成backendNginx or Envoyproxy. . .. . .
Nginxと⽐較
Nginxと⽐較: listen
Nginxと⽐較: virtual host
Nginxと⽐較: ルーティング
Nginxと⽐較: ロードバランシング
Envoyができること• 基本的なプロキシができることはわかったので、 さらにできることをかいつまんで紹介します
各種プロトコル対応• HTTP( . / )• gRPC• AWS Lambda, DynamoDB• Kafka• MySQL• Postgres• Redis• Thrift• ZooKeeeper
サーキットブレーカー• 突発的な負荷の増⼤、何かしらの障害によりプロキシ先の レスポンスタイムやエラーレートが増⼤した時にトラフィックを転送しないようにする• 障害の連鎖が防⽌できる• 条件指定で⾃動でリトライをさせることもできる
トラフィック分割• A/Bテストやカナリアリリース、ローリングアップデートなど
ロードバランシング• Random• Weighted round robin• Weighted least connection• Ring Hash• Maglev• 昔紹介記事を書きました• https://www.slideshare.net/kuro_m /maglev-a-fast-and-reliable-software-network-load-balancer
Dynamic Configuration• 動的に設定を変更することができる• 今まで紹介したのは設定ファイルによる静的な設定⽅法• Dynamic from filesystem• ファイルの変更を監視して⾃動で反映• 外部から設定変更するアプリケーションが作りやすい• Dynamic from control plane• gRPC streamingで管理サーバと通信して リアルタイムに設定変更可能(xDS protocol)• これが特徴的(後述)
Envoyのつかい⽅
Envoyの使い⽅• Envoyのデプロイパターンを紹介します
Edge Proxy• ⾃分たちのサービス群の中と外の境界に置くプロキシbackendEnvoy
Egress Proxy• 外向きのトラフィックの通信先などを透過的に書き換える• クライアントサイドロードバランシングのようなことができる• 通信先のリストを知らないといけないのでサービスディスカバリが必要になるbackendEnvoy
サービスメッシュ• サービス間の通信をEnvoyが媒介する• コンテナで動くアプリケーションの場合はEnvoyのコンテナを並べてプロキシ• 「インジェクション」すると表現されることもある• アンバサダーパターンとも• 詳しくは後述Service BEnvoyService AEnvoyhost A host B
Envoyを「インジェクション」する?• コンテナを横に並べるだけですべての通信が勝⼿にEnvoyを経由する訳ではない• iptablesで出⼊りするトラフィックをすべてEnvoyに吸い込む• Egressはすべて吸い込むとEnvoy⾃⾝のトラフィックも吸い込んでしまうので除外条件つきiptablesの設定例
サービスメッシュについて
サービスメッシュとは• サービス(アプリケーション)同⼠が連携するために直接通信し、 メッシュ状になっているもののこと• そのために必要な機能をプロキシによって透過的に提供する インフラレイヤのこと
サービスメッシュを導⼊する動機• 機能ごとにサービスを分割し、サービス間が通信で連携することによりシステム全体を構築する(サービス指向アーキテクチャ)• サービスの単位が⼩さくなるとマイクロサービスアーキテクチャ• サービスが分割されると通信が発⽣するため考えることが増える• 通信先のリストが欲しい(サービスディスカバリ)• サービス間の通信の流れをトラッキングしたい(分散トレーシング)• 障害時に影響範囲を⼩さくしたい(サーキットブレーカー)• 負荷分散したい(ロードバランシング)• などなど• ⾃前で実装していたら⼤変なので全てProxyを挟んで透過的に、 しかも⾃動で設定変更の反映をしてほしい => Envoy登場
コントロールプレーンとデータプレーン• ここまで話した内容だとEnvoyは外部から設定しないと動作しない• データプレーン(D-plane)と それらを管理するコントロールプレーン(C-palne)が必要
D-planeが⾏うべきこと• サービスディスカバリ• バックエンド(upstream)の転送先は?• ヘルスチェック• 転送先は⽣きているのか?• ルーティング• どのリクエストをどのバックエンドに転送する?• ロードバランシング• 認証/認可• JWTの検証やTLSの終端など• mTLSを⽤いてサービスメッシュ内のトラフィックを 暗号化 + 認証/認可することも• 可観測性(Observability)• 各種メトリクス, トレーシング, ロギングなど
C-planeが⾏うべきこと• D-planeの制御• D-planeは単独では何をするべきなのか知らないので、司令をする• 直接データを転送することには関与しない(D-palneの仕事)• C-planeはサーバだったりDBで構成されていて、 D-planeはC-plalneに⾃分は何をすべきか問い合わせにいくパターンが多い
EnvoyをD-planeに採⽤している例• C-planeの例を3つ紹介します
Istiohttps://istio.io/latest/docs/ops/deployment/architecture/
AWS App Meshhttps://aws.amazon.com/jp/blogs/news/introducing-aws-app-mesh-service-mesh-for-microservices-on-aws/
Google Cloud Endpointshttps://cloud.google.com/blog/ja/products/api-management/announcing-api-management-for-services-that-use-envoy
Dynalystでの導⼊事例
Envoyを導⼊することになった動機• 広告⼊札価格決定の機械学習の推論部分を外部サービス化することになった• データサイエンティストが増えてきてA/Bテストをたくさん回すようになった• サービスとして切り離してA/Bテストをたくさん回しやすいようにしたい• データサイエンティストはScalaよりもPythonでロジック実装できたほうが嬉しい• ⾼パフォーマンスが要求される• ms程度でレスポンスしてほしいのでサービス間で直接通信させたい• きちんとトラフィックをモニタリングしたい• サーキットブレーカーが欲しい• => サービスメッシュが向いてそう• 検証中
AWS App Mesh• AWSのサービスメッシュのマネージド サービス• EC , ECS, EKSでサポートされている• Envoyのことを知らなくても使えるように抽象化されて提供されている印象• ⾃分の場合は抽象化されていると逆に挙動が気になってしまうため今回の発表に⾄る• 実務上はEnvoyのことをほぼ意識することなく使えて便利• AWS X-Rayでトレーシング可能
C-plane• AWS App Meshのマネージド サービスとして提供• サービスディスカバリはxDS APIを使う• AWS Cloud Map(サービスディスカバリのマネージド‧サービス)と連携できる• Amazon ECSを使っている場合は Cloud Map連携をオンにするだけで⾃動でコンテナが登録されて便利
D-plane• Envoyを利⽤• AWSが提供しているApp Mesh⽤のEnvoyコンテナを使うと 起動時にApp MeshのAPIを叩いて初期設定を⽣成しEnvoyを起動してくれるhttps://docs.aws.amazon.com/app-mesh/latest/userguide/envoy.html
パフォーマンス問題• Pythonで書かれた機械学習推論サーバが推論サーバ単体の時と⽐較してEnvoyを間に挟むとスループットが半分以下になる• CPU使⽤率も100%近くあったのが半分以下になってしまう
原因• 推論サーバとの通信にはgRPC(HTTP/ )を使っていた• Pythonをマルチプロセスで動かし、SO_REUSEPORTを使って コネクションごとの負荷分散をしていた• HTTP/ は1つのコネクションに複数のストリームを同時に流すことができる• Envoyはコネクションを有効活⽤するためにできるだけ多くのリクエストを1つのストリームに流そうとする• Pythonは並列処理が苦⼿(GIL)なのでコネクション数が少ないと スループットが出しにくい• Envoyと推論サーバのコネクション数を増やせば解決しそう
対処• EnvoyはデフォルトだとCPUのコア数と同じ数のワーカースレッドを⽣成する• EnvoyはHTTP/ において1つの宛先につきワーカー数以上のコネクションを貼らない(ようにみえる, 要出典)• --concurrency を起動時にオプションで渡すことでスレッド数は変更可能• App Mesh⽤の公式Envoyコンテナはオプションが変更できない• 起動スクリプトを改造しカスタムのEnvoyイメージを作成• Feature requestしました: https://github.com/aws/aws-app-mesh-roadmap/issues/• スループットは改善した• (あまり綺麗な解決ではないものの…)
まとめ
まとめ• Envoyの概要を紹介したあと、 Envoyとサービスメッシュの関係性、 Dynalystでの導⼊事例について紹介しました。• これから使ってみたいと思っていた⼈の参考になれば幸いです