Migráció az Nginxről az Envoy Proxyra

Szia Habr! Figyelmébe ajánlom a bejegyzés fordítását: Migráció az Nginxről az Envoy Proxyra.

Az Envoy egy nagy teljesítményű elosztott proxyszerver (C++ nyelven írva), amelyet egyedi szolgáltatásokhoz és alkalmazásokhoz terveztek, valamint kommunikációs busz és "univerzális adatsík", amelyet nagy mikroszolgáltatási "service mesh" architektúrákhoz terveztek. Létrehozásakor figyelembe vették az olyan szerverek fejlesztése során felmerülő problémák megoldását, mint az NGINX, a HAProxy, a hardveres terheléselosztók és a felhőalapú terheléselosztók. Az Envoy az egyes alkalmazások mellett dolgozik, és absztrahálja a hálózatot, hogy platformtól függetlenül közös funkcionalitást biztosítson. Amikor egy infrastruktúra teljes szolgáltatási forgalma az Envoy hálón keresztül áramlik, könnyűvé válik a problémás területek következetes megfigyelhetőséggel történő megjelenítése, az általános teljesítmény hangolása és az alapvető funkciók hozzáadása egy adott helyen.

Képességek

  • Folyamaton kívüli architektúra: az envoy egy önálló, nagy teljesítményű szerver, amely kis mennyiségű RAM-ot foglal el. Bármilyen alkalmazásnyelvvel vagy keretrendszerrel együtt működik.
  • http/2 és grpc támogatás: az envoy első osztályú http/2 és grpc támogatással rendelkezik a bejövő és kimenő kapcsolatokhoz. Ez egy átlátszó proxy a http/1.1-től a http/2-ig.
  • Speciális terheléselosztás: az envoy támogatja a fejlett terheléselosztási funkciókat, beleértve az automatikus újrapróbálkozásokat, a lánctörést, a globális sebességkorlátozást, a kérés árnyékolását, a helyi zóna terheléselosztását stb.
  • Configuration Management API: Az envoy robusztus API-t biztosít a konfiguráció dinamikus kezeléséhez.
  • Megfigyelhetőség: Az L7 forgalom mély megfigyelhetősége, natív támogatás az elosztott nyomkövetéshez, valamint a mongodb, dynamodb és sok más alkalmazás megfigyelhetősége.

1. lépés – Példa NGINX Config

Ez a szkript egy speciálisan kialakított fájlt használ nginx.confszármazó teljes példa alapján NGINX Wiki. Megnyitva megtekintheti a konfigurációt a szerkesztőben nginx.conf

nginx forráskonfiguráció

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

Az NGINX konfigurációk általában három kulcselemből állnak:

  1. NGINX szerver, naplóstruktúra és Gzip funkciók konfigurálása. Ezt minden esetben globálisan határozzák meg.
  2. Az NGINX beállítása a gazdagéphez intézett kérések fogadására one.example.com a 8080-as porton.
  3. A célhely beállítása, az URL különböző részeihez tartozó forgalom kezelése.

Nem minden konfiguráció vonatkozik az Envoy Proxyra, és néhány beállítást nem kell konfigurálnia. Envoy Proxy rendelkezik négy kulcstípus, amelyek támogatják az NGINX által kínált alapvető infrastruktúrát. A mag a következő:

  • Hallgatók: Meghatározzák, hogy az Envoy Proxy hogyan fogadja el a bejövő kéréseket. Az Envoy Proxy jelenleg csak a TCP-alapú figyelőket támogatja. A kapcsolat létrejöttét követően a rendszer egy szűrőkészlethez kerül feldolgozásra.
  • Szűrők: A bejövő és kimenő adatok feldolgozására képes csővezeték-architektúra részét képezik. Ez a funkció olyan szűrőket tartalmaz, mint például a Gzip, amely tömöríti az adatokat, mielőtt elküldené azokat az ügyfélnek.
  • Routerek: Továbbítják a forgalmat a kívánt célhelyre, amely fürtként van definiálva.
  • Klaszterek: Meghatározzák a forgalmi és konfigurációs paraméterek végpontját.

