初めましてこんにちは、2023年新卒入社のやまなかです。
Envoyは、マイクロサービスアーキテクチャをサポートするOSSのネットワークプロキシとロードバランサです。自分はマイクロサービスアーキテクチャ??ネットワークプロキシ??ロードバランサ??横文字が多くてわからないよ~といった感じでしたので、この記事ではその辺りも噛み砕いてEnvoyの基本的な概念と重要な特徴を紹介します。
用語集
- マイクロサービスアーキテクチャ
機能ごとに独立したサービスとしてシステムを分け、それらを組み合わせて一つの大きなシステムを作るアーキテクチャ - ネットワークプロキシ
インターネットを接続する際に、ネットワークの内部から外部へのアクセスを代理で行うシステム。外部から内部へのアクセスを代理で行う場合はリバースプロキシと呼ばれる。 - ロードバランサ
外部からの通信(トラフィック)を複数のサーバーに分散する装置 - ネットワークトラフィック
一定時間にネットワークを流れるデータ量。 - 分散システム
複数のコンピューターをネットワークで接続し、複数のコンピューターが連携して一つの作業を分担するコンピューターシステムのことをいいます。個々のコンピューターは独立していますが、外からは全体が一つの高性能なシステムに見えるのが特徴です。
Envoyとは?
Envoyは、ネットワークトラフィックを効率的に管理し、分散システムを構築するためのツールです。サービス間のネットワークの制御をライブラリではなくネットワークプロキシとして提供することで、個々のサービスはEnvoyを経由してそれぞれのサービスへ接続します。このようにすることで、ネットワークが抽象化され、アプリケーションとネットワークの切り離しが実現されます。Kubernetesでマイクロサービスを提供するIstioのコアコンポーネントとして一躍注目を集めています。
主な特徴
-
サービスディスカバリ
新しいサービスの追加や変更を自動的に検出することができます。これにより、手動で設定を更新する手間を省くことができます。
-
ロードバランシング
トラフィックを複数のサービスインスタンス間で均等に分散することができます。これにより、負荷を適切に分散してシステムのパフォーマンスを向上させることができます。
-
ヘルスチェック
サービスの状態を監視して異常値がある場合は自動的にトラフィックを避けることができます。これにより、システムの可用性を高めることができます。
-
暗号化
TLS (Transport layer security) などのセキュリティ機能をサポートしており、通信の暗号化や認証認可を行うことができます。これにより、データの安全性を確保することができます。
構築パターン
-
Edge Proxy
自分たちのサービス群の中と外の境界に置くプロキシ
-
Egress Proxy
外部へのトラフィックの通信先などを書き換える
-
サービスメッシュ
サービス間の通信をEnvoyが媒介する
デモ
ここでは簡単にEnvoyのGetting Startedのうち、Quick startの一部までをやってみたいと思います。
動作環境
- OS : WSL2 – Ubuntu 22.04.2 LTS
- Docker : Docker version 24.0.2, build cb74dfc
デモ構成でEnvoyを動かしてみる
使用するdocker imageについては2023年8月18日時点のものです。Quick start/Run EnvoyのRun Envoy with the demo configurationから最新のドキュメントを参考にしてください。
$ docker run --rm -it -p 9901:9901 -p 10000:10000 envoyproxy/envoy:dev-c745c1956cdaffa35d6f4933b57a431a2d2e9fc7
コンテナが立ち上がったらlocalhost:10000にアクセスしてみるとhttps://www.envoyproxy.io/が表示されます。
カスタムした設定でEnvoyを動かしてみる
コンテナに入ってEnvoyの設定ファイルを覗いてみます。
まずdocker psでコンテナ名を調べて、
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
619631a04dc5 envoyproxy/envoy:dev-c745c1956cdaffa35d6f4933b57a431a2d2e9fc7 "/docker-entrypoint.…" 26 seconds ago Up 24 seconds 0.0.0.0:9901->9901/tcp, :::9901->9901/tcp, 0.0.0.0:10000->10000/tcp, :::10000->10000/tcp ecstatic_wing
コンテナに入って、envoy.yamlを見てみます。
$ docker exec -it ecstatic_wing sh #cat /etc/envoy/envoy.yaml admin: address: socket_address: protocol: TCP address: 0.0.0.0 port_value: 9901 static_resources: listeners: - name: listener_0 address: socket_address: protocol: TCP address: 0.0.0.0 port_value: 10000 filter_chains: - filters: - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager scheme_header_transformation: scheme_to_overwrite: https stat_prefix: ingress_http route_config: name: local_route virtual_hosts: - name: local_service domains: ["*"] routes: - match: prefix: "/" route: host_rewrite_literal: www.envoyproxy.io cluster: service_envoyproxy_io http_filters: - name: envoy.filters.http.router typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router clusters: - name: service_envoyproxy_io connect_timeout: 30s type: LOGICAL_DNS # Comment out the following line to test on v6 networks dns_lookup_family: V4_ONLY lb_policy: ROUND_ROBIN load_assignment: cluster_name: service_envoyproxy_io endpoints: - lb_endpoints: - endpoint: address: socket_address: address: www.envoyproxy.io port_value: 443 transport_socket: name: envoy.transport_sockets.tls typed_config: "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext sni: www.envoyproxy.io
先ほど確認した通りwww.envoyproxy.ioに転送することになっていそうです。
ローカル上にenvoy-custom.yamlという新しいファイルを作成して確認したenvoy.yamlをコピペします。
www.envoyproxy.ioをwww.sios.comに変更して、一応cluster_nameもservice_siosとかに変えておきます。
$ docker exec -it ecstatic_wing sh #cat /etc/envoy/envoy.yaml admin: address: socket_address: protocol: TCP address: 0.0.0.0 port_value: 9901 static_resources: listeners: - name: listener_0 address: socket_address: protocol: TCP address: 0.0.0.0 port_value: 10000 filter_chains: - filters: - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager scheme_header_transformation: scheme_to_overwrite: https stat_prefix: ingress_http route_config: name: local_route virtual_hosts: - name: local_service domains: ["*"] routes: - match: prefix: "/" route: host_rewrite_literal: www.sios.com cluster: service_sios http_filters: - name: envoy.filters.http.router typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router clusters: - name: service_sios connect_timeout: 30s type: LOGICAL_DNS # Comment out the following line to test on v6 networks dns_lookup_family: V4_ONLY lb_policy: ROUND_ROBIN load_assignment: cluster_name: service_sios endpoints: - lb_endpoints: - endpoint: address: socket_address: address: www.sios.com port_value: 443 transport_socket: name: envoy.transport_sockets.tls typed_config: "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext sni: www.sios.com
構成ファイルのマウント、パスを指定する下記のコマンドを実行します。
$ docker run --rm -it -v $(pwd)/envoy-custom.yaml:/envoy-custom.yaml -p 9901:9901 -p 10000:10000 envoyproxy/envoy:dev-c745c1956cdaffa35d6f4933b57a431a2d2e9fc7 -c /envoy-custom.yaml
再びlocalhost:10000にアクセスしてみると、サイオスのトップページにリダイレクトされました。
まとめ
Envoyはマイクロサービスアーキテクチャをサポートするネットワークプロキシとロードバランサの優れたツールです。サービスディスカバリ、ロードバランシング、ヘルスチェック、暗号化などの特徴により、分散システムのパフォーマンスと可用性を向上させる役割を果たします。様々な構築パターンがあり、クラウドネイティブなWebサービスにおいて重要な役割を果たします。
参考文献
https://www.envoyproxy.io/docs/envoy/v1.27.0/
https://openstandia.jp/oss_info/envoy/
https://qiita.com/miyuki_samitani/items/bbe9e1d162574a00c04c