Migracija sa Nginxa na Envoy proxy

Hej Habr! Evo prijevoda posta: Migracija sa Nginxa na Envoy proxy.

Envoy je distribuirani proxy server visokih performansi (napisan na C++) dizajniran za pojedinačne usluge i aplikacije, također je komunikaciona magistrala i "univerzalna podatkovna ravan" dizajnirana za velike "servisne mreže" mikroservisne arhitekture. Prilikom njegovog kreiranja uzeta su u obzir rješenja problema koji su nastali tokom razvoja servera kao što su NGINX, HAProxy, hardverski balanseri opterećenja i balanseri opterećenja u oblaku. Envoy radi zajedno sa svakom aplikacijom i apstrahuje mrežu kako bi pružio zajedničku funkcionalnost bez obzira na platformu. Kada sav promet usluga u infrastrukturi prođe kroz Envoy mrežu, postaje lako vizualizirati problematična područja kroz dosljednu vidljivost, podešavanje ukupnih performansi i dodavanje osnovne funkcionalnosti na određenoj lokaciji.

Karakteristike

  • Arhitektura izvan procesa: envoy je samostalni server visokih performansi koji zauzima malo RAM-a. Radi u sprezi sa bilo kojim aplikacijskim jezikom ili okvirom.
  • http/2 i grpc podrška: envoy ima vrhunsku http/2 i grpc podršku za dolazne i odlazne veze. To je transparentni proxy od http/1.1 do http/2.
  • Napredno balansiranje opterećenja: envoy podržava napredne funkcije balansiranja opterećenja, uključujući automatske ponovne pokušaje, prekid lanca, globalno ograničenje brzine, sjenčanje upita, zonsko lokalno balansiranje opterećenja itd.
  • API za upravljanje konfiguracijom: envoy pruža robustan API za dinamičko upravljanje njegovom konfiguracijom.
  • Opservabilnost: Duboka uočljivost L7 saobraćaja, izvorna podrška za distribuirano praćenje i vidljivost mongodb, dynamodb i mnogih drugih aplikacija.

Korak 1 — Primjer NGINX konfiguracije

Ova skripta koristi posebno kreiranu datoteku nginx.conf, na osnovu kompletnog primjera iz Wiki. Možete pogledati konfiguraciju u uređivaču otvaranjem nginx.conf

Početna nginx konfiguracija

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

NGINX konfiguracije obično imaju tri ključna elementa:

  1. Postavljanje NGINX servera, strukture evidentiranja i Gzip funkcionalnosti. Ovo je globalno definisano u svim slučajevima.
  2. Konfiguriranje NGINX-a za prihvatanje zahtjeva hostu one.example.com na portu 8080.
  3. Postavljanje ciljane lokacije, kako upravljati prometom za različite dijelove URL-a.

Neće se sva konfiguracija primijeniti na Envoy proxy i ne morate konfigurirati neke postavke. Izaslanik Proxy ima četiri ključna tipa, koji podržavaju osnovnu infrastrukturu koju nudi NGINX. Kernel je:

  • Slušaoci: Oni određuju kako Envoy Proxy prihvata dolazne zahtjeve. Envoy Proxy trenutno podržava samo slušaoce zasnovane na TCP-u. Jednom kada je veza uspostavljena, ona se prosljeđuje u set filtera na obradu.
  • Filteri: Oni su dio arhitekture cjevovoda koja može obraditi dolazne i odlazne podatke. Ova funkcionalnost uključuje filtere kao što je Gzip, koji komprimira podatke prije nego što ih pošalje klijentu.
  • ruteri: Preusmjeravaju promet na željeno odredište, definirano kao klaster.
  • Klasteri: Oni definiraju krajnju točku za promet i opcije konfiguracije.

Koristićemo ove četiri komponente da kreiramo Envoy proxy konfiguraciju koja odgovara specifičnoj NGINX konfiguraciji. Svrha Envoya je API rad i dinamička konfiguracija. U ovom slučaju, osnovna konfiguracija će koristiti statičke, tvrdo kodirane opcije iz NGINX-a.

Korak 2 — NGINX konfiguracija

Prvi dio nginx.conf definira neke NGINX interne elemente koji se moraju konfigurirati.

Worker Connections

Konfiguracija u nastavku određuje broj radnih procesa i veza. Ovo pokazuje kako će se NGINX skalirati da zadovolji potražnju.

worker_processes  2;

events {
  worker_connections   2000;
}

Envoy Proxy upravlja tokovima posla i vezama na različite načine.

Envoy kreira radnu nit za svaku hardversku nit u sistemu. Svaka radna nit izvršava neblokirajuću petlju događaja za koju je odgovorna

  1. Slušanje svakog slušaoca (slušatelja)
  2. Prihvatanje novih veza
  3. Kreirajte set filtera za vezu
  4. Obrada svih I/O operacija tokom životnog veka veze.

