Paglipat mula Nginx sa Envoy Proxy

Hello, Habr! Dinadala ko sa iyong pansin ang isang pagsasalin ng post: Paglipat mula Nginx sa Envoy Proxy.

Ang Envoy ay isang high-performance distributed proxy server (nakasulat sa C++) na idinisenyo para sa mga indibidwal na serbisyo at application, isa rin itong bus ng komunikasyon at "universal data plane" na idinisenyo para sa malalaking microservice na "service mesh" na arkitektura. Kapag nilikha ito, ang mga solusyon sa mga problema na lumitaw sa panahon ng pagbuo ng mga server tulad ng NGINX, HAProxy, hardware load balancer at cloud load balancer ay isinasaalang-alang. Gumagana ang Envoy sa tabi ng bawat application at i-abstract ang network upang magbigay ng karaniwang functionality anuman ang platform. Kapag ang lahat ng trapiko ng serbisyo sa isang imprastraktura ay dumadaloy sa Envoy mesh, nagiging madaling makita ang mga lugar ng problema na may pare-parehong pagmamasid, ibagay ang pangkalahatang pagganap, at magdagdag ng pangunahing functionality sa isang partikular na lokasyon.

Mga Kakayahan

  • Out-of-process architecture: ang envoy ay isang self-contained, high-performance server na kumukuha ng maliit na halaga ng RAM. Gumagana ito kasabay ng anumang wika o balangkas ng aplikasyon.
  • http/2 at grpc support: envoy ay may first-class na http/2 at grpc support para sa mga papasok at papalabas na koneksyon. Ito ay isang transparent na proxy mula sa http/1.1 hanggang http/2.
  • Advanced na Load Balancing: Sinusuportahan ng envoy ang mga advanced na feature ng load balancing kabilang ang mga awtomatikong muling pagsubok, chain breaking, global rate limiting, request shadowing, local zone load balancing, atbp.
  • Configuration Management API: nagbibigay ang envoy ng isang matatag na API para sa dynamic na pamamahala sa iyong configuration.
  • Obserbasyon: Malalim na obserbasyon ng trapiko ng L7, katutubong suporta para sa distributed tracing at observability ng mongodb, dynamodb at marami pang ibang application.

Hakbang 1 β€” Halimbawa NGINX Config

Gumagamit ang script na ito ng isang espesyal na ginawang file nginx.conf, batay sa buong halimbawa mula sa NGINX Wiki. Maaari mong tingnan ang configuration sa editor sa pamamagitan ng pagbubukas nginx.conf

nginx source config

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;
    }
  }
}

Ang mga configuration ng NGINX ay karaniwang may tatlong pangunahing elemento:

  1. Pag-configure ng NGINX server, istraktura ng log at pag-andar ng Gzip. Ito ay tinukoy sa buong mundo sa lahat ng kaso.
  2. Pag-configure ng NGINX upang tanggapin ang mga kahilingan sa host one.example.com sa port 8080.
  3. Pagse-set up ng target na lokasyon, kung paano pangasiwaan ang trapiko para sa iba't ibang bahagi ng URL.

Hindi lahat ng configuration ay malalapat sa Envoy Proxy, at hindi mo kailangang i-configure ang ilang mga setting. Ang Envoy Proxy ay mayroon apat na pangunahing uri, na sumusuporta sa pangunahing imprastraktura na inaalok ng NGINX. Ang core ay:

  • Mga nakikinig: Tinutukoy nila kung paano tinatanggap ng Envoy Proxy ang mga papasok na kahilingan. Kasalukuyang sinusuportahan lamang ng Envoy Proxy ang mga tagapakinig na nakabatay sa TCP. Sa sandaling maitatag ang isang koneksyon, ipapasa ito sa isang hanay ng mga filter para sa pagproseso.
  • Mga Filter: Ang mga ito ay bahagi ng isang pipeline architecture na maaaring magproseso ng papasok at papalabas na data. Kasama sa functionality na ito ang mga filter gaya ng Gzip, na nagpi-compress ng data bago ito ipadala sa client.
  • Mga Router: Nagpapasa sila ng trapiko sa kinakailangang destinasyon, na tinukoy bilang isang cluster.
  • Mga Cluster: Tinutukoy nila ang endpoint para sa trapiko at mga parameter ng configuration.

