Migració de Nginx a Envoy Proxy

Hola Habr! Aquí teniu la traducció del post: Migració de Nginx a Envoy Proxy.

Envoy és un servidor intermediari distribuït d'alt rendiment (escrit en C++) dissenyat per a serveis i aplicacions individuals, també és un bus de comunicació i un "pla de dades universal" dissenyat per a grans arquitectures de microserveis de "malla de servei". Quan es va crear, es van tenir en compte les solucions als problemes que van sorgir durant el desenvolupament de servidors com NGINX, HAProxy, equilibradors de càrrega de maquinari i equilibradors de càrrega del núvol. Envoy treballa conjuntament amb totes les aplicacions i resumeix la xarxa per proporcionar una funcionalitat comuna independentment de la plataforma. Quan tot el trànsit de serveis de la infraestructura passa per la graella d'Envoy, és fàcil visualitzar les àrees problemàtiques mitjançant una observabilitat constant, ajustant el rendiment general i afegint funcionalitats bàsiques en una ubicació específica.

Capacitats

  • Arquitectura fora de procés: l'envoy és un servidor autònom i d'alt rendiment que ocupa poca memòria RAM. Funciona conjuntament amb qualsevol llenguatge o marc d'aplicació.
  • Suport http/2 i grpc: l'envoy té un suport http/2 i grpc de primer nivell tant per a connexions entrants com sortints. És un servidor intermediari transparent de http/1.1 a http/2.
  • Equilibri de càrrega avançat: l'envoy admet funcions avançades d'equilibri de càrrega, com ara reintents automàtics, terminació de la cadena, limitació de la velocitat global, ombra de consultes, equilibri de càrrega local de zona, etc.
  • API de gestió de la configuració: l'envoy proporciona una API robusta per gestionar dinàmicament la seva configuració.
  • Observabilitat: observabilitat profunda del trànsit L7, suport integrat per al seguiment distribuït i observabilitat de mongodb, dynamodb i moltes altres aplicacions.

Pas 1: exemple de configuració de NGINX

Aquest script utilitza un fitxer especialment dissenyat nginx.conf, basat en l'exemple complet de Viqui. Podeu veure la configuració a l'editor obrint nginx.conf

Configuració inicial de 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;
    }
  }
}

Les configuracions de NGINX solen tenir tres elements clau:

  1. Configuració del servidor NGINX, l'estructura de registre i la funcionalitat Gzip. Això es defineix globalment en tots els casos.
  2. S'està configurant NGINX per acceptar sol·licituds a l'amfitrió one.example.com al port 8080.
  3. Configuració de la ubicació de destinació, com gestionar el trànsit de diferents parts de l'URL.

No tota la configuració s'aplicarà a l'Envoy Proxy i no cal que configureu alguns paràmetres. Envoy Proxy té quatre tipus de claus, que donen suport a la infraestructura subjacent que ofereix NGINX. El nucli és:

  • Oients: Determinen com Envoy Proxy accepta les sol·licituds entrants. Envoy Proxy actualment només admet els oients basats en TCP. Un cop establerta una connexió, es passa al conjunt de filtres per processar-la.
  • Filtres: Formen part d'una arquitectura de canalització que pot processar dades entrants i sortints. Aquesta funcionalitat inclou filtres com ara Gzip, que comprimeix les dades abans d'enviar-les al client.
  • Encaminadors: Redirigeixen el trànsit a la destinació desitjada, definit com a clúster.
  • Clústers: Defineixen el punt final per al trànsit i les opcions de configuració.

Utilitzarem aquests quatre components per crear una configuració d'Envoy Proxy que coincideixi amb una configuració específica de NGINX. L'objectiu d'Envoy és el treball de l'API i la configuració dinàmica. En aquest cas, la configuració base utilitzarà les opcions estàtiques i codificades de NGINX.

Pas 2: Configuració de NGINX

Primera part nginx.conf defineix alguns elements interns de NGINX que s'han de configurar.

Connexions dels treballadors

La configuració següent determina el nombre de processos de treball i connexions. Això indica com NGINX escalarà per satisfer la demanda.

worker_processes  2;

events {
  worker_connections   2000;
}

Envoy Proxy gestiona els fluxos de treball i les connexions de diferents maneres.

Envoy crea un fil de treball per a cada fil de maquinari del sistema. Cada fil de treball executa un bucle d'esdeveniments no bloquejador del qual és responsable

  1. Escoltar a cada oient (oient)
  2. Acceptació de noves connexions
  3. Creeu un conjunt de filtres per a una connexió
  4. Processament de totes les operacions d'E/S durant la vida útil de la connexió.