Sva daljnja obrada veze se u potpunosti obrađuje u radnoj niti, uključujući svako ponašanje prosljeđivanja.

Za svaku radničku nit u Envoyu postoji veza u spremištu. Dakle, HTTP/2 skupovi veza uspostavljaju samo jednu vezu za svaki eksterni host u isto vreme, sa četiri radne niti, postojaće četiri HTTP/2 veze za svaki eksterni host u stabilnom stanju. Držeći sve na jednoj radnoj niti, gotovo sav kod se može napisati bez blokova kao da je jednonit. Ako se dodijeli više radnih niti nego što je potrebno, to može rezultirati gubitkom memorije, stvaranjem velikog broja neaktivnih veza i smanjenjem broja vraćanja veza natrag u spremište.

Za dobijanje dodatnih informacija posjetite web stranicu Envoy Proxy blog.

HTTP konfiguracija

Sljedeći blok NGINX konfiguracije definira HTTP postavke kao što su:

  • Koji su mimi tipovi podržani
  • Default timeouts
  • Gzip konfiguracija

Ove aspekte možete prilagoditi pomoću filtera u Envoy proxyju, o čemu ćemo kasnije raspravljati.

Korak 3 — Konfiguracija servera

U bloku HTTP konfiguracije, NGINX konfiguracija specificira slušanje porta 8080 i odgovaranje na dolazne zahtjeve za domene one.example.com и www.one.example.com.

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

Unutar Envoy-a, Slušatelji to upravljaju.

Poslanici slušaoci

Najvažniji aspekt početka rada sa Envoy proxyjem je definiranje slušalaca. Morate kreirati konfiguracijsku datoteku koja opisuje kako želite pokrenuti Envoy instancu.

Isječak ispod će kreirati novog slušaoca i vezati ga za port 8080. Konfiguracija govori Envoy Proxy-u na koje portove bi trebao biti vezan za dolazne zahtjeve.

Envoy Proxy koristi YAML notaciju za svoju konfiguraciju. Za uvod u ovu notaciju, pogledajte ovdje link.

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

Nema potrebe da se definiše server_name, jer će Envoy proxy filteri to riješiti.

Korak 4 — Konfiguracija lokacije

Kada zahtjev stigne u NGINX, lokacijski blok određuje kako će se rukovati i kamo usmjeriti promet. U sljedećem fragmentu, sav promet na web-stranici se prenosi u uzvodni (napomena prevodioca: uzvodni je obično aplikacijski server) klaster pod nazivom targetCluster. Uzvodni klaster definira čvorove koji bi trebali obraditi zahtjev. O tome ćemo razgovarati u sljedećem koraku.

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

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

U Envoyu ovo radi Filters.

Filteri za poslanike

Za statičku konfiguraciju, filteri određuju kako se obrađuju dolazni zahtjevi. U ovom slučaju postavljamo filtere koji odgovaraju server_name u prethodnom koraku. Kada dolaze dolazni zahtjevi koji odgovaraju određenim domenama i rutama, promet se usmjerava na klaster. Ovo je ekvivalent NGINX upstream konfiguraciji.

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

ime envoy.http_connection_manager je ugrađeni filter u Envoy Proxy. Ostali filteri uključuju Redis, Mongo, TCP. Kompletnu listu možete pronaći na dokumentaciju.

Za više informacija o drugim politikama balansiranja opterećenja, posjetite Dokumentacija izaslanika.

Korak 5 - Proxy i Upstream konfiguracija

U NGINX-u, uzvodna konfiguracija definira skup ciljnih servera koji će obraditi promet. U ovom slučaju su dodijeljena dva klastera.

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

U Envoyu ovim upravljaju klasteri.

Envoy Clusters

Uzvodni ekvivalent je definiran kao klasteri. U ovom slučaju su definirani hostovi koji će opsluživati ​​promet. Način na koji se pristupa hostovima, kao što je timeout, definira se kao konfiguracija klastera. Ovo omogućava finiju kontrolu nad granularnošću aspekata kao što su kašnjenje i balansiranje opterećenja.

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

Kada koristite otkrivanje usluge STRICT_DNS Izaslanik će kontinuirano i asinhrono rješavati navedene DNS ciljeve. Svaka vraćena IP adresa iz DNS rezultata će se smatrati eksplicitnim hostom u uzvodnom klasteru. To znači da ako upit vrati dvije IP adrese, Envoy će pretpostaviti da postoje dva hosta u klasteru i oba treba da budu uravnotežena opterećenja. Ako se host ukloni iz rezultata, Envoy pretpostavlja da on više ne postoji i povući će promet iz svih postojećih skupova veza.

Za više informacija pogledajte Proxy dokumentacija izaslanika.

Korak 6 — Pristup evidenciji i greške

Konačna konfiguracija je registracija. Umjesto guranja evidencije grešaka na disk, Envoy Proxy koristi pristup baziran na oblaku. Svi zapisnici aplikacije se izlaze na stdout и stderr.

