Миграция от Nginx към Envoy Proxy

Здравейте, Хабр! Предлагам вниманието ви превод на поста: Миграция от Nginx към Envoy Proxy.

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

Възможности

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

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

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

Изходен конфиг nginx

потребител 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. Изслушване на всеки слушател (listener)
  2. Приемане на нови връзки
  3. Създаване на набор от филтри за връзката
  4. Обработване на всички операции по вход-изход през времето на съществуването на връзката.

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

За всеки работен поток в 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

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

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

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

Копирай в редактораstatic_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 8080 }

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

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

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

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

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

В Envoy това се управлява от Filters.

Envoy Filters

За статичната конфигурация филтрите определят как да се обработват входящите заявки. В този случай задаваме филтри, които съответстват на server_names от предишната стъпка. Когато постъпват входящи заявки, които отговарят на определени домейни и маршрути, трафикът се насочва към клъстера. Това е еквивалент на upstream конфигурацията на NGINX.

Копирай в редактора    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

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

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

Стъпка 5 — Конфигурация на Proxy и Upstream

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

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

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

Envoy Clusters

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

Copy to Editor  клъстери:
  - име: 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 използва облачен подход. Всички журнали на приложенията се извеждат в stdout и stderr.

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

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

Copy to Clipboardaccess_log:
- име: envoy.file_access_log
  config:
    path: "/dev/stdout"

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

      - име: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          access_log:
          - име: 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 строката user 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 Response)

В заглавията на отговора от валидната заявка ще видите допълнителни 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/

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

Добавете конфигурация на systemd service \etc\systemd\system\envoy.service:

[Unit]
Description=Envoy Proxy
Documentation=https:\/\/www.envoyproxy.io\/\nAfter=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.

По envoy proxy има телеграм чат: https://t.me/envoyproxy_ru

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

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

Вдъхнови ли те този пост да инсталираш и тествате envoy proxy?

  • да

  • не

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

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

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster