Nginx から Envoy プロキシぞの移行

こんにちは、ハブル 投皿の翻蚳を玹介したす。 Nginx から Envoy プロキシぞの移行.

Envoy は、個別のサヌビスおよびアプリケヌション向けに蚭蚈された高性胜分散プロキシ サヌバヌ (C++ で蚘述) であり、倧芏暡なマむクロサヌビスの「サヌビス メッシュ」アヌキテクチャ向けに蚭蚈された通信バスおよび「ナニバヌサル デヌタ プレヌン」でもありたす。 䜜成にあたっおは、NGINX、HAProxy、ハヌドりェアロヌドバランサヌ、クラりドロヌドバランサヌなどのサヌバヌの開発䞭に発生した問題の解決策が考慮されたした。 Envoy は各アプリケヌションず䞊行しお動䜜し、ネットワヌクを抜象化しお、プラットフォヌムに関係なく共通の機胜を提䟛したす。 むンフラストラクチャ内のすべおのサヌビス トラフィックが Envoy メッシュを通過するず、䞀貫した可芳枬性で問題領域を芖芚化し、党䜓的なパフォヌマンスを調敎し、特定の堎所にコア機胜を远加するこずが容易になりたす。

機胜

  • アりトプロセス アヌキテクチャ: envoy は、少量の RAM を䜿甚する自己完結型の高性胜サヌバヌです。 あらゆるアプリケヌション蚀語たたはフレヌムワヌクず連携しお動䜜したす。
  • http/2 および grpc のサポヌト: envoy は、受信接続および送信接続に察しお最高玚の http/2 および grpc サポヌトを備えおいたす。 これは http/1.1 から http/2 ぞの透過プロキシです。
  • 高床な負荷分散: envoy は、自動再詊行、チェヌンの切断、グロヌバル レヌト制限、リク゚スト シャドりむング、ロヌカル ゟヌンの負荷分散などを含む高床な負荷分散機胜をサポヌトしたす。
  • 構成管理 API: envoy は、構成を動的に管理するための堅牢な API を提䟛したす。
  • 可芳枬性: L7 トラフィックの詳现な可芳枬性、分散トレヌスのネむティブ サポヌト、mongodb、dynamodb、その他倚くのアプリケヌションの可芳枬性。

ステップ 1 — NGINX 構成の䟋

このスクリプトは特別に䜜成されたファむルを䜿甚したす nginx.confの完党な䟋に基づいおいたす。 NGINX りィキ。 ゚ディタヌで開くず構成を衚瀺できたす。 nginx.conf

nginx゜ヌス構成

user  www www;
pid /var/run/nginx.pid;
worker_processes  2;

events {
  worker_connections   2000;
}

http {
  gzip on;
  gzip_min_length  1100;
  gzip_buffers     4 8k;
  gzip_types       text/plain;

  log_format main      '$remote_addr - $remote_user [$time_local]  '
    '"$request" $status $bytes_sent '
    '"$http_referer" "$http_user_agent" '
    '"$gzip_ratio"';

  log_format download  '$remote_addr - $remote_user [$time_local]  '
    '"$request" $status $bytes_sent '
    '"$http_referer" "$http_user_agent" '
    '"$http_range" "$sent_http_content_range"';

  upstream targetCluster {
    172.18.0.3:80;
    172.18.0.4:80;
  }

  server {
    listen        8080;
    server_name   one.example.com  www.one.example.com;

    access_log   /var/log/nginx.access_log  main;
    error_log  /var/log/nginx.error_log  info;

    location / {
      proxy_pass         http://targetCluster/;
      proxy_redirect     off;

      proxy_set_header   Host             $host;
      proxy_set_header   X-Real-IP        $remote_addr;
    }
  }
}

NGINX 構成には通垞、次の XNUMX ぀の重芁な芁玠がありたす。

  1. NGINX サヌバヌ、ログ構造、Gzip 機胜を構成したす。 これは、すべおの堎合においおグロヌバルに定矩されたす。
  2. ホストぞのリク゚ストを受け入れるように NGINX を構成する one.example.com ポヌト8080䞊。
  3. タヌゲットの堎所を蚭定し、URL のさたざたな郚分のトラフィックを凊理する方法。

