Migrazione da Nginx a Envoy Proxy

Ciao, Habr! Vi presento la traduzione del post: Migrazione da Nginx a Envoy Proxy.

Envoy è un proxy distribuito ad alte prestazioni (scritto in C++), progettato per singoli servizi e applicazioni; è anche un bus di comunicazione e un "universal data plane" sviluppato per grandi architetture di microservizi "service mesh". Durante la sua creazione sono state considerate le soluzioni ai problemi che si presentavano nello sviluppo di server come NGINX, HAProxy, bilanciatori di carico hardware e bilanciatori di carico cloud. Envoy funziona insieme a ogni applicazione e astrae la rete, fornendo funzionalità comuni indipendentemente dalla piattaforma. Quando tutto il traffico di servizio nell'infrastruttura passa attraverso la rete Envoy, diventa facile visualizzare le aree problematiche grazie a un'osservabilità coerente, ottimizzando le prestazioni generali e aggiungendo funzionalità chiave in un determinato punto.

Capacità

  • Architettura fuori processo: envoy è un server autonomo ad alte prestazioni che occupa poca memoria. Funziona insieme a qualsiasi linguaggio di applicazione o framework.
  • Supporto http/2 e grpc: envoy offre un supporto di prim'ordine per http/2 e grpc per le connessioni in entrata e in uscita. Si tratta di un proxy trasparente da http/1.1 a http/2.
  • Bilanciamento del carico avanzato: envoy supporta funzionalità avanzate di bilanciamento del carico, incluse le ripetizioni automatiche, il circuit breaking, il throttling globale, lo shadowing delle richieste, il bilanciamento del carico locale per zona, ecc.
  • API per la gestione della configurazione: envoy fornisce un'API affidabile per la gestione dinamica della propria configurazione.
  • Osservabilità: osservabilità approfondita del traffico L7, supporto integrato per la tracciabilità distribuita e osservabilità per mongodb, dynamodb e molte altre applicazioni.

Passo 1 — Esempio di configurazione NGINX

In questo scenario, viene utilizzato un file appositamente creato nginx.conf, basato su un esempio completo da NGINX Wiki. Puoi visualizzare la configurazione nell'editor aprendo nginx.conf

La configurazione sorgente di 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;
    }
  }
}

Le configurazioni di NGINX solitamente hanno tre elementi chiave:

  1. Configurazione del server NGINX, struttura dei log e funzionalità Gzip. Questo è definito globalmente in tutti i casi.
  2. Configurazione di NGINX per ricevere richieste all'host one.example.com sulla porta 8080.
  3. Configurazione della posizione target, su come gestire il traffico per diverse parti dell'URL.

Non tutte le configurazioni si applicheranno a Envoy Proxy, e non è necessario configurare alcuni parametri. Envoy Proxy ha quattro tipi chiave, che supportano l'infrastruttura di base offerta da NGINX. Il nucleo è:

  • Ascoltatori: Definiscono come Envoy Proxy riceve le richieste in entrata. Attualmente, Envoy Proxy supporta solo listener basati su TCP. Una volta stabilita la connessione, viene trasmessa a un insieme di filtri per l'elaborazione.
  • Filtri: Fanno parte di un'architettura a pipeline in grado di gestire dati in entrata e in uscita. Questa funzionalità include filtri come Gzip, che comprime i dati prima di inviarli al client.
  • Router: Reindirizzano il traffico verso la destinazione richiesta, definita come cluster.
  • Cluster: Definiscono il punto finale per il traffico e i parametri di configurazione.

Utilizzeremo questi quattro componenti per creare la configurazione di Envoy Proxy in modo da conformarli a una specifica configurazione di NGINX. L'obiettivo di Envoy è lavorare con le API e la configurazione dinamica. In questo caso, la configurazione di base utilizzerà parametri statici e rigidi forniti da NGINX.

Passo 2 — Configurazione NGINX

Prima parte nginx.conf definisce alcuni componenti interni di NGINX che devono essere configurati.

Worker Connections

La configurazione sottostante definisce il numero di processi di lavoro e connessioni. Indica come NGINX scalerà per soddisfare la domanda.

worker_processes  2;

events {
  worker_connections   2000;
}

Envoy Proxy gestisce in modo diverso i processi di lavoro e le connessioni.

Envoy crea un flusso di lavoro per ogni thread hardware nel sistema. Ogni flusso di lavoro esegue un ciclo di eventi non bloccante, responsabile di

  1. Ascoltare ogni listener
  2. Accettare nuove connessioni
  3. Creare un insieme di filtri per la connessione
  4. Gestire tutte le operazioni di input/output durante la vita della connessione.

