初心者でもわかる!Envoyとは?

初めましてこんにちは、2023年新卒入社のやまなかです。

Envoyは、マイクロサービスアーキテクチャをサポートするOSSのネットワークプロキシとロードバランサです。自分はマイクロサービスアーキテクチャ??ネットワークプロキシ??ロードバランサ??横文字が多くてわからないよ~といった感じでしたので、この記事ではその辺りも噛み砕いてEnvoyの基本的な概念と重要な特徴を紹介します。

用語集

  • マイクロサービスアーキテクチャ
    機能ごとに独立したサービスとしてシステムを分け、それらを組み合わせて一つの大きなシステムを作るアーキテクチャ
  • ネットワークプロキシ
    インターネットを接続する際に、ネットワークの内部から外部へのアクセスを代理で行うシステム。外部から内部へのアクセスを代理で行う場合はリバースプロキシと呼ばれる。
  • ロードバランサ
    外部からの通信(トラフィック)を複数のサーバーに分散する装置
  • ネットワークトラフィック
    一定時間にネットワークを流れるデータ量。
  • 分散システム
    複数のコンピューターをネットワークで接続し、複数のコンピューターが連携して一つの作業を分担するコンピューターシステムのことをいいます。個々のコンピューターは独立していますが、外からは全体が一つの高性能なシステムに見えるのが特徴です。

Envoyとは?

Envoyは、ネットワークトラフィックを効率的に管理し、分散システムを構築するためのツールです。サービス間のネットワークの制御をライブラリではなくネットワークプロキシとして提供することで、個々のサービスはEnvoyを経由してそれぞれのサービスへ接続します。このようにすることで、ネットワークが抽象化され、アプリケーションとネットワークの切り離しが実現されます。Kubernetesでマイクロサービスを提供するIstioのコアコンポーネントとして一躍注目を集めています。

主な特徴

  1. サービスディスカバリ

    新しいサービスの追加や変更を自動的に検出することができます。これにより、手動で設定を更新する手間を省くことができます。

  2. ロードバランシング

    トラフィックを複数のサービスインスタンス間で均等に分散することができます。これにより、負荷を適切に分散してシステムのパフォーマンスを向上させることができます。

  3. ヘルスチェック

    サービスの状態を監視して異常値がある場合は自動的にトラフィックを避けることができます。これにより、システムの可用性を高めることができます。

  4. 暗号化

    TLS (Transport layer security) などのセキュリティ機能をサポートしており、通信の暗号化や認証認可を行うことができます。これにより、データの安全性を確保することができます。

構築パターン

  1. Edge Proxy

    自分たちのサービス群の中と外の境界に置くプロキシ 

  2. Egress Proxy

    外部へのトラフィックの通信先などを書き換える

  3. サービスメッシュ

    サービス間の通信を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

https://i-beam.org/2019/01/22/hello-envoy/

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

1人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です