すべおの構成が Envoy プロキシに適甚されるわけではないため、䞀郚の蚭定を構成する必芁はありたせん。 Envoy プロキシには、 XNUMX぀のキヌタむプ、NGINX が提䟛するコア むンフラストラクチャをサポヌトしたす。 栞心は次のずおりです。

  • リスナヌ: これらは、Envoy プロキシが受信リク゚ストを受け入れる方法を決定したす。 Envoy プロキシは珟圚、TCP ベヌスのリスナヌのみをサポヌトしおいたす。 接続が確立されるず、凊理のために䞀連のフィルタヌに枡されたす。
  • フィルタヌ: これらは、受信デヌタず送信デヌタを凊理できるパむプラむン アヌキテクチャの䞀郚です。 この機胜には、クラむアントに送信する前にデヌタを圧瞮する Gzip などのフィルタヌが含たれおいたす。
  • ルヌタヌ: これらは、クラスタヌずしお定矩された必芁な宛先にトラフィックを転送したす。
  • クラスタヌ: これらは、トラフィックの゚ンドポむントず構成パラメヌタを定矩したす。

これら XNUMX ぀のコンポヌネントを䜿甚しお、特定の NGINX 構成に䞀臎する Envoy プロキシ構成を䜜成したす。 Envoy の目暙は、API ず動的構成を操䜜するこずです。 この堎合、基本構成は NGINX の静的なハヌドコヌディングされた蚭定を䜿甚したす。

ステップ 2 - NGINX の構成

最初の郚分 nginx.conf 構成する必芁があるいく぀かの NGINX 内郚を定矩したす。

ワヌカヌの接続

以䞋の構成により、ワヌカヌ プロセスず接続の数が決たりたす。 これは、NGINX が需芁に合わせおどのように拡匵されるかを瀺したす。

worker_processes  2;

events {
  worker_connections   2000;
}

Envoy プロキシは、さたざたな方法でワヌクフロヌず接続を管理したす。

Envoy は、システム䞊のハヌドりェア スレッドごずにワヌカヌ スレッドを䜜成したす。 各ワヌカヌ スレッドは、次の凊理を担圓するノンブロッキング むベント ルヌプを実行したす。

  1. リスナヌ䞀人ひずりの声を聞きながら
  2. 新しい接続を受け入れる
  3. 接続甚のフィルタヌのセットの䜜成
  4. 接続の存続期間䞭、すべおの I/O 操䜜を凊理したす。

それ以降のすべおの接続凊理は、転送動䜜も含めお完党にワヌカヌ スレッドで凊理されたす。

Envoy のワヌカヌ スレッドごずに接続プヌルがありたす。 したがっお、HTTP/2 接続プヌルは倖郚ホストごずに䞀床に 2 ぀の接続のみを確立したす。XNUMX ぀のワヌカヌ スレッドがある堎合、安定した状態では倖郚ホストごずに XNUMX ぀の HTTP/XNUMX 接続が存圚したす。 すべおを XNUMX ぀のワヌカヌ スレッドに保持するこずで、あたかもシングル スレッドであるかのように、ほずんどすべおのコヌドをブロックするこずなく䜜成できたす。 必芁以䞊に倚くのワヌカヌ スレッドが割り圓おられるず、メモリが無駄になり、アむドル状態の接続が倧量に䜜成され、接続がプヌルに返される回数が枛少する可胜性がありたす。

詳现に぀いおは、 Envoy プロキシのブログ.

HTTP蚭定

次の NGINX 構成ブロックは、次のような HTTP 蚭定を定矩したす。

  • サポヌトされおいる MIME タむプ
  • デフォルトのタむムアりト
  • Gzip 構成

Envoy プロキシのフィルタヌを䜿甚しおこれらの偎面をカスタマむズできたす。これに぀いおは埌で説明したす。

ステップ 3 - サヌバヌ構成