Gagamitin namin ang apat na bahaging ito upang lumikha ng configuration ng Envoy Proxy upang tumugma sa isang partikular na configuration ng NGINX. Ang layunin ng Envoy ay magtrabaho kasama ang mga API at dynamic na configuration. Sa kasong ito, ang base configuration ay gagamit ng static, hard-coded na mga setting mula sa NGINX.

Hakbang 2 - Configuration ng NGINX

Ang unang bahagi nginx.conf tumutukoy sa ilang NGINX internal na kailangang i-configure.

Mga Koneksyon sa Manggagawa

Tinutukoy ng configuration sa ibaba ang bilang ng mga proseso at koneksyon ng manggagawa. Ipinapahiwatig nito kung paano mag-i-scale ang NGINX upang matugunan ang demand.

worker_processes  2;

events {
  worker_connections   2000;
}

Pinamamahalaan ng Envoy Proxy ang mga daloy ng trabaho at koneksyon sa iba't ibang paraan.

Lumilikha si Envoy ng thread ng manggagawa para sa bawat thread ng hardware sa system. Ang bawat thread ng manggagawa ay nagpapatupad ng isang hindi nakaharang na loop ng kaganapan na responsable para sa

  1. Pakikinig sa bawat tagapakinig
  2. Pagtanggap ng mga bagong koneksyon
  3. Paglikha ng isang hanay ng mga filter para sa isang koneksyon
  4. Iproseso ang lahat ng mga operasyon ng I/O sa buong buhay ng koneksyon.

Ang lahat ng karagdagang pagpoproseso ng koneksyon ay ganap na pinangangasiwaan sa thread ng manggagawa, kabilang ang anumang pag-uugali sa pagpapasa.

Para sa bawat thread ng manggagawa sa Envoy, mayroong pool ng koneksyon. Kaya ang mga pool ng koneksyon sa HTTP/2 ay nagtatag lamang ng isang koneksyon sa bawat panlabas na host sa isang pagkakataon, kung mayroong apat na thread ng manggagawa magkakaroon ng apat na HTTP/2 na koneksyon sa bawat panlabas na host sa isang matatag na estado. Sa pamamagitan ng pagpapanatili ng lahat sa isang thread ng manggagawa, halos lahat ng code ay maaaring isulat nang walang pagharang, na parang ito ay isang sinulid. Kung mas maraming thread ng manggagawa ang inilalaan kaysa sa kinakailangan, maaari itong humantong sa nasayang na memorya, paglikha ng malaking bilang ng mga idle na koneksyon, at pagbabawas ng bilang ng beses na ibinalik ang mga koneksyon sa pool.

Para sa karagdagang impormasyon sa pagbisita Envoy Proxy blog.

HTTP Configuration

Ang sumusunod na bloke ng pagsasaayos ng NGINX ay tumutukoy sa mga setting ng HTTP tulad ng:

  • Anong mga uri ng mime ang sinusuportahan
  • Mga Default na Timeout
  • Configuration ng Gzip

Maaari mong i-customize ang mga aspetong ito gamit ang mga filter sa Envoy Proxy, na tatalakayin natin sa ibang pagkakataon.

Hakbang 3 - Configuration ng Server

Sa HTTP configuration block, ang NGINX configuration ay tumutukoy upang makinig sa port 8080 at tumugon sa mga papasok na kahilingan para sa mga domain one.example.com ΠΈ www.one.example.com.

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

Inside Envoy, ito ay kinokontrol ng Listeners.

Mga tagapakinig ng sugo

Ang pinakamahalagang aspeto ng pagsisimula sa Envoy Proxy ay ang pagtukoy sa iyong mga tagapakinig. Kailangan mong gumawa ng configuration file na naglalarawan kung paano mo gustong patakbuhin ang Envoy instance.

Ang snippet sa ibaba ay lilikha ng bagong tagapakinig at ibibigkis ito sa port 8080. Sinasabi ng configuration sa Envoy Proxy kung aling mga port ang dapat nitong i-bind para sa mga papasok na kahilingan.

Gumagamit ang Envoy Proxy ng YAML notation para sa configuration nito. Para sa panimula sa notasyong ito, tingnan dito link.

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

Hindi na kailangang tukuyin pangalan ng server, dahil ang mga filter ng Envoy Proxy ang hahawak nito.

Hakbang 4 - Configuration ng Lokasyon