Ezt a négy összetevőt fogjuk használni egy Envoy Proxy konfiguráció létrehozásához, amely megfelel egy adott NGINX konfigurációnak. Az Envoy célja, hogy API-kkal és dinamikus konfigurációval dolgozzon. Ebben az esetben az alapkonfiguráció az NGINX statikus, kódolt beállításait fogja használni.

2. lépés – NGINX konfiguráció

Első rész nginx.conf meghatároz néhány NGINX belsőt, amelyeket konfigurálni kell.

Munkavállalói kapcsolatok

Az alábbi konfiguráció határozza meg a dolgozói folyamatok és kapcsolatok számát. Ez azt jelzi, hogy az NGINX hogyan skálázódik a kereslet kielégítésére.

worker_processes  2;

events {
  worker_connections   2000;
}

Az Envoy Proxy különböző módokon kezeli a munkafolyamatokat és a kapcsolatokat.

Az Envoy létrehoz egy munkaszálat a rendszer minden hardverszálához. Minden munkaszál egy nem blokkoló eseményhurkot hajt végre, amelyért felelős

  1. Minden hallgató meghallgatása
  2. Új kapcsolatok elfogadása
  3. Szűrőkészlet létrehozása egy kapcsolathoz
  4. Az összes I/O művelet feldolgozása a kapcsolat élettartama alatt.

Minden további kapcsolatfeldolgozás teljes egészében a feldolgozói szálban történik, beleértve az esetleges továbbítási viselkedést is.

Az Envoy alkalmazásban minden egyes dolgozói szálhoz van kapcsolat a készletben. Tehát a HTTP/2 kapcsolatkészletek egyszerre csak egy kapcsolatot hoznak létre külső gazdagépenként, ha négy munkaszál van, akkor stabil állapotban négy HTTP/2 kapcsolat lesz külső gazdagépenként. Ha mindent egy munkaszálban tartunk, szinte az összes kód blokkolás nélkül írható, mintha egyszálú lenne. Ha a szükségesnél több worker szál van lefoglalva, az elvesztegetheti a memóriát, nagyszámú tétlen kapcsolatot hozhat létre, és csökkenti a kapcsolatok visszaküldésének számát a készletbe.

További információkért látogasson el Envoy Proxy blog.

HTTP konfiguráció

A következő NGINX konfigurációs blokk olyan HTTP-beállításokat határoz meg, mint például:

  • Milyen MIME típusok támogatottak
  • Alapértelmezett időtúllépések
  • Gzip konfiguráció

Ezeket a szempontokat testreszabhatja az Envoy Proxy szűrőivel, amelyeket később tárgyalunk.

3. lépés – Szerver konfigurálása

A HTTP konfigurációs blokkban az NGINX konfiguráció meghatározza, hogy a 8080-as porton figyeljen, és válaszoljon a tartományokra vonatkozó bejövő kérésekre one.example.com и www.one.example.com.

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

Az Envoyon belül a Listeners irányítja.

Küldj hallgatókat

Az Envoy Proxy használatának megkezdésének legfontosabb szempontja a hallgatók meghatározása. Létre kell hoznia egy konfigurációs fájlt, amely leírja, hogyan kívánja futtatni az Envoy példányt.

Az alábbi részlet létrehoz egy új figyelőt, és a 8080-as porthoz köti. A konfiguráció közli az Envoy Proxy-val, hogy mely portokhoz kell kapcsolódnia a bejövő kérésekhez.

Az Envoy Proxy YAML jelölést használ a konfigurációjához. A jelölés bevezetését itt találja link.

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

Nem kell meghatározni szerver név, mivel az Envoy Proxy szűrői kezelik ezt.

4. lépés – Hely konfigurálása

Amikor egy kérés érkezik az NGINX-be, a helyblokk határozza meg, hogyan kell feldolgozni és hova irányítani a forgalmat. A következő részletben a webhelyre irányuló teljes forgalom egy upstream (a fordító megjegyzése: az upstream általában egy alkalmazásszerver) nevű fürtbe kerül. célCluster. Az upstream fürt határozza meg azokat a csomópontokat, amelyeknek fel kell dolgozniuk a kérést. Ezt a következő lépésben megbeszéljük.

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

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