Tot el processament posterior de la connexió es gestiona completament al fil de treball, inclòs qualsevol comportament de reenviament.

Per a cada fil de treball a Envoy, hi ha una connexió a la piscina. Així, els grups de connexions HTTP/2 només estableixen una connexió per a cada host extern alhora, amb quatre fils de treball, hi haurà quatre connexions HTTP/2 per a cada host extern en un estat estable. En mantenir-ho tot en un sol fil de treball, gairebé tot el codi es pot escriure sense blocs com si fos d'un sol fil. Si s'assignen més fils de treball del necessari, això pot provocar un malbaratament de memòria, la creació d'un gran nombre de connexions inactives i la reducció del nombre de retorns de connexió a l'agrupació.

Per obtenir més informació, visiteu Bloc d'Envoy Proxy.

Configuració HTTP

El següent bloc de configuració NGINX defineix paràmetres HTTP com ara:

  • Quins tipus de mímica s'admeten
  • Temps d'espera predeterminats
  • Configuració Gzip

Podeu personalitzar aquests aspectes amb filtres a Envoy Proxy, dels quals parlarem més endavant.

Pas 3: Configuració del servidor

Al bloc de configuració HTTP, la configuració de NGINX especifica escoltar al port 8080 i respondre a les sol·licituds entrants de dominis one.example.com и www.one.example.com.

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

Dins d'Envoy, els oients ho gestionen.

Enviats oients

L'aspecte més important per començar amb Envoy Proxy és definir els oients. Heu de crear un fitxer de configuració que descrigui com voleu executar la instància d'Envoy.

El fragment següent crearà un oient nou i l'enllaçarà al port 8080. La configuració indica a Envoy Proxy a quins ports s'ha d'enllaçar per a les sol·licituds entrants.

Envoy Proxy utilitza la notació YAML per a la seva configuració. Per obtenir una introducció a aquesta notació, vegeu aquí enllaç.

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

No cal definir nom_servidor, ja que els filtres Envoy Proxy ho gestionaran.

Pas 4: Configuració de la ubicació

Quan arriba una sol·licitud a NGINX, el bloc d'ubicació determina com s'ha de gestionar i on s'adreça el trànsit. En el fragment següent, tot el trànsit al lloc es transfereix al clúster upstream (nota del traductor: upstream sol ser un servidor d'aplicacions) anomenat targetCluster. El clúster aigües amunt defineix els nodes que haurien de processar la sol·licitud. En parlarem d'això en el següent pas.

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

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

A Envoy, això és el que fa Filters.

Filtres Envoy

Per a una configuració estàtica, els filtres determinen com es processen les sol·licituds entrants. En aquest cas, establim filtres que coincideixen noms_servidor en el pas anterior. Quan arriben sol·licituds entrants que coincideixen amb determinats dominis i rutes, el trànsit s'encamina al clúster. Aquest és l'equivalent a la configuració amunt de 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

nom enviat.http_connection_manager és un filtre integrat a Envoy Proxy. Altres filtres inclouen Redis, mongo, TCP. Podeu trobar la llista completa a documentació.

Per obtenir més informació sobre altres polítiques d'equilibri de càrrega, visiteu Documentació enviada.

Pas 5: Configuració del servidor intermediari i aigües amunt

A NGINX, la configuració aigües amunt defineix un conjunt de servidors de destinació que processaran el trànsit. En aquest cas, s'han assignat dos clústers.

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

A Envoy això està gestionat per clústers.

Clústers enviats

L'equivalent aigües amunt es defineix com a clústers. En aquest cas, s'han definit els hosts que serviran el trànsit. Com s'accedeix als amfitrions, com ara el temps d'espera, es defineix com una configuració de clúster. Això permet un control més fi de la granularitat d'aspectes com ara la latència i l'equilibri de càrrega.

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

Quan utilitzeu el descobriment de serveis STRICT_DNS Envoy resoldrà de manera contínua i asíncrona els objectius DNS especificats. Cada adreça IP retornada del resultat DNS es considerarà un amfitrió explícit al clúster amunt. Això vol dir que si una consulta retorna dues adreces IP, Envoy assumirà que hi ha dos amfitrions al clúster i que tots dos haurien d'estar equilibrats de càrrega. Si s'elimina un amfitrió del resultat, Envoy assumeix que ja no existeix i extreu trànsit de les agrupacions de connexions existents.

Per obtenir més informació, vegeu Documentació de proxy d'enviament.

Pas 6: registre d'accés i errors

La configuració final és el registre. En lloc d'enviar els registres d'errors al disc, Envoy Proxy adopta un enfocament basat en núvol. Tots els registres de l'aplicació s'envien a stdout и stderr.

