Ciao, Habr! Vi presento la traduzione del post: .
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 . 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:
- Configurazione del server NGINX, struttura dei log e funzionalità Gzip. Questo è definito globalmente in tutti i casi.
- Configurazione di NGINX per ricevere richieste all'host one.example.com sulla porta 8080.
- 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
- Ascoltare ogni listener
- Accettare nuove connessioni
- Creare un insieme di filtri per la connessione
- 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 .
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. .
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.routerNome 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 .
For more information on other load balancing policies, visit .
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. .
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%"nIl 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
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 oppure tramite .
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/envoyTest
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 -iLa 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 -iDovresti 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: envoyConfigurazione 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
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.targetDevi creare la directory /etc/envoy/ e posizionare all'interno il file di configurazione config.yaml.
Esiste un chat su Telegram per envoy proxy:
Envoy Proxy non supporta la distribuzione di contenuti statici. Quindi chi può voti per questa funzione:
Solo gli utenti registrati possono partecipare al sondaggio. , per favore.
Ti ha ispirato questo post a installare e testare Envoy Proxy?
sì
no
75 utenti hanno votato. 18 utenti si sono astenuti.
Fonte: habr.com
