Мигриране от Nginx към Envoy Proxy

Хей Хабр! Ето превод на поста: Мигриране от Nginx към Envoy Proxy.

Envoy е високопроизводителен разпределен прокси сървър (написан на C++), предназначен за индивидуални услуги и приложения, той също е комуникационна шина и „универсална равнина на данни“, предназначена за големи архитектури на микросервизи на „сервизна мрежа“. При създаването му бяха взети предвид решенията на проблемите, възникнали по време на разработката на сървъри като NGINX, HAProxy, хардуерни балансьори на натоварването и облачни балансьори на натоварването. Envoy работи заедно с всяко приложение и абстрахира мрежата, за да осигури обща функционалност, независимо от платформата. Когато целият обслужващ трафик в инфраструктурата преминава през мрежата на Envoy, става лесно да се визуализират проблемните области чрез последователна видимост, настройка на цялостната производителност и добавяне на основна функционалност в конкретно местоположение.

Възможности

  • Архитектура извън процеса: envoy е самостоятелен, високопроизводителен сървър, който заема малко RAM. Работи във връзка с всеки език на приложение или рамка.
  • Поддръжка на http/2 и grpc: envoy има първокласна поддръжка на http/2 и grpc както за входящи, така и за изходящи връзки. Това е прозрачен прокси от http/1.1 до http/2.
  • Разширено балансиране на натоварването: envoy поддържа разширени функции за балансиране на натоварването, включително автоматични повторни опити, прекратяване на веригата, глобално ограничаване на скоростта, засенчване на заявки, балансиране на локално натоварване в зоната и т.н.
  • API за управление на конфигурацията: envoy предоставя стабилен API за динамично управление на своята конфигурация.
  • Наблюдаемост: Дълбока наблюдаемост на L7 трафик, вградена поддръжка за разпределено проследяване и наблюдаемост на mongodb, dynamodb и много други приложения.

Стъпка 1 — Пример за конфигурация на NGINX

Този скрипт използва специално създаден файл nginx.conf, въз основа на пълния пример от Wiki. Можете да видите конфигурацията в редактора, като отворите nginx.conf

Първоначална конфигурация на 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;
    }
  }
}

Конфигурациите на NGINX обикновено имат три ключови елемента:

  1. Настройване на NGINX сървъра, структура за регистриране и Gzip функционалност. Това се определя глобално във всички случаи.
  2. Конфигуриране на NGINX да приема заявки към хоста one.example.com на порт 8080.
  3. Настройка на целево местоположение, как да се справя с трафика за различни части от URL адреса.

Не всички конфигурации ще се прилагат за Envoy Proxy и не е необходимо да конфигурирате някои настройки. Envoy Proxy има четири ключови типа, които поддържат основната инфраструктура, предлагана от NGINX. Ядрото е:

  • Слушатели: Те определят как Envoy Proxy приема входящи заявки. Понастоящем Envoy Proxy поддържа само TCP-базирани слушатели. След като се установи връзка, тя се предава на филтърния набор за обработка.
  • Филтри: Те са част от конвейерна архитектура, която може да обработва входящи и изходящи данни. Тази функционалност включва филтри като Gzip, който компресира данни, преди да ги изпрати на клиента.
  • Рутери: Те пренасочват трафика към желаната дестинация, определена като клъстер.
  • Клъстери: Те определят крайната точка за трафик и опции за конфигурация.

Ще използваме тези четири компонента, за да създадем конфигурация на Envoy Proxy, която да съответства на конкретна конфигурация на NGINX. Целта на Envoy е работа с API и динамична конфигурация. В този случай основната конфигурация ще използва статичните, твърдо кодирани опции от NGINX.

Стъпка 2 — Конфигуриране на NGINX

Първата част nginx.conf дефинира някои вътрешни елементи на NGINX, които трябва да бъдат конфигурирани.

Работнически връзки

Конфигурацията по-долу определя броя на работните процеси и връзки. Това показва как NGINX ще се мащабира, за да отговори на търсенето.

worker_processes  2;

events {
  worker_connections   2000;
}

Envoy Proxy управлява работни процеси и връзки по различни начини.

Envoy създава работна нишка за всяка хардуерна нишка в системата. Всяка работна нишка изпълнява неблокиращ цикъл на събития, който отговаря за

  1. Слушане на всеки слушател (слушател)
  2. Приемане на нови връзки
  3. Създайте набор от филтри за връзка
  4. Обработка на всички I/O операции по време на живота на връзката.

