Envoyの概要と、FrontProxyを実装してみる

スポンサーリンク

概要

参考: 公式ドキュメント

Microserviceとプロキシサーバについて

Microservice Architectureでは、monolithなArchitectureとは違い、システムが機能や役割別に細分化されて小さなサービスとしてデプロイされます。
サービス間はRESTAPIやgRPC等を利用して通信されます。これにより、無数のMicroserviceによる巨大なネットワークが作り出されます。
その際に、問題になるのがネットワークの透過性です。透過性とは何か問題が発生した場合に、原因が明白であること。すなわち、問題の原因をすぐに特定することができるという事です。
通常、Microservice Architectureの各Serviceは、Dockerコンテナを利用してプロキシサーバとアプリケーションサーバまとめてPod(kubernates)、ECS(Task)という形でデプロイされます。
プロキシサーバをサイドカーパターンでデプロイする事で、複雑化したネットワークの透過性の低下を解決しようとします。
プロキシサーバが担う役割として以下の点が挙げられます。

  • retry処理やtimeout等の本来アプリケーションレイヤーで実装するべきではない機能
  • ネットワークのトラフィック調整
  • ネットワークトラフィックロギングのやtrace(可視化ツールでトラフィクを可視化させる)
  • サーキットブレーキング
  • etc…

そこで、最近注目を集めているのがEnvoyという高機能のプロキシサーバです。

Envoyとは

  • Envoyは、C++で書かれたMicroservice Architectureの為の、プロキシーサーバ(ロードバランサー)です。(Nginxと似たようなポジションのミドルウェア)
  • ドキュメントには、アプリケーションの邪魔にならないように低レイテンシーな実装にするためC++で書いたという記述があります。
  • Envoyは、L3,L4レイヤーだけではなく、gRPC等のL7レイヤーやAWSのDynamoDB等のプロキシにも利用できます。
  • よくIstioのコンポーネントの一つとして紹介される事が多いですが、ServiceMeshの分野だとEnvoyはデータプレーンと呼ばれます。(ネットワークトラフィックを制御するレイヤー)それと対を成すのがコントロールプレーンと呼ばれる、Plilot,Mixerと呼ばれるコンポーネントで、EnvoyとまとめてIstioとよばれるServiceMeshが実装されます。

Envoyの機能

  • HTTP/2 のサポート
  • L7のルーティング
  • xDSとよばれるAPIを利用した、ServiceDiscovery(DynamicにConfigrationを変更できる)
  • 上位のサーバ(プロキシ先のアプリケーションサーバ)のヘルスチェック
  • 自動リトライ
  • サーキットブレーキング
  • プライオリティによるトラフィックの調整
  • ロギング

Envoyは2種類の使い分け

  • Front Proxy(Envoy単体で、Edgeに対してリクエストを振り分けて、TLS通信のエンドポイントになったりする)
  • Edge Proxy(アプリケーションサーバとサイドカーパターンでデプロイする)
  • FrontとEdgeで同一のソフトウエアを利用することで、Envoyのネットワークサービスとしての最大限の恩恵(機能)を受ける事ができるようです。(ドキュメントより)

EnvoyのStatic Configration

  • 今回は、Static Configration(静的な設定)でpythonのアプリケーションを動作させたいとおもいます。
  • Envoyの設定ファイルは、yml形式で記述します。

検証構成

  • 構成は以下のとおりです。

envoy

  • Front Envoyから2つのアプリケーションにプロキシする構成です。(アプリケーションは同一であるが、環境変数で少し動作を変える)

FrontEnvoyの設定

  • 以下のとおりに設定ファイルを記述する

Edge側の設定

  • 以下の通りに設定ファイルを記述する

  • app-aの部分はdockerのDNSで名前解決するため、app-bをデプロイする際は、修正が必要です。

EdgeのEnvoyに紐づくアプリケーション

  • 今回のアプリケーションはFlaskを利用してredisをインクリメントするだけのAPIを作成します。

Docker-ComposeでFrontProxyとedgeを立ち上げる

  • 完成したものはこちらにあるのでcloneしてdocker-compose upしましょう!
# buildする
$ docker-compose build

# 起動する
$ docker-compose up

# curlでFrontEnvoyにリクエストを投げる
$ curl localhost:8000/app/a
Hello from behind Envoy (service a)! hostname: 9ae222e5c6e5 resolvedhostname: 172.21.0.
$ curl localhost:8000/app/b
Hello from behind Envoy (service b)! hostname: b2cf2538729f resolvedhostname: 172.21.0.8

# redisをインクリメントする
$ curl localhost:8000/app/a/incr
Hello from behind Envoy (service a)! hostname: 9ae222e5c6e5 resolvedhostname: 172.21.0.7
app 1times

# /app/a/viewでincrementしないでredisのカウントを取得する
$ curl localhost:8000/app/a/view
Hello from behind Envoy (service a)! hostname: 9ae222e5c6e5 resolvedhostname: 172.21.0.7
app 1times

# redisを初期化する
$ curl localhost:8000/app/a/init
Hello from behind Envoy (service a)! hostname: 9ae222e5c6e5 resolvedhostname: 172.21.0.7
app 0times

# アプリケーションコンテナを増やしてみる
$ docker-compose scale app-a=3
  • コンテナの数を増やしたり減らしたりして、挙動が変わるので遊んでみて下さい!

まとめ

今回、EnvoyのStatic Configrationを利用して簡単なPythonのアプリケーションを実装してみました。Envoyは、プロキシサーバとしても優秀ですが様々なAPIが実装されています。それらを利用することで、DynamicにConfigrationを変更することができます。Envoy自体はConfigrationをDynamicに変更するAPIしか実装されていないため、単体でServiceDiscovery等の実装を行う事はできません。ServiceDiscoveryを実装するには、サービスレジストリの更新を検知してEnvoyのConfigrationをAPI経由で変更する役割を持ったControlPlaneとよばれるコンポーネントが必要になります。
Istio等を利用しなくても、Envoyの公式でgo-control-plane等のパッケージ等も用意されているので、独自でServiceDiscoveryを実装することも可能なようです。
また、最近Microservice向けにプロキシサーバが活発にGithub上に公開されているようです。
Golang等でProxyを実装しているパターンもあったりします。
それぞれのプロキシサーバの性能比較とかを行ってみるのも面白いかもしれません。
次回は、今回docker-composeで実装した内容をAWSのECS上で展開していきたいと思います。

コメント

タイトルとURLをコピーしました