Az Envoynál a Filters ezt teszi.

Envoy szűrők

Statikus konfiguráció esetén a szűrők határozzák meg, hogyan kell feldolgozni a bejövő kéréseket. Ebben az esetben a megfelelő szűrőket állítjuk be szerver_nevek az előző lépésben. Amikor bizonyos tartományoknak és útvonalaknak megfelelő bejövő kérések érkeznek, a forgalom a fürtbe kerül. Ez az NGINX alulról felfelé történő konfigurációjának megfelelő.

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

név küldött.http_kapcsolatkezelő az Envoy Proxy beépített szűrője. Egyéb szűrők közé tartozik Feleinek, Mongo, TCP. A teljes listát a címen találja dokumentáció.

További információért az egyéb terheléselosztási szabályzatokról látogassa meg a webhelyet Küldött Dokumentáció.

5. lépés – Proxy és upstream konfiguráció

Az NGINX-ben az upstream konfiguráció meghatározza a célkiszolgálók készletét, amelyek feldolgozzák a forgalmat. Ebben az esetben két klaszter került hozzárendelésre.

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

Az Envoy-ban ezt klaszterek kezelik.

Envoy Klaszterek

Az upstream ekvivalens klaszterekként van definiálva. Ebben az esetben azonosították a forgalmat kiszolgáló gazdagépeket. A gazdagépek elérésének módja, például az időtúllépések, fürtkonfigurációként vannak meghatározva. Ez lehetővé teszi az olyan szempontok részletesebb szabályozását, mint a késleltetés és a terheléselosztás.

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

Szolgáltatásfelderítés használatakor STRICT_DNS Az Envoy folyamatosan és aszinkron módon feloldja a megadott DNS-célokat. A DNS-eredményből származó minden egyes visszaadott IP-cím explicit gazdagépnek minősül az upstream fürtben. Ez azt jelenti, hogy ha egy kérés két IP-címet ad vissza, az Envoy azt feltételezi, hogy két gazdagép van a fürtben, és mindkettőt terheléskiegyenlítettnek kell lennie. Ha egy gazdagép eltávolításra kerül az eredményből, az Envoy azt feltételezi, hogy az már nem létezik, és levonja a forgalmat a meglévő kapcsolatkészletekből.

További információért lásd Meghatalmazotti dokumentáció.

6. lépés – Hozzáférés és hibák naplózása

A végső konfiguráció a regisztráció. A hibanaplók lemezre küldése helyett az Envoy Proxy felhőalapú megközelítést alkalmaz. Az összes alkalmazásnapló a következőre kerül kiadásra: stdout и stderr.

Amikor a felhasználók kérelmet nyújtanak be, a hozzáférési naplók nem kötelezőek, és alapértelmezés szerint le vannak tiltva. A HTTP-kérések hozzáférési naplóinak engedélyezéséhez engedélyezze a konfigurációt hozzáférési_napló a HTTP kapcsolatkezelő számára. Az útvonal lehet akár egy eszköz, mint pl stdout, vagy egy fájl a lemezen, az Ön igényeitől függően.

A következő konfiguráció az összes hozzáférési naplót ide irányítja át stdout (a fordító megjegyzése – az stdout szükséges az envoy belső docker használatához. Ha docker nélkül használjuk, cserélje ki a /dev/stdout fájlt egy normál naplófájl elérési útjára). Másolja a kódrészletet a kapcsolatkezelő konfigurációs részébe:

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

Az eredményeknek így kell kinézniük:

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

Alapértelmezés szerint az Envoy rendelkezik egy formátum karakterlánccal, amely tartalmazza a HTTP-kérés részleteit:

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

A formátum karakterlánc eredménye:

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

A kimeneti tartalom testreszabható a formátum mező beállításával. Például:

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"

A naplósor JSON formátumban is kiadható a mező beállításával json_format. Például:

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