Quan els usuaris fan una sol·licitud, els registres d'accés són opcionals i estan desactivats per defecte. Per habilitar els registres d'accés per a les sol·licituds HTTP, activeu la configuració registre_accés per al gestor de connexions HTTP. El camí pot ser un dispositiu com ara stdout, o un fitxer al disc, segons els vostres requisits.

La configuració següent redirigirà tots els registres d'accés a stdout (Nota del traductor: stdout és necessari per utilitzar l'envoy dins del docker. Si s'utilitza sense docker, substituïu /dev/stdout pel camí del fitxer de registre habitual). Copieu el fragment a la secció de configuració del gestor de connexions:

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

Els resultats haurien de ser així:

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

De manera predeterminada, Envoy té una cadena de format que inclou els detalls de la sol·licitud 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

El resultat d'aquesta cadena de format és:

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

El contingut de sortida es pot personalitzar configurant el camp de format. Per exemple:

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"

La línia de registre també es pot sortir en format JSON configurant el camp json_format. Per exemple:

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

Per obtenir més informació sobre la metodologia de registre d'enviats, visiteu

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

El registre no és l'única manera de tenir una idea de treballar amb Envoy Proxy. Té un seguiment avançat i mètriques integrats. Podeu obtenir més informació a documentació de traça o per mitjà de Script d'encaminament interactiu.

Pas 7: llançament

Ara heu migrat la configuració de NGINX a Envoy Proxy. L'últim pas és llançar una instància d'Envoy Proxy per provar-la.

Executar com a usuari

A la part superior de la línia de configuració de NGINX usuari www www; indica que NGINX s'està executant com un usuari amb privilegis baixos per millorar la seguretat.

Envoy Proxy utilitza un enfocament basat en núvol per gestionar qui és el propietari d'un procés. Quan executem Envoy Proxy a través d'un contenidor, podem especificar un usuari amb privilegis baixos.

Executeu Envoy Proxy

L'ordre següent iniciarà Envoy Proxy a través d'un contenidor Docker a l'amfitrió. Aquesta ordre ofereix a l'Envoy la possibilitat d'escoltar les sol·licituds entrants al port 80. Tanmateix, tal com s'especifica a la configuració de l'escolta, l'Envoy Proxy escolta el trànsit entrant al port 8080. Això permet que el procés s'executi com a usuari amb privilegis baixos.

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

Proves

Amb el proxy en funcionament, ara es poden fer i processar proves. L'ordre cURL següent emet una sol·licitud amb la capçalera de l'amfitrió definida a la configuració del servidor intermediari.

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

La sol·licitud HTTP donarà lloc a un error 503. Això es deu al fet que les connexions amunt no funcionen i no estan disponibles. Per tant, Envoy Proxy no té destinacions disponibles per a la sol·licitud. L'ordre següent iniciarà una sèrie de serveis HTTP que coincideixen amb la configuració definida per a l'Envoy.

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

Amb els serveis disponibles, Envoy pot enviar el trànsit amb èxit a la seva destinació.

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

Hauríeu de veure una resposta que indiqui quin contenidor de Docker va gestionar la sol·licitud. Als registres d'Envoy Proxy, també hauríeu de veure la cadena d'accés impresa.

Capçaleres de resposta HTTP addicionals (resposta HTTP)

Veureu capçaleres HTTP addicionals a les capçaleres de resposta d'una sol·licitud vàlida. La capçalera mostra el temps que l'amfitrió amunt va passar processant la sol·licitud. Expressat en mil·lisegons. Això és útil si el client vol determinar el temps de servei versus la latència de la xarxa.

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

Configuració final

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 }

Informació addicional del traductor

Les instruccions per instal·lar Envoy Proxy es poden trobar al lloc web https://www.getenvoy.io/

De manera predeterminada, no hi ha cap configuració de servei systemd a rpm.

Afegiu la configuració del servei systemd a /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

Heu de crear el directori /etc/envoy/ i posar-hi la configuració config.yaml.

Hi ha un xat de telegrama per al proxy enviat: https://t.me/envoyproxy_ru

Envoy Proxy no admet la publicació de contingut estàtic. Per tant, qui pot votar per una funció: https://github.com/envoyproxy/envoy/issues/378

Només els usuaris registrats poden participar en l'enquesta. Inicia sessiósi us plau.

T'ha animat aquesta publicació a instal·lar i provar el proxy d'envoy?

  • нет

Han votat 75 usuaris. 18 usuaris es van abstenir.

Font: www.habr.com

Afegeix comentari