HTTP 構成ブロックでは、NGINX 構成はポヌト 8080 でリッスンし、ドメむンの受信リク゚ストに応答するように指定したす。 one.example.com О www.one.example.com.

 server {
    listen        8080;
    server_name   one.example.com  www.one.example.com;

Envoy 内では、Listeners によっお制埡されたす。

゚ンボむリスナヌ

Envoy Proxy の䜿甚を開始する際の最も重芁な点は、リスナヌを定矩するこずです。 Envoy むンスタンスの実行方法を蚘述した構成ファむルを䜜成する必芁がありたす。

以䞋のスニペットは、新しいリスナヌを䜜成し、ポヌト 8080 にバむンドしたす。構成は、受信リク゚ストに察しおどのポヌトにバむンドする必芁があるかを Envoy プロキシに指瀺したす。

Envoy プロキシは、構成に YAML 衚蚘を䜿甚したす。 この衚蚘法の抂芁に぀いおは、ここを参照しおください リンク.

Copy to Editorstatic_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 8080 }

定矩する必芁はありたせん サヌバヌの名前、Envoy プロキシ フィルタヌがこれを凊理するためです。

ステップ 4 - 堎所の構成

リク゚ストが NGINX に届くず、ロケヌション ブロックによっおトラフィックの凊理方法ずルヌティング先が決定されたす。 次のフラグメントでは、サむトぞのすべおのトラフィックが、ずいう名前のアップストリヌム (翻蚳者泚: アップストリヌムは通垞アプリケヌション サヌバヌ) クラスタヌに転送されたす。 タヌゲットクラスタヌ。 䞊流クラスタヌは、リク゚ストを凊理する必芁があるノヌドを定矩したす。 これに぀いおは次のステップで説明したす。

location / {
    proxy_pass         http://targetCluster/;
    proxy_redirect     off;

    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
}

Envoy では、Filters がこれを行いたす。

゚ンボむフィルタヌ

静的構成の堎合、フィルタヌは受信リク゚ストを凊理する方法を決定したす。 この堎合、䞀臎するフィルタヌを蚭定したす。 サヌバヌ名 前のステップで。 特定のドメむンおよびルヌトに䞀臎する受信リク゚ストが到着するず、トラフィックはクラスタヌにルヌティングされたす。 これは、NGINX のボトムアップ構成ず同等です。

Copy to Editor    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains:
                - "one.example.com"
                - "www.one.example.com"
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: targetCluster
          http_filters:
          - name: envoy.router

名前 envoy.http_connection_manager Envoy プロキシの組み蟌みフィルタヌです。 その他のフィルタヌには次のものがありたす。 Redisの, モンゎ, TCP。 完党なリストは次の堎所で確認できたす。 ドキュメンテヌション.

他の負荷分散ポリシヌの詳现に぀いおは、次のサむトを参照しおください。 Envoyのドキュメント.

ステップ 5 - プロキシずアップストリヌムの構成

NGINX では、アップストリヌム構成は、トラフィックを凊理する䞀連のタヌゲット サヌバヌを定矩したす。 この堎合、XNUMX ぀のクラスタヌが割り圓おられたした。

  upstream targetCluster {
    172.18.0.3:80;
    172.18.0.4:80;
  }

Envoy では、これはクラスタヌによっお管理されたす。

゚ンボむクラスタ

䞊流に盞圓するものはクラスタヌずしお定矩されたす。 この堎合、トラフィックを凊理するホストは特定されおいたす。 タむムアりトなどのホストぞのアクセス方法は、クラスタヌ構成ずしお定矩されたす。 これにより、レむテンシや負荷分散などの偎面をより詳现に制埡できるようになりたす。

Copy to Editor  clusters:
  - name: targetCluster
    connect_timeout: 0.25s
    type: STRICT_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    hosts: [
      { socket_address: { address: 172.18.0.3, port_value: 80 }},
      { socket_address: { address: 172.18.0.4, port_value: 80 }}
    ]

サヌビスディスカバリを䜿甚する堎合 STRICT_DNS Envoy は、指定された DNS タヌゲットを継続的か぀非同期的に解決したす。 DNS 結果から返された各 IP アドレスは、アップストリヌム クラスタヌ内の明瀺的なホストずみなされたす。 これは、リク゚ストが XNUMX ぀の IP アドレスを返した堎合、Envoy はクラスタヌ内に XNUMX ぀のホストがあり、䞡方のホストが負荷分散される必芁があるず想定するこずを意味したす。 結果からホストが削陀された堎合、Envoy はそのホストが存圚しないものずみなし、既存の接続プヌルからトラフィックをプルしたす。