Tutta la successiva elaborazione della connessione è gestita interamente dal flusso di lavoro, compreso qualsiasi comportamento di reindirizzamento.

Per ogni thread di lavoro in Envoy esiste una connessione nel pool. Così, i pool di connessioni HTTP/2 stabiliscono solo una connessione per ogni host esterno alla volta; con quattro thread di lavoro, ci saranno quattro connessioni HTTP/2 per ogni host esterno in uno stato stabile. Mantenendo tutto in un solo thread di lavoro, quasi tutto il codice può essere scritto senza blocchi, come se fosse monothread. Se vengono allocati più thread di lavoro di quanto necessario, ciò può portare a un utilizzo inefficiente della memoria, alla creazione di un gran numero di connessioni inattive e a una riduzione del numero di riconnessioni nel pool.

Per ulteriori informazioni visita Blog di Envoy Proxy.

Configurazione HTTP

Il seguente blocco di configurazione NGINX definisce le impostazioni HTTP, come:

  • Quali tipi mime sono supportati
  • Timeout predefiniti
  • Configurazione Gzip

Puoi configurare questi aspetti utilizzando filtri in Envoy Proxy, che discuteremo più avanti.

Passo 3 — Configurazione Server

Nel blocco di configurazione HTTP, la configurazione NGINX specifica di ascoltare sulla porta 8080 e rispondere alle richieste in arrivo per i domini one.example.com e www.one.example.com.

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

All'interno di Envoy, questo è gestito dai listener.

Listener Envoy

L'aspetto più importante per iniziare a lavorare con Envoy Proxy è la definizione dei listener. Devi creare un file di configurazione che descriva come vuoi avviare un'istanza di Envoy.

Il frammento sottostante creerà un nuovo listener e lo collegherà alla porta 8080. La configurazione indica a Envoy Proxy a quali porte deve essere associato per le richieste in entrata.

Envoy Proxy utilizza la notazione YAML per la sua configurazione. Per familiarizzare con questa notazione, guarda qui. il link.

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

Non è necessario definire server_name, poiché i filtri di Envoy Proxy se ne occuperanno.

Passo 4 — Configurazione della posizione

Quando una richiesta arriva in NGINX, il blocco della posizione determina come elaborare e dove indirizzare il traffico. Nel seguente frammento, tutto il traffico verso il sito viene trasferito nel cluster upstream (nota del traduttore: upstream solitamente è costituito dai server delle applicazioni) chiamato targetCluster. Il cluster upstream determina quali nodi devono elaborare la richiesta. Ne discuteremo nel prossimo passo.

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

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

In Envoy, this is handled by Filters.

Envoy Filters

For static configuration, filters define how to handle incoming requests. In this case, we set filters that match server_names from the previous step. When incoming requests matching certain domains and routes arrive, traffic is directed to the cluster. This is equivalent to an upstream configuration in 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

Nome envoy.http_connection_manager is a built-in filter in Envoy Proxy. Other filters include Redis, Mongo, TCP. You can find the full list in documentazione.

For more information on other load balancing policies, visit the Envoy Documentation.

Step 5 — Proxy and Upstream Configuration

Nella configurazione NGINX, l'upstream definisce un insieme di server di destinazione che gestiranno il traffico. In questo caso, sono stati assegnati due cluster.

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

In Envoy, questo è gestito tramite cluster.

Cluster Envoy

L'equivalente dell'upstream è definito come cluster. In questo caso, sono stati definiti gli host che gestiranno il traffico. Il modo di accesso agli host, come ad esempio i timeout, è definito come configurazione del cluster. Questo consente un controllo più preciso su aspetti come i timeout e il bilanciamento del carico.

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

Utilizzando il rilevamento dei servizi STRICT_DNS Envoy risolverà continuamente e in modo asincrono gli obiettivi DNS specificati. Ogni indirizzo IP restituito come risultato della risoluzione DNS verrà considerato un host esplicito nel cluster ascendete. Ciò significa che se una richiesta restituisce due indirizzi IP, Envoy presumerà che ci siano due host nel cluster e entrambi saranno bilanciati per carico. Se un host viene rimosso dal risultato, Envoy presume che non esista più e inizierà a deviare il traffico da qualsiasi pool di connessioni esistente.

Per ulteriori informazioni consulta. La documentazione di Envoy Proxy.

Passo 6 — Accesso ai log e errori

Configurazione finale — registrazione. Invece di scrivere i log degli errori su disco, Envoy Proxy utilizza un approccio cloud. Tutti i log delle applicazioni vengono scritti in stdout e stderr.