A Küldött regisztrációs módszertanával kapcsolatos további információkért látogasson el ide

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

A naplózás nem az egyetlen módja annak, hogy betekintést nyerjen az Envoy Proxyval való együttműködésbe. Fejlett nyomkövetési és mérési képességekkel rendelkezik. Többet megtudhat a címen nyomkövetési dokumentáció vagy azon keresztül Interaktív nyomkövetési szkript.

7. lépés – Indítsa el

Mostanra áttelepítette konfigurációját NGINX-ről Envoy Proxyra. Az utolsó lépés egy Envoy Proxy példány elindítása a teszteléshez.

Futtassa felhasználóként

Az NGINX konfigurációs sorának tetején felhasználó www www; meghatározza, hogy az NGINX alacsony jogosultságokkal rendelkező felhasználóként futtassa a biztonság javítása érdekében.

Az Envoy Proxy felhőalapú megközelítést alkalmaz a folyamat tulajdonosának kezeléséhez. Amikor egy tárolón keresztül futtatjuk az Envoy Proxyt, megadhatunk alacsony jogosultságokkal rendelkező felhasználót.

Envoy Proxy indítása

Az alábbi parancs az Envoy Proxyt futtatja egy Docker-tárolón keresztül a gazdagépen. Ez a parancs lehetővé teszi az Envoy számára, hogy figyelje a bejövő kéréseket a 80-as porton. A figyelő konfigurációjában meghatározottak szerint azonban az Envoy Proxy a 8080-as porton figyeli a bejövő forgalmat. Ez lehetővé teszi, hogy a folyamat alacsony jogosultságokkal rendelkező felhasználóként futhasson.

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

tesztelés

A proxy futása után tesztek készíthetők és dolgozhatók fel. A következő cURL parancs kérést ad ki a proxykonfigurációban definiált gazdagép fejléccel.

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

A HTTP-kérés hibát eredményez 503. Ennek az az oka, hogy az upstream kapcsolatok nem működnek, és nem elérhetők. Ezért az Envoy Proxy nem rendelkezik elérhető célállomásokkal a kérelemhez. A következő parancs olyan HTTP-szolgáltatások sorozatát indítja el, amelyek megfelelnek az Envoy számára meghatározott konfigurációnak.

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

Az elérhető szolgáltatásokkal az Envoy sikeresen proxy forgalmat küld a célállomásra.

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

Látnia kell egy választ, amely jelzi, hogy melyik Docker-tároló dolgozta fel a kérést. Az Envoy Proxy naplóiban is látnia kell egy hozzáférési karakterlánc kimenetet.

További HTTP-válaszfejlécek

További HTTP-fejléceket fog látni a tényleges kérés válaszfejlécében. A fejléc azt az időt jeleníti meg, amelyet az upstream gazdagép a kérés feldolgozásával töltött. Ezredmásodpercben kifejezve. Ez akkor hasznos, ha az ügyfél a hálózati késleltetéshez képest szeretné meghatározni a szolgáltatási időt.

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

Végső konfig

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 }

További információk a fordítótól

Az Envoy Proxy telepítésére vonatkozó utasítások megtalálhatók a weboldalon https://www.getenvoy.io/

Alapértelmezés szerint az rpm nem rendelkezik rendszerszolgáltatási konfigurációval.

Adja hozzá a systemd szolgáltatás konfigurációját /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

Létre kell hozni egy /etc/envoy/ könyvtárat, és oda kell tenni a config.yaml config-ot.

Van egy távirati csevegés küldött proxy használatával: https://t.me/envoyproxy_ru

Az Envoy Proxy nem támogatja a statikus tartalom kiszolgálását. Ezért ki szavazhat a funkcióra: https://github.com/envoyproxy/envoy/issues/378

A felmérésben csak regisztrált felhasználók vehetnek részt. Bejelentkezés, kérem.

Ez a bejegyzés arra ösztönözte Önt, hogy telepítse és tesztelje az envoy proxyt?

  • igen

  • nincs

75 felhasználó szavazott. 18 felhasználó tartózkodott.

Forrás: will.com

Hozzászólás