Цялата по-нататъшна обработка на връзката се обработва изцяло в работната нишка, включително всяко поведение при пренасочване.

За всяка работна нишка в Envoy има връзка в пула. Така че пуловете за HTTP/2 връзки установяват само една връзка за всеки външен хост наведнъж, с четири работни нишки ще има четири HTTP/2 връзки за всеки външен хост в стабилно състояние. Като държи всичко в една работна нишка, почти целият код може да бъде написан без блокове, сякаш е еднонишков. Ако са разпределени повече работни нишки от необходимото, това може да доведе до загуба на памет, създаване на голям брой неактивни връзки и намаляване на броя на връщанията на връзки обратно към пула.

За повече информация посетете Блог на Envoy Proxy.

HTTP конфигурация

Следният конфигурационен блок на NGINX дефинира HTTP настройки като:

  • Кои типове mime се поддържат
  • Изчаквания по подразбиране
  • Gzip конфигурация

Можете да персонализирате тези аспекти с филтри в Envoy Proxy, които ще обсъдим по-късно.

Стъпка 3 — Конфигуриране на сървъра

В HTTP конфигурационния блок конфигурацията на NGINX указва да слуша на порт 8080 и да отговаря на входящи заявки за домейни one.example.com и www.one.example.com.

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

Вътре в Envoy слушателите управляват това.

Пратеник на слушателите

Най-важният аспект от започването на работа с Envoy Proxy е дефинирането на слушателите. Трябва да създадете конфигурационен файл, който описва как искате да стартирате екземпляра Envoy.

Фрагментът по-долу ще създаде нов слушател и ще го свърже към порт 8080. Конфигурацията казва на Envoy Proxy към кои портове трябва да бъде свързан за входящи заявки.

Envoy Proxy използва YAML нотация за своята конфигурация. За въведение в тази нотация вижте тук връзка.

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

Няма нужда от дефиниране Име на сървъра, тъй като филтрите на Envoy Proxy ще се справят с това.

Стъпка 4 — Конфигуриране на местоположението

Когато заявка пристигне в NGINX, блокът за местоположение определя как да се обработва и къде да се насочва трафикът. В следващия фрагмент целият трафик към сайта се прехвърля към възходящия (бележка на преводача: нагоре по веригата обикновено е сървър на приложения) клъстер с име targetCluster. Клъстерът нагоре по веригата дефинира възлите, които трябва да обработят заявката. Ще обсъдим това в следващата стъпка.

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

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

В Envoy това прави Filters.

Филтри Envoy

За статична конфигурация филтрите определят как се обработват входящите заявки. В този случай задаваме филтри, които съответстват имена на сървъри в предишната стъпка. Когато постъпят входящи заявки, които съответстват на определени домейни и маршрути, трафикът се насочва към клъстера. Това е еквивалентът на конфигурацията нагоре по веригата на 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

име пратеник.http_connection_manager е вграден филтър в Envoy Proxy. Други филтри включват Redis, Монго, TCP. Можете да намерите пълния списък на документация.

За повече информация относно други политики за балансиране на натоварването посетете Документация на Envoy.

Стъпка 5 - Конфигуриране на прокси и възходящ поток

В NGINX конфигурацията нагоре дефинира набор от целеви сървъри, които ще обработват трафика. В този случай са зададени два клъстера.

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

В Envoy това се управлява от клъстери.

Пратенически клъстери

Еквивалентът нагоре по веригата се определя като клъстери. В този случай са определени хостовете, които ще обслужват трафика. Начинът на достъп до хостове, като изчакване, се определя като конфигурация на клъстер. Това позволява по-фин контрол върху детайлността на аспекти като латентност и балансиране на натоварването.

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

Когато използвате откриване на услуги STRICT_DNS Envoy непрекъснато и асинхронно ще разрешава посочените DNS цели. Всеки върнат IP адрес от DNS резултата ще се счита за изричен хост в горния клъстер. Това означава, че ако една заявка върне два IP адреса, Envoy ще приеме, че има два хоста в клъстера и двата трябва да бъдат балансирани по натоварване. Ако даден хост бъде премахнат от резултата, Envoy приема, че той вече не съществува и ще изтегли трафик от всички съществуващи пулове за връзка.

За повече информация вижте Документация за пълномощник на Envoy.

Стъпка 6 — Достъп до регистрационния файл и грешки