Kada korisnici podnose zahtjev, evidencije pristupa su opcione i onemogućene prema zadanim postavkama. Da biste omogućili evidenciju pristupa za HTTP zahtjeve, omogućite konfiguraciju access_log za upravitelja HTTP veze. Put može biti uređaj kao što je stdout, ili datoteku na disku, ovisno o vašim zahtjevima.

Sljedeća konfiguracija će preusmjeriti sve evidencije pristupa na stdout (napomena prevodioca - stdout je neophodan za korištenje izaslanika unutar docker-a. Ako se koristi bez docker-a, zamijenite /dev/stdout putanjom do uobičajene datoteke dnevnika). Kopirajte isječak u odjeljak za konfiguraciju za upravitelja veze:

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

Rezultati bi trebali izgledati ovako:

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

Po defaultu, Envoy ima niz formata koji uključuje detalje HTTP zahtjeva:

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

Rezultat ovog formatnog niza je:

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

Izlazni sadržaj se može prilagoditi postavljanjem polja za format. Na primjer:

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"

Linija dnevnika se također može izvesti u JSON formatu postavljanjem polja json_format. Na primjer:

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

Za više informacija o metodologiji registracije izaslanika, posjetite

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

Evidentiranje nije jedini način da dobijete osjećaj za rad sa Envoy proxyjem. Ima ugrađeno napredno praćenje i metriku. Više možete saznati na dokumentacija u tragovima ili kroz Interaktivna skripta za rutiranje.

Korak 7 - Pokrenite

Sada ste migrirali konfiguraciju sa NGINX na Envoy proxy. Posljednji korak je pokretanje Envoy proxy instance da biste je testirali.

Pokreni kao korisnik

Na vrhu konfiguracijske linije NGINX korisnik www www; označava da NGINX radi kao korisnik s niskim privilegijama radi poboljšanja sigurnosti.

Envoy Proxy ima pristup zasnovan na oblaku za upravljanje vlasništvom procesa. Kada pokrenemo Envoy Proxy kroz kontejner, možemo odrediti korisnika s niskim privilegijama.

Pokrenite Envoy proxy

Naredba u nastavku će pokrenuti Envoy Proxy kroz Docker kontejner na hostu. Ova komanda daje Envoyju mogućnost da sluša dolazne zahtjeve na portu 80. Međutim, kao što je navedeno u konfiguraciji slušatelja, Envoy Proxy osluškuje dolazni promet na portu 8080. Ovo omogućava da se proces pokrene kao korisnik sa niskim privilegijama.

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

Testiranje

Kada je proxy pokrenut, testovi se sada mogu praviti i obraditi. Sljedeća naredba cURL izdaje zahtjev sa zaglavljem hosta definiranim u proxy konfiguraciji.

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

HTTP zahtjev će rezultirati greškom 503. To je zato što uzvodne veze ne rade i nisu dostupne. Dakle, proxy poslanika nema dostupnih ciljnih odredišta za zahtjev. Sljedeća naredba će pokrenuti niz HTTP usluga koje odgovaraju konfiguraciji definiranoj za Envoy.

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

Uz dostupne usluge, Envoy može uspješno proksirirati promet do svog odredišta.

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

Trebali biste vidjeti odgovor koji pokazuje koji je Docker kontejner obradio zahtjev. U zapisnicima proxy poslanika trebalo bi da vidite i odštampan pristupni niz.

Dodatna zaglavlja HTTP odgovora (HTTP odgovor)

Vidjet ćete dodatna HTTP zaglavlja u zaglavljima odgovora važećeg zahtjeva. Zaglavlje prikazuje vrijeme koje je upstream host proveo obrađujući zahtjev. Izraženo u milisekundama. Ovo je korisno ako klijent želi odrediti vrijeme usluge u odnosu na kašnjenje mreže.

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

Konačna konfiguracija

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 }

Dodatne informacije od prevodioca

Upute za instaliranje Envoy proxyja možete pronaći na web stranici https://www.getenvoy.io/

Podrazumevano nema konfiguracije systemd servisa u rpm.

Dodajte systemd konfiguraciju usluge u /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

Morate kreirati /etc/envoy/ direktorij i tamo staviti config.yaml konfiguraciju.

Postoji telegram chat za proxy izaslanika: https://t.me/envoyproxy_ru

Envoy Proxy ne podržava posluživanje statičkog sadržaja. Dakle, ko može glasati za funkciju: https://github.com/envoyproxy/envoy/issues/378

Samo registrovani korisnici mogu učestvovati u anketi. Prijavite semolim.

Da li vas je ova objava ohrabrila da instalirate i testirate envoy proxy?

  • da

  • ne

Glasalo je 75 korisnika. Uzdržano je bilo 18 korisnika.

izvor: www.habr.com

Dodajte komentar