Kapag dumating ang isang kahilingan sa NGINX, tinutukoy ng bloke ng lokasyon kung paano iproseso at kung saan dadalhin ang trapiko. Sa sumusunod na fragment, ang lahat ng trapiko sa site ay inililipat sa isang upstream (tala ng tagapagsalin: upstream ay karaniwang isang server ng application) cluster na pinangalanan targetCluster. Tinutukoy ng upstream cluster ang mga node na dapat magproseso ng kahilingan. Tatalakayin natin ito sa susunod na hakbang.

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

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

Sa Envoy, ginagawa ito ng Mga Filter.

Mga Filter ng Envoy

Para sa isang static na configuration, tinutukoy ng mga filter kung paano iproseso ang mga papasok na kahilingan. Sa kasong ito, nagtatakda kami ng mga filter na tumutugma server_name sa nakaraang hakbang. Kapag dumating ang mga papasok na kahilingan na tumutugma sa ilang partikular na domain at ruta, iruruta ang trapiko sa cluster. Ito ay katumbas ng isang NGINX bottom-up configuration.

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

pangalan envoy.http_connection_manager ay isang built-in na filter sa Envoy Proxy. Kasama sa iba pang mga filter Redis, Mongo, TCP. Mahahanap mo ang kumpletong listahan sa dokumentasyon.

Para sa higit pang impormasyon tungkol sa iba pang mga patakaran sa pag-load balancing, bisitahin ang Dokumentasyon ng Envoy.

Hakbang 5 - Proxy at Upstream na Configuration

Sa NGINX, ang upstream configuration ay tumutukoy sa isang set ng mga target na server na magpoproseso ng trapiko. Sa kasong ito, dalawang kumpol ang itinalaga.

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

Sa Envoy, ito ay pinamamahalaan ng mga kumpol.

Mga Kluster ng Envoy

Ang katumbas ng upstream ay tinukoy bilang mga kumpol. Sa kasong ito, natukoy na ang mga host na magsisilbi sa trapiko. Ang paraan ng pag-access sa mga host, gaya ng mga timeout, ay tinukoy bilang isang cluster configuration. Nagbibigay-daan ito para sa higit pang butil na kontrol sa mga aspeto gaya ng latency at load balancing.

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 }}
    ]

Kapag gumagamit ng pagtuklas ng serbisyo STRICT_DNS Patuloy at asynchronous na lulutasin ng Envoy ang tinukoy na mga target ng DNS. Ang bawat ibinalik na IP address mula sa resulta ng DNS ay ituturing na isang tahasang host sa upstream cluster. Nangangahulugan ito na kung ang isang kahilingan ay magbabalik ng dalawang IP address, ipapalagay ni Envoy na mayroong dalawang host sa cluster, at pareho dapat na balanse ang pag-load. Kung aalisin ang isang host sa resulta, ipapalagay ni Envoy na wala na ito at hihilahin ang trapiko mula sa anumang umiiral na mga pool ng koneksyon.

Para sa karagdagang impormasyon tingnan Dokumentasyon ng envoy proxy.

Hakbang 6 β€” Pag-access sa Log at Mga Error

Ang huling pagsasaayos ay pagpaparehistro. Sa halip na itulak ang mga error log sa disk, ang Envoy Proxy ay gumagamit ng cloud-based na diskarte. Ang lahat ng mga log ng application ay output sa stdout ΠΈ stderr.

Kapag humiling ang mga user, opsyonal ang mga log ng access at hindi pinagana bilang default. Upang paganahin ang mga log ng pag-access para sa mga kahilingan sa HTTP, paganahin ang configuration access_log para sa HTTP connection manager. Ang landas ay maaaring alinman sa isang aparato tulad ng stdout, o isang file sa disk, depende sa iyong mga kinakailangan.

Ire-redirect ng sumusunod na configuration ang lahat ng access logs sa stdout (tala ng tagasalin - kailangan ng stdout na gumamit ng envoy sa loob ng docker. Kung ginamit nang walang docker, pagkatapos ay palitan ang /dev/stdout ng path sa isang regular na log file). Kopyahin ang snippet sa seksyon ng configuration para sa manager ng koneksyon:

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

Ang mga resulta ay dapat magmukhang ganito:

      - 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:

Bilang default, ang Envoy ay may format na string na kinabibilangan ng mga detalye ng kahilingan sa 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

Ang resulta ng string ng format na ito ay:

