Ciao, Habr! Porto alla vostra attenzione la traduzione del post:
Envoy è un server proxy distribuito ad alte prestazioni (scritto in C++) progettato per singoli servizi e applicazioni, è anche un bus di comunicazione e un “piano dati universale” progettato per grandi architetture “service mesh” di microservizi. Durante la sua creazione, sono state prese in considerazione le soluzioni ai problemi sorti durante lo sviluppo di server come NGINX, HAProxy, bilanciatori di carico hardware e bilanciatori di carico cloud. Envoy funziona insieme a ciascuna applicazione ed astrae la rete per fornire funzionalità comuni indipendentemente dalla piattaforma. Quando tutto il traffico di servizio in un'infrastruttura scorre attraverso la rete mesh Envoy, diventa facile visualizzare le aree problematiche con osservabilità coerente, ottimizzare le prestazioni complessive e aggiungere funzionalità principali in una posizione specifica.
opportunità
- Architettura out-of-process: Envoy è un server autonomo e ad alte prestazioni che occupa una piccola quantità di RAM. Funziona insieme a qualsiasi linguaggio o framework dell'applicazione.
- Supporto http/2 e grpc: Envoy dispone di un supporto http/2 e grpc di prima classe per le connessioni in entrata e in uscita. Questo è un proxy trasparente da http/1.1 a http/2.
- Bilanciamento del carico avanzato: Envoy supporta funzionalità avanzate di bilanciamento del carico tra cui tentativi automatici, interruzione della catena, limitazione della velocità globale, shadowing delle richieste, bilanciamento del carico della zona locale, ecc.
- API di gestione della configurazione: Envoy fornisce una solida API per la gestione dinamica della configurazione.
- Osservabilità: osservabilità approfondita del traffico L7, supporto nativo per il tracciamento distribuito e osservabilità di mongodb, dynamodb e molte altre applicazioni.
Passaggio 1: esempio di configurazione NGINX
Questo script utilizza un file appositamente predisposto nginx.conf, basato sull'esempio completo di
Configurazione sorgente 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 NGINX hanno in genere tre elementi chiave:
- Configurazione del server NGINX, della struttura dei log e della funzionalità Gzip. Questo è definito globalmente in tutti i casi.
- Configurazione di NGINX per accettare richieste all'host one.esempio.com sulla porta 8080.
- Impostazione della posizione target, come gestire il traffico per le diverse parti dell'URL.
Non tutta la configurazione verrà applicata a Envoy Proxy e non è necessario configurare alcune impostazioni. Envoy Proxy ha quattro tipi di chiavi, che supportano l'infrastruttura principale offerta da NGINX. Il nucleo è:
- Ascoltatori: Determinano il modo in cui Envoy Proxy accetta le richieste in entrata. Envoy Proxy attualmente supporta solo ascoltatori basati su TCP. Una volta stabilita una connessione, viene passata a una serie di filtri per l'elaborazione.
- Filtri: Fanno parte di un'architettura di pipeline in grado di elaborare i dati in entrata e in uscita. Questa funzionalità include filtri come Gzip, che comprime i dati prima di inviarli al client.
- Router: Inoltrano il traffico alla destinazione richiesta, definita come cluster.
- Cluster: Definiscono l'endpoint per il traffico e i parametri di configurazione.
Utilizzeremo questi quattro componenti per creare una configurazione Envoy Proxy che corrisponda a una specifica configurazione NGINX. L'obiettivo di Envoy è lavorare con API e configurazione dinamica. In questo caso, la configurazione di base utilizzerà impostazioni statiche e codificate da NGINX.
Passaggio 2: configurazione NGINX
La prima parte nginx.conf definisce alcuni interni NGINX che devono essere configurati.
Collegamenti dei lavoratori
La configurazione seguente determina il numero di processi di lavoro e connessioni. Ciò indica come NGINX si ridimensionerà per soddisfare la domanda.
worker_processes 2;
events {
worker_connections 2000;
}
Envoy Proxy gestisce flussi di lavoro e connessioni in diversi modi.
Envoy crea un thread di lavoro per ogni thread hardware sul sistema. Ogni thread di lavoro esegue un ciclo di eventi non bloccante di cui è responsabile
- Ascoltare ogni ascoltatore
- Accettare nuove connessioni
- Creazione di una serie di filtri per una connessione
- Elabora tutte le operazioni di I/O durante la durata della connessione.
Tutta l'ulteriore elaborazione della connessione viene gestita interamente nel thread di lavoro, incluso qualsiasi comportamento di inoltro.
Per ogni thread di lavoro in Envoy esiste un pool di connessioni. Pertanto, i pool di connessioni HTTP/2 stabiliscono solo una connessione per host esterno alla volta, se sono presenti quattro thread di lavoro ci saranno quattro connessioni HTTP/2 per host esterno in uno stato stabile. Mantenendo tutto in un thread di lavoro, quasi tutto il codice può essere scritto senza blocchi, come se fosse a thread singolo. Se vengono allocati più thread di lavoro del necessario, ciò può comportare uno spreco di memoria, la creazione di un numero elevato di connessioni inattive e la riduzione del numero di volte in cui le connessioni vengono restituite al pool.
Per maggiori informazioni visita
Configurazione HTTP
Il seguente blocco di configurazione NGINX definisce le impostazioni HTTP come:
- Quali tipi MIME sono supportati
- Timeout predefiniti
- Configurazione Gzip
Puoi personalizzare questi aspetti utilizzando i filtri in Envoy Proxy, di cui parleremo più avanti.
Passaggio 3: configurazione del 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.esempio.com и www.one.example.com.
server {
listen 8080;
server_name one.example.com www.one.example.com;
All'interno di Envoy, è controllato dagli ascoltatori.
Inviato ascoltatori
L'aspetto più importante per iniziare con Envoy Proxy è definire i tuoi ascoltatori. È necessario creare un file di configurazione che descriva come si desidera eseguire l'istanza di Envoy.
Lo snippet seguente creerà un nuovo ascoltatore e lo collegherà alla porta 8080. La configurazione indica a Envoy Proxy a quali porte deve collegarsi per le richieste in entrata.
Envoy Proxy utilizza la notazione YAML per la sua configurazione. Per un'introduzione a questa notazione, guarda qui
Copy to Editorstatic_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }
Non c'è bisogno di definire nome del server, poiché i filtri Envoy Proxy gestiranno questo problema.
Passaggio 4: configurazione della posizione
Quando una richiesta arriva a NGINX, il blocco di posizione determina come elaborare e dove instradare il traffico. Nel frammento seguente, tutto il traffico verso il sito viene trasferito a un cluster upstream (nota del traduttore: upstream è solitamente un server delle applicazioni) denominato targetCluster. Il cluster upstream definisce i nodi che dovrebbero elaborare la richiesta. Ne discuteremo nel passaggio successivo.
location / {
proxy_pass http://targetCluster/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
In Envoy, Filters fa questo.
Filtri inviati
Per una configurazione statica, i filtri determinano come elaborare le richieste in entrata. In questo caso impostiamo i filtri che corrispondono nomi_server nel passaggio precedente. Quando arrivano richieste in entrata che corrispondono a determinati domini e percorsi, il traffico viene instradato al cluster. Questo è l’equivalente di una configurazione bottom-up di 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 inviato.http_connection_manager è un filtro integrato in Envoy Proxy. Altri filtri includono Redis, Mongo, TCP. Puoi trovare l'elenco completo su
Per ulteriori informazioni su altre policy di bilanciamento del carico, visitare
Passaggio 5: configurazione proxy e upstream
In NGINX, la configurazione upstream definisce un insieme di server di destinazione che elaboreranno 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 dai cluster.
Cluster di inviati
L'equivalente a monte è definito come cluster. In questo caso sono stati identificati gli host che serviranno il traffico. La modalità di accesso agli host, ad esempio i timeout, è definita come configurazione del cluster. Ciò consente un controllo più granulare su aspetti quali latenza e bilanciamento del carico.
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 }}
]
Quando si utilizza il rilevamento dei servizi RIGOROSAMENTE DNS Envoy risolverà in modo continuo e asincrono le destinazioni DNS specificate. Ogni indirizzo IP restituito dal risultato DNS verrà considerato un host esplicito nel cluster upstream. Ciò significa che se una richiesta restituisce due indirizzi IP, Envoy presuppone che siano presenti due host nel cluster ed entrambi devono avere un carico bilanciato. Se un host viene rimosso dal risultato, Envoy presuppone che non esista più e attirerà il traffico da eventuali pool di connessioni esistenti.
ля получения дополнительной информации см.
Passaggio 6: accesso ed errori di registro
La configurazione finale è la registrazione. Invece di inviare i log degli errori su disco, Envoy Proxy adotta un approccio basato su cloud. Tutti i registri dell'applicazione vengono inviati a stdout и 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, abilitare la configurazione registro_accesso per la gestione connessione HTTP. Il percorso può essere un dispositivo come stdouto un file su disco, a seconda delle vostre esigenze.
La seguente configurazione reindirizzerà tutti i log di accesso a stdout (nota del traduttore: per utilizzare Envoy all'interno della finestra mobile è necessario stdout. Se utilizzato senza finestra mobile, sostituire /dev/stdout con il percorso di un normale file di registro). Copia lo snippet nella sezione di configurazione per la gestione connessione:
Copy to Clipboardaccess_log:
- name: envoy.file_access_log
config:
path: "/dev/stdout"
I risultati dovrebbero assomigliare a questo:
- 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 i dettagli della 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 di output può essere personalizzato impostando il campo formato. Per 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 registro può anche essere emessa 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 di Envoy, visitare
La registrazione non è l'unico modo per ottenere informazioni dettagliate sull'utilizzo di Envoy Proxy. Dispone di funzionalità avanzate di tracciamento e metrica integrate. Puoi saperne di più su
Passaggio 7: avvio
Ora hai migrato la tua configurazione da NGINX a Envoy Proxy. L'ultimo passaggio consiste nell'avviare un'istanza di Envoy Proxy per testarla.
Esegui come utente
In cima alla linea di configurazione NGINX utentewwwwww; specifica di eseguire NGINX come utente con privilegi limitati per migliorare la sicurezza.
Envoy Proxy adotta un approccio basato sul cloud per gestire chi possiede un processo. Quando eseguiamo Envoy Proxy tramite un contenitore, possiamo specificare un utente con privilegi limitati.
Avvio di Envoy Proxy
Il comando seguente eseguirà Envoy Proxy tramite un contenitore Docker sull'host. Questo comando dà a Envoy la possibilità di ascoltare le richieste in entrata sulla porta 80. Tuttavia, come specificato nella configurazione del listener, Envoy Proxy ascolta il traffico in entrata sulla porta 8080. Ciò consente al processo di essere eseguito 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 possibile effettuare ed elaborare i 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 upstream non funzionano e non sono disponibili. Pertanto, Envoy Proxy non ha destinazioni disponibili per la richiesta. Il comando seguente 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 con successo il traffico verso la sua destinazione.
curl -H "Host: one.example.com" localhost -i
Dovresti vedere una risposta che indica quale contenitore Docker ha elaborato la richiesta. Nei registri di Envoy Proxy dovresti vedere anche l'output di una stringa di accesso.
Intestazioni di risposta HTTP aggiuntive
Vedrai intestazioni HTTP aggiuntive nelle intestazioni di risposta della richiesta effettiva. L'intestazione visualizza il tempo impiegato dall'host upstream nell'elaborazione della richiesta. Espresso in millisecondi. Ciò è utile se il client desidera determinare il tempo di servizio rispetto alla latenza di 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 }
Ulteriori informazioni dal traduttore
Le istruzioni per l'installazione di Envoy Proxy sono disponibili sul sito Web
Per impostazione predefinita, RPM non ha una configurazione del servizio systemd.
Aggiungi la configurazione del servizio 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
Devi creare una directory /etc/envoy/ e inserire lì la configurazione config.yaml.
Esiste una chat di Telegram utilizzando il proxy Envoy:
Envoy Proxy non supporta la fornitura di contenuto statico. Pertanto, chi può votare per la funzionalità:
Solo gli utenti registrati possono partecipare al sondaggio.
Questo post ti ha incoraggiato a installare e testare il proxy Envoy?
-
sì
-
no
75 utenti hanno votato. 18 utenti si sono astenuti.
Fonte: habr.com