Крайната конфигурация е регистрация. Вместо да изпраща регистрационни файлове за грешки на диск, Envoy Proxy използва базиран на облак подход. Всички регистрационни файлове на приложението се извеждат към стандартния изход и STDERR.

Когато потребителите направят заявка, регистрационните файлове за достъп не са задължителни и са деактивирани по подразбиране. За да активирате регистрационни файлове за достъп за HTTP заявки, активирайте конфигурацията access_log за мениджъра на HTTP връзки. Пътят може да бъде или устройство като стандартния изход, или файл на диск, в зависимост от вашите изисквания.

Следната конфигурация ще пренасочи всички регистрационни файлове за достъп към стандартния изход (бележка на преводача - stdout е необходим за използване на envoy в докер. Ако се използва без докер, заменете /dev/stdout с пътя към обичайния лог файл). Копирайте фрагмента в раздела за конфигурация за мениджъра на връзки:

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

Резултатите трябва да изглеждат така:

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

По подразбиране Envoy има форматиращ низ, който включва детайлите на 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

Резултатът от този форматиращ низ е:

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

Изходното съдържание може да бъде персонализирано чрез задаване на полето за формат. Например:

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"

Редът на регистрационния файл може също да бъде изведен във формат JSON чрез настройка на полето json_format, Например:

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

За повече информация относно методологията за регистрация на пратеници посетете

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

Регистрирането не е единственият начин да получите усещане за работа с Envoy Proxy. Има вградени разширено проследяване и показатели. Можете да научите повече на следова документация или чрез Скрипт за интерактивно маршрутизиране.

Стъпка 7 - Стартиране

Вече сте мигрирали конфигурацията от NGINX към Envoy Proxy. Последната стъпка е да стартирате екземпляр на Envoy Proxy, за да го тествате.

Стартирайте като потребител

В горната част на конфигурационния ред на NGINX потребител www www; показва, че NGINX работи като потребител с ниски права за подобряване на сигурността.

Envoy Proxy използва облачен подход за управление на това кой притежава процес. Когато стартираме Envoy Proxy през контейнер, можем да посочим потребител с ниска привилегия.

Стартирайте Envoy Proxy

Командата по-долу ще стартира Envoy Proxy през Docker контейнер на хоста. Тази команда дава възможност на Envoy да слуша за входящи заявки на порт 80. Въпреки това, както е посочено в конфигурацията на слушателя, Envoy Proxy слуша за входящ трафик на порт 8080. Това позволява на процеса да се изпълнява като потребител с ниски привилегии.

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

Тестване

При работещ прокси вече могат да се правят и обработват тестове. Следната команда cURL издава заявка със заглавката на хоста, дефинирана в конфигурацията на прокси сървъра.

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

HTTP заявката ще доведе до грешка 503. Това е така, защото връзките нагоре не работят и не са налични. По този начин Envoy Proxy няма налични целеви дестинации за заявката. Следната команда ще стартира поредица от HTTP услуги, които съответстват на конфигурацията, дефинирана за Envoy.

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

С наличните услуги Envoy може успешно да проксира трафика до своята дестинация.

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

Трябва да видите отговор, указващ кой Docker контейнер е обработил заявката. В регистрационните файлове на Envoy Proxy трябва също да видите отпечатания низ за достъп.

Допълнителни заглавки на HTTP отговор (HTTP отговор)

Ще видите допълнителни HTTP заглавки в заглавките на отговора на валидна заявка. Заглавката показва времето, което хостът нагоре по веригата е изразходвал за обработка на заявката. Изразено в милисекунди. Това е полезно, ако клиентът иска да определи времето за обслужване спрямо латентността на мрежата.

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

Окончателна конфигурация

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 }

Допълнителна информация от преводача

Инструкции за инсталиране на Envoy Proxy можете да намерите на уебсайта https://www.getenvoy.io/

Няма конфигурация на услугата systemd в rpm по подразбиране.

Добавете конфигурацията на услугата 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

Трябва да създадете директорията /etc/envoy/ и да поставите config.yaml config там.

Има телеграм чат за прокси пратеник: https://t.me/envoyproxy_ru

Envoy Proxy не поддържа обслужване на статично съдържание. И така, кой може да гласува за функция: https://github.com/envoyproxy/envoy/issues/378

В анкетата могат да участват само регистрирани потребители. Впиши се, Моля те.

Тази публикация насърчи ли ви да инсталирате и тествате envoy proxy?

  • да

  • не

75 потребители гласуваха. 18 потребители се въздържаха.

Източник: www.habr.com

Добавяне на нов коментар