[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"

Maaaring ipasadya ang nilalaman ng output sa pamamagitan ng pagtatakda ng field ng format. Halimbawa:

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"

Ang linya ng log ay maaari ding maging output sa JSON na format sa pamamagitan ng pagtatakda ng field json_format. Halimbawa:

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

Para sa karagdagang impormasyon sa Paraan ng Pagpaparehistro ng Envoy, bisitahin ang

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

Ang pag-log ay hindi lamang ang paraan upang makakuha ng insight sa pagtatrabaho sa Envoy Proxy. Mayroon itong advanced na pagsubaybay at mga kakayahan sa sukatan na nakapaloob dito. Maaari mong malaman ang higit pa sa pagsubaybay sa dokumentasyon o sa pamamagitan ng Interactive na pagsubaybay sa script.

Hakbang 7 - Ilunsad

Nailipat mo na ngayon ang iyong configuration mula NGINX patungo sa Envoy Proxy. Ang huling hakbang ay ang maglunsad ng Envoy Proxy instance para subukan ito.

Patakbuhin bilang user

Sa tuktok ng linya ng pagsasaayos ng NGINX gumagamit www www; tumutukoy sa pagpapatakbo ng NGINX bilang isang user na may mababang pribilehiyo upang mapabuti ang seguridad.

Ang Envoy Proxy ay gumagamit ng cloud-based na diskarte sa pamamahala kung sino ang nagmamay-ari ng isang proseso. Kapag nagpatakbo kami ng Envoy Proxy sa pamamagitan ng isang container, maaari naming tukuyin ang isang mababang privileged na user.

Inilunsad ang Envoy Proxy

Ang command sa ibaba ay magpapatakbo ng Envoy Proxy sa pamamagitan ng isang Docker container sa host. Binibigyan ng command na ito si Envoy ng kakayahang makinig para sa mga papasok na kahilingan sa port 80. Gayunpaman, tulad ng tinukoy sa configuration ng listener, nakikinig ang Envoy Proxy para sa papasok na trapiko sa port 8080. Nagbibigay-daan ito sa proseso na tumakbo bilang isang user na may mababang pribilehiyo.

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

Pagsubok

Sa pagtakbo ng proxy, maaari na ngayong gawin at iproseso ang mga pagsubok. Ang sumusunod na utos ng cURL ay naglalabas ng isang kahilingan sa header ng host na tinukoy sa configuration ng proxy.

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

Ang kahilingan sa HTTP ay magreresulta sa isang error 503. Ito ay dahil ang mga upstream na koneksyon ay hindi gumagana at hindi magagamit. Samakatuwid, walang available na destinasyon ang Envoy Proxy para sa kahilingan. Ang sumusunod na command ay magsisimula ng isang serye ng mga serbisyo ng HTTP na tumutugma sa configuration na tinukoy para sa Envoy.

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

Gamit ang mga serbisyong magagamit, matagumpay na mai-proxy ng Envoy ang trapiko sa destinasyon nito.

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

Dapat kang makakita ng tugon na nagsasaad kung aling lalagyan ng Docker ang nagproseso ng kahilingan. Sa mga log ng Envoy Proxy dapat mo ring makita ang output ng access string.

Karagdagang HTTP Response Header

Makakakita ka ng mga karagdagang HTTP header sa mga header ng tugon ng aktwal na kahilingan. Ipinapakita ng header ang oras na ginugol ng upstream host sa pagproseso ng kahilingan. Ipinahayag sa millisecond. Ito ay kapaki-pakinabang kung gusto ng kliyente na matukoy ang oras ng serbisyo kumpara sa latency ng network.

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

Panghuling config

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 }

Karagdagang impormasyon mula sa tagasalin

Ang mga tagubilin para sa pag-install ng Envoy Proxy ay matatagpuan sa website https://www.getenvoy.io/

Bilang default, walang systemd service config ang rpm.

Magdagdag ng systemd service config /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

Kailangan mong gumawa ng direktoryo /etc/envoy/ at ilagay ang config.yaml config doon.

Mayroong telegrama chat gamit ang envoy proxy: https://t.me/envoyproxy_ru

Hindi sinusuportahan ng Envoy Proxy ang paghahatid ng static na nilalaman. Samakatuwid, sino ang maaaring bumoto para sa tampok na ito: https://github.com/envoyproxy/envoy/issues/378

Ang mga rehistradong user lamang ang maaaring lumahok sa survey. Mag-sign in, pakiusap

Hinihikayat ka ba ng post na ito na i-install at subukan ang envoy proxy?

  • oo

  • hindi

75 user ang bumoto. 18 na user ang umiwas.

Pinagmulan: www.habr.com

Magdagdag ng komento