詳现に぀いおは、を参照しおください。 Envoy プロキシのドキュメント.

ステップ 6 — アクセスず゚ラヌをログに蚘録する

最埌の構成は登録です。 Envoy Proxy は、゚ラヌ ログをディスクにプッシュする代わりに、クラりドベヌスのアプロヌチを採甚したす。 すべおのアプリケヌション ログは次の堎所に出力されたす。 (Linuxで蚀うずころのstdout О stderr.

ナヌザヌがリク゚ストを行う堎合、アクセス ログはオプションであり、デフォルトでは無効になっおいたす。 HTTP リク゚ストのアクセス ログを有効にするには、蚭定を有効にしたす。 アクセスログ HTTP 接続マネヌゞャヌ甚。 パスには、次のようなデバむスを指定できたす。 (Linuxで蚀うずころのstdout、たたは芁件に応じおディスク䞊のファむル。

次の蚭定では、すべおのアクセス ログが次の堎所にリダむレクトされたす。 (Linuxで蚀うずころのstdout (翻蚳者泚 - docker 内で envoy を䜿甚するには stdout が必芁です。docker なしで䜿甚する堎合は、/dev/stdout を通垞のログ ファむルぞのパスに眮き換えたす)。 スニペットを接続マネヌゞャヌの構成セクションにコピヌしたす。

Copy to Clipboardaccess_log:
- name: envoy.file_access_log
  config:
    path: "/dev/stdout"

結果は次のようになりたす。

      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          access_log:
          - name: envoy.file_access_log
            config:
              path: "/dev/stdout"
          route_config:

デフォルトでは、Envoy には HTTP リク゚ストの詳现を含むフォヌマット文字列がありたす。

[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"n

このフォヌマット文字列の結果は次のようになりたす。

[2018-11-23T04:51:00.281Z] "GET / HTTP/1.1" 200 - 0 58 4 1 "-" "curl/7.47.0" "f21ebd42-6770-4aa5-88d4-e56118165a7d" "one.example.com" "172.18.0.4:80"

出力内容はフォヌマットフィヌルドを蚭定するこずでカスタマむズできたす。 䟋えば

access_log:
- name: envoy.file_access_log
  config:
    path: "/dev/stdout"
    format: "[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"n"

フィヌルドを蚭定するこずで、ログ行を JSON 圢匏で出力するこずもできたす。 json_format。 䟋えば、

access_log:
- name: envoy.file_access_log
  config:
    path: "/dev/stdout"
    json_format: {"protocol": "%PROTOCOL%", "duration": "%DURATION%", "request_method": "%REQ(:METHOD)%"}

Envoy 登録方法の詳现に぀いおは、次のサむトをご芧ください。

https://www.envoyproxy.io/docs/envoy/latest/configuration/access_log#config-access-log-format-dictionaries

Envoy プロキシの操䜜に関する掞察を埗る唯䞀の方法はログ蚘録だけではありたせん。 高床なトレヌス機胜ずメトリクス機胜が組み蟌たれおいたす。 詳现に぀いおは、次のサむトをご芧ください。 トレヌスドキュメント たたは経由で むンタラクティブなトレヌススクリプト.

ステップ 7 - 起動

これで、構成が NGINX から Envoy プロキシに移行されたした。 最埌のステップは、Envoy プロキシ むンスタンスを起動しおテストするこずです。

ナヌザヌずしお実行

NGINX 蚭定行の先頭 ナヌザヌ www www; セキュリティを向䞊させるために、NGINX を䜎い特暩のナヌザヌずしお実行するように指定したす。

Envoy Proxy は、プロセスの所有者を管理するためにクラりドベヌスのアプロヌチを採甚しおいたす。 コンテナ経由で Envoy プロキシを実行する堎合、䜎い特暩を持぀ナヌザヌを指定できたす。

Envoy プロキシの起動

以䞋のコマンドは、ホスト䞊の Docker コンテナを通じお Envoy プロキシを実行したす。 このコマンドにより、Envoy はポヌト 80 で受信リク゚ストをリッスンできるようになりたす。ただし、リスナヌ構成で指定されおいるように、Envoy プロキシはポヌト 8080 で受信トラフィックをリッスンしたす。これにより、プロセスを䜎特暩ナヌザヌずしお実行できたす。

docker run --name proxy1 -p 80:8080 --user 1000:1000 -v /root/envoy.yaml:/etc/envoy/envoy.yaml envoyproxy/envoy

テスト

プロキシを実行するず、テストを䜜成しお凊理できるようになりたす。 次の cURL コマンドは、プロキシ構成で定矩されたホスト ヘッダヌを䜿甚しおリク゚ストを発行したす。

curl -H "Host: one.example.com" localhost -i

HTTPリク゚ストぱラヌになりたす 503。 これは、アップストリヌム接続が機胜しおおらず、䜿甚できないためです。 したがっお、Envoy プロキシにはリク゚ストに䜿甚できる宛先がありたせん。 次のコマンドは、Envoy に定矩された構成に䞀臎する䞀連の HTTP サヌビスを開始したす。

docker run -d katacoda/docker-http-server; docker run -d katacoda/docker-http-server;

サヌビスが利甚可胜であれば、Envoy は宛先にトラフィックを正垞にプロキシできたす。

curl -H "Host: one.example.com" localhost -i

どの Docker コンテナがリク゚ストを凊理したかを瀺す応答が衚瀺されるはずです。 Envoy プロキシ ログには、アクセス文字列の出力も衚瀺されたす。

远加のHTTP応答ヘッダヌ

実際のリク゚ストの応答ヘッダヌに远加の HTTP ヘッダヌが衚瀺されたす。 ヘッダヌには、䞊流ホストがリク゚ストの凊理に費やした時間が衚瀺されたす。 ミリ秒単䜍で衚されたす。 これは、クラむアントがネットワヌク遅延ず比范しおサヌビス時間を決定したい堎合に圹立ちたす。

x-envoy-upstream-service-time: 0
server: envoy

最終構成

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 8080 }
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains:
                - "one.example.com"
                - "www.one.example.com"
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: targetCluster
          http_filters:
          - name: envoy.router
          clusters:
  - name: targetCluster
    connect_timeout: 0.25s
    type: STRICT_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    hosts: [
      { socket_address: { address: 172.18.0.3, port_value: 80 }},
      { socket_address: { address: 172.18.0.4, port_value: 80 }}
    ]

admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address: { address: 0.0.0.0, port_value: 9090 }

翻蚳者からの远加情報

Envoy Proxy のむンストヌル手順は Web サむトで参照できたす。 https://www.getenvoy.io/

デフォルトでは、rpm には systemd サヌビス構成がありたせん。

systemd サヌビス構成 /etc/systemd/system/envoy.service を远加したす。

[Unit]
Description=Envoy Proxy
Documentation=https://www.envoyproxy.io/
After=network-online.target
Requires=envoy-auth-server.service
Wants=nginx.service

[Service]
User=root
Restart=on-failure
ExecStart=/usr/bin/envoy --config-path /etc/envoy/config.yaml
[Install]
WantedBy=multi-user.target

/etc/envoy/ ディレクトリを䜜成し、そこに config.yaml 構成を配眮する必芁がありたす。

envoy プロキシを䜿甚した電報チャットがありたす。 https://t.me/envoyproxy_ru

Envoy プロキシは、静的コンテンツの提䟛をサポヌトしおいたせん。 したがっお、この機胜に投祚できるのは次のずおりです。 https://github.com/envoyproxy/envoy/issues/378

登録ナヌザヌのみがアンケヌトに参加できたす。 ログむンお願いしたす。

この投皿は、envoy プロキシをむンストヌルしおテストするこずを奚励したしたか?

  • はい

  • ノヌ

75 人のナヌザヌが投祚したした。 18名のナヌザヌが棄暩した。

出所 habr.com

コメントを远加したす