Quando gli utenti effettuano una richiesta, i log di accesso sono facoltativi e disabilitati per impostazione predefinita. Per abilitare i log di accesso per le richieste HTTP, attiva la configurazione access_log per il dispatcher delle connessioni HTTP. Il percorso può essere o un dispositivo, come stdout, o un file su disco, a seconda delle tue esigenze.

La seguente configurazione reindirizzerà tutti i log degli accessi a stdout (nota del traduttore — stdout è necessario per utilizzare envoy all'interno di docker. Se si utilizza senza docker, sostituisci /dev/stdout con il percorso di un normale file di log). Copia il frammento nella sezione di configurazione per il gestore delle connessioni:

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

I risultati dovrebbero apparire così:

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

Per impostazione predefinita, Envoy ha una stringa di formato che include dettagli sulla richiesta 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

Il risultato di questa stringa di formato:

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

Il contenuto dell'output può essere personalizzato impostando il campo formato. Ad esempio:

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 riga di log può essere anche esportata in formato JSON impostando il campo json_format. Ad esempio:

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

Per ulteriori informazioni sulla metodologia di registrazione del proxy, visita

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

La registrazione non è l'unico modo per ottenere una visione del funzionamento di Envoy Proxy. Sono integrate funzionalità avanzate di tracciamento e metriche. Puoi saperne di più nella documentazione sul tracciamento oppure tramite Lo script di tracciamento interattivo.

Passaggio 7 — Avvio

Ora hai tradotto la configurazione da NGINX a Envoy Proxy. L'ultimo passo è avviare un'istanza di Envoy Proxy per testarla.

Esecuzione come utente

In cima alla configurazione NGINX, la riga user www www; indica che NGINX viene eseguito come utente con privilegi ridotti per una maggiore sicurezza.

Envoy Proxy utilizza un approccio basato sul cloud per gestire chi è proprietario del processo. Quando eseguiamo Envoy Proxy tramite un contenitore, possiamo specificare un utente con privilegi bassi.

Avvio di Envoy Proxy

Il comando qui sotto avvierà Envoy Proxy all'interno di un container Docker sull'host. Questo comando consente a Envoy di ascoltare le richieste in ingresso sulla porta 80. Tuttavia, come specificato nella configurazione del listener, Envoy Proxy ascolta il traffico in ingresso sulla porta 8080. Ciò consente al processo di avviarsi come utente con privilegi limitati.

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

Test

Con il proxy in esecuzione, ora possono essere effettuati e gestiti dei test. Il seguente comando cURL invia una richiesta con l'intestazione Host definita nella configurazione del proxy.

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

La richiesta HTTP genererà un errore 503. Questo perché le connessioni ascendenti non sono funzionanti e non sono disponibili. Pertanto, Envoy Proxy non ha destinatari disponibili per la richiesta. Il seguente comando avvierà una serie di servizi HTTP che corrispondono alla configurazione definita per Envoy.

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

Con i servizi disponibili, Envoy può inoltrare correttamente il traffico verso la destinazione.

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

Dovresti vedere una risposta che indica quale container Docker ha gestito la richiesta. Nei log di Envoy Proxy dovresti anche vedere la riga di accesso generata.

Intestazioni HTTP aggiuntive della risposta (HTTP Response)

Nelle intestazioni della risposta della richiesta valida, vedrai intestazioni HTTP aggiuntive. L'intestazione mostra il tempo impiegato dall'host upstream per elaborare la richiesta. È espresso in millisecondi. Questo è utile se il client vuole determinare il tempo di elaborazione rispetto alla latenza in rete.

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

Configurazione finale

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 }

Informazioni aggiuntive dal traduttore

Puoi trovare le istruzioni per l'installazione di Envoy Proxy sul sito web https://www.getenvoy.io/

Per impostazione predefinita, il pacchetto rpm non include la configurazione per il servizio systemd.

Aggiungi la configurazione del servizio 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

Devi creare la directory /etc/envoy/ e posizionare all'interno il file di configurazione config.yaml.

Esiste un chat su Telegram per envoy proxy: https://t.me/envoyproxy_ru

Envoy Proxy non supporta la distribuzione di contenuti statici. Quindi chi può voti per questa funzione: https://github.com/envoyproxy/envoy/issues/378

Solo gli utenti registrati possono partecipare al sondaggio. Accedi, per favore.

Ti ha ispirato questo post a installare e testare Envoy Proxy?

  • no

75 utenti hanno votato. 18 utenti si